方案一:

//手机号
if(StringUtils.isEmpty(user.getMobile())){
    return Result.fail("添加用户时,手机号不能为空");
}
//角色
if(CollectionUtils.isEmpty(user.getRoles())) {
    return Result.fail("添加用户时,角色信息不能为空");
}

方案二:

 

1、实体类注解添加


/*
    @NotNull    验证对象是否不为null, 无法查检长度为0的字符串
    @NotBlank 检查约束 (字符串) 是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
    @NotEmpty 检查(集合)约束元素是否为NULL或者是EMPTY.
    ********上面导入的是两个包******
*/

@NotBlank(message = "应用名称不能为空")

private String applicationName;

2、controller入口处理


@ApiOperation(value="添加API分类接口", notes="添加API分类接口")
@PostMapping(value={"/saveCategory"})
public R saveCategory(@RequestHeader String userCode,@Valid @RequestBody ApiCategoryRequest request){
    log.info("APICategoryController-->saveCategory添加API分类操作");
    return  this.apiCategoryService.saveCategory(request,userCode);
}

3、自定义返回


package com.dnt.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.baomidou.mybatisplus.extension.api.R;
import com.dnt.web.ResultCode;
import com.dnt.web.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.ResponseUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Configuration
@EnableWebMvc
@Slf4j
public class WebMvcConfig implements WebMvcConfigurer {
    //tomcat下没有 此设置
    @Value("${spring.profiles.active}")
    private String env;//当前激活的配置文件
    @Value("${dnt.feishui.notice.url}")
    private String feishuUrl;
    /**
     * 请求参数的转换
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        WebMvcConfigurer.super.configureMessageConverters(converters);
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        //自定义fastjson配置
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                SerializerFeature.WriteNullNumberAsZero,    // 将数值类型字段的空值输出为0
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.DisableCircularReferenceDetect,    // 禁用循环引用
                SerializerFeature.IgnoreNonFieldGetter //忽略为空的属性向前台返回
        );
        fastJsonHttpMessageConverter.setFastJsonConfig(config);
        // 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
        // 但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json
        // 参考它的做法, fastjson也只添加application/json的MediaType
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        converters.add(fastJsonHttpMessageConverter);

        // 添加 StringHttpMessageConverter,解决中文乱码问题
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        converters.add(stringHttpMessageConverter);
        //Long类型的数据转字符串
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fjc = new FastJsonConfig();
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class , ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE , ToStringSerializer.instance);
        fjc.setSerializeConfig(serializeConfig);
        fastJsonConverter.setFastJsonConfig(fjc);
        converters.add(fastJsonConverter);
    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    //跨域
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //设置允许访问的ip与域名信息
        registry.addMapping("/**").allowCredentials(true)
                .allowedOrigins("*")
                .allowedHeaders("*")
                .allowedMethods("*")
                .maxAge(3600);
    }




    //统一异常处理
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        exceptionResolvers.add(new HandlerExceptionResolver() {
            public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
                R r = new R();
                String message="";
                if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误”
                    message = e.getMessage();
                    r.setCode(ResultCode.FAIL.code()).setMsg(message);
                    log.info(message);
                } else if (e instanceof NoHandlerFoundException) {
                    message = "接口 [" + request.getRequestURI() + "] 不存在";
                    r.setCode(ResultCode.NOT_FOUND.code()).setMsg(message);
                } else if (e instanceof ServletException) {
                    message = e.getMessage();
                    r.setCode(ResultCode.FAIL.code()).setMsg(message);
                } else if (e instanceof MethodArgumentNotValidException) {
                    List<FieldError> fieldErrorList = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors();
                    if(fieldErrorList.size()>0){
                        FieldError fieldError = fieldErrorList.get(fieldErrorList.size() - 1);
                        message=fieldError.getDefaultMessage();
                    }
                    r.setCode(ResultCode.FAIL.code()).setMsg(message);
                } else {
                    message = "接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员";
                    r.setCode(ResultCode.INTERNAL_SERVER_ERROR.code()).setMsg(message);
                    if (handler instanceof HandlerMethod) {
                        HandlerMethod handlerMethod = (HandlerMethod) handler;
                        message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s",
                                request.getRequestURI(),
                                handlerMethod.getBean().getClass().getName(),
                                handlerMethod.getMethod().getName(),
                                e.getMessage());
                    } else {
                        message = e.getMessage();
                    }
                    log.error(message, e);
                }
                responseResult(response, r);
                //发送告警通知
                sendFeiShu(message);
                return new ModelAndView();
            }



        });
    }

    private String makeBindErrors(List<FieldError> fieldErrorList, Exception exception) {

        String errorMessage = "";
        if (CollectionUtil.isEmpty(fieldErrorList)) {
            return errorMessage;
        }


        Object data = null;
        int errorCode = 0;
        for (FieldError fieldError : fieldErrorList) {
            if (fieldError != null) {
                //fieldError.getDefaultMessage()  这个就是你自己定义的message
                errorMessage = fieldError.getDefaultMessage();
                data = fieldError.getRejectedValue();
                if (fieldError.getCode().matches("^[-\\\\+]?[\\\\d]*$")) {
                    errorCode = Integer.parseInt(fieldError.getCode());
                } else {
                    errorCode = 1;
                }
                break;
            }
        }
        return errorMessage;
    }

    //发送告警通知
    //{"msg_type":"text","content":{"text":"测试通知"}}
    private void sendFeiShu(String message) {

        JSONObject mes = new JSONObject();
        mes.put("text",message);
        JSONObject mesj = new JSONObject();
        mesj.put("msg_type","text");
        mesj.put("content",mes);
        /*    //发送消息
        String str = HttpUtil.post(feishuUrl,mesj);
        log.info("消息推送结果:{}",str);*/

        String str1 = HttpRequest.post(feishuUrl)
                .header(Header.CONTENT_TYPE,"application/json")
                .body(mesj.toJSONString())
                .execute().body();
        log.info("消息推送结果:{}",str1);

    }
    //添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //接口签名认证拦截器,该签名认证比较简单,实际项目中可以使用Json Web Token或其他更好的方式替代。
        if (!"dev".equals(env)) { //开发环境忽略签名认证
            registry.addInterceptor(new HandlerInterceptorAdapter() {
                @Override
                public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                    //验证签名
                    boolean pass = validateSign(request);
                    if (pass) {
                        return true;
                    } else {
                        log.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}",
                                request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap()));

                        R r = new R();
                        r.setCode(ResultCode.UNAUTHORIZED.code()).setMsg("签名认证失败");
                        responseResult(response, r);
                        return false;
                    }
                }
            });
        }
    }

    private void responseResult(HttpServletResponse response, R result) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        response.setStatus(200);
        try {
            response.getWriter().write(JSON.toJSONString(result));
        } catch (IOException ex) {
            log.error(ex.getMessage());
        }
    }

    /**
     * 一个简单的签名认证,规则:
     * 1. 将请求参数按ascii码排序
     * 2. 拼接为a=value&b=value...这样的字符串(不包含sign)
     * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较
     */
    private boolean validateSign(HttpServletRequest request) {
        String requestSign = request.getParameter("sign");//获得请求签名,如sign=19e907700db7ad91318424a97c54ed57
        if (StringUtils.isEmpty(requestSign)) {
            return false;
        }
        List<String> keys = new ArrayList<>(request.getParameterMap().keySet());
        keys.remove("sign");//排除sign参数
        Collections.sort(keys);//排序

        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串
        }
        String linkString = sb.toString();
        linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最后一个'&'

        String secret = "dntApiServer";//密钥,自己修改
        String sign = DigestUtils.md5Hex(linkString + secret);//混合密钥md5

        return StringUtils.equals(sign, requestSign);//比较
    }

    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 如果是多级代理,那么取第一个ip为客户端ip
        if (ip != null && ip.indexOf(",") != -1) {
            ip = ip.substring(0, ip.indexOf(",")).trim();
        }

        return ip;
    }

}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐