专栏名称: Java编程精选
关注语言编程Java,分享、交流Java编程技巧和信息
目录
相关文章推荐
Java编程精选  ·  字节员工爆料:快40岁了,每天晚上加班到12 ... ·  20 小时前  
芋道源码  ·  2W字全面剖析 Mybatis 中的9种设计模式 ·  昨天  
ImportNew  ·  Java 之父怒斥:AI ... ·  4 天前  
51好读  ›  专栏  ›  Java编程精选

Controller层代码这么写,简洁又优雅!

Java编程精选  · 公众号  · Java  · 2025-06-06 18:00

正文

请到「今天看啥」查看全文


Integer code;
private String message;
private T data;

public static Result success (T data) {
return new Result<>(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage(), data);
}

public static Result success (String message, T data) {
return new Result<>(ResultEnum.SUCCESS.getCode(), message, data);
}

public static Result> failed() {
return new Result<>(ResultEnum.COMMON_FAILED.getCode(), ResultEnum.COMMON_FAILED.getMessage(), null );
}

public static Result> failed(String message) {
return new Result<>(ResultEnum.COMMON_FAILED.getCode(), message, null );
}

public static Result> failed(IResult errorResult) {
return new Result<>(errorResult.getCode(), errorResult.getMessage(), null );
}

public static Result instance (Integer code, String message, T data) {
Result result = new Result<>();
result.setCode(code);
result.setMessage(message);
result.setData(data);
return result;
}
}


统一返回结构后,在 Controller 中就可以使用了,但是每一个 Controller 都写这么一段最终封装的逻辑,这些都是很重复的工作,所以还要继续想办法进一步处理统一返回结构。


| 统一包装处理

Spring 中提供了一个类 ResponseBodyAdvice ,能帮助我们实现上述需求:
public interface ResponseBodyAdvice<T{
    boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType);

    @Nullable
    beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType, Class extends HttpMessageConverter>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response);
}


ResponseBodyAdvice 是对 Controller 返回的内容在 HttpMessageConverter 进行类型转换之前拦截,进行相应的处理操作后,再将结果返回给客户端。


那这样就可以把统一包装的工作放到这个类里面:

  • supports: 判断是否要交给 beforeBodyWrite 方法执行,ture:需要;false:不需要

  • beforeBodyWrite: 对 response 进行具体的处理
// 如果引入了swagger或knife4j的文档生成组件,这里需要仅扫描自己项目的包,否则文档无法正常生成
@RestControllerAdvice(basePackages = "com.example.demo")
public class ResponseAdvice implements ResponseBodyAdvice<Object{
    @Override
    public boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType{
        // 如果不需要进行封装的,可以添加一些校验手段,比如添加标记排除的注解
        return true;
    }


    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class extends HttpMessageConverter>> selectedConverterTypeServerHttpRequest requestServerHttpResponse response{
        // 提供一定的灵活度,如果body已经被包装了,就不进行包装
        if (body instanceof Result) {
            return body;
        }
        return Result.success(body);
    }
}


经过这样改造,既能实现对 Controller 返回的数据进行统一包装,又不需要对原有代码进行大量的改动。


| 参数校验

Java API 的规范 JSR303 定义了校验的标准 validation-api ,其中一个比较出名的实现是 hibernate validation。


spring validation 是对其的二次封装,常用于 SpringMVC 的参数自动校验,参数校验的代码就不需要再与业务逻辑代码进行耦合了。


①@PathVariable 和 @RequestParam 参数校验


Get 请求的参数接收一般依赖这两个注解,但是处于 url 有长度限制和代码的可维护性,超过 5 个参数尽量用实体来传参。


对 @PathVariable 和 @RequestParam 参数进行校验需要在入参声明约束的注解。


如果校验失败,会抛出 MethodArgumentNotValidException 异常。
@RestController(value = "prettyTestController")
@RequestMapping("/pretty")
public class TestController {

    private TestService testService;

    @GetMapping(






请到「今天看啥」查看全文