springboot包装controller返回值
hui008 人气:01、springboot项目统一包装返回值,通常返回结果包含code、message、data,结构如下
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class ResponseResult<T> { private int code; private String message; private T data; public ResponseResult(T data) { this.data = data; this.code = 0; this.message = "success"; } }
2、基于ControllerAdvice和HttpMessageConverter实现
定义类ResponseAdvisor实现ResponseBodyAdvice接口,重写supports跟beforeBodyWrite方法
import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @ControllerAdvice public class ResponseAdvisor implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { return true; } @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { if(o instanceof ResponseResult){ return o; } return new ResponseResult<>(o); }
3、接口测试
3.1 测试返回Object类型:
@RestController @RequestMapping("/test") public class TestController { @GetMapping("/test") public Test test(){ return new Test("test", 10); } }
执行结果如下:
3.2 测试返回String类型:
@RestController @RequestMapping("/test") public class TestController { @GetMapping("/test") public Test test(){ return new Test("test", 10); } @GetMapping("/test1") public String test1(){ return "test"; } }
执行结果如下:
3.3 如果Controller类的返回值没有String类型的,仅有上面这个类就够了。如果有String类型的返回值,就有可能遇到类型不匹配的问题。HttpMessageConverter是根据Controller的原始返回值类型进行处理的,而我们在ResponseAdvisor中改变了返回值的类型。如果HttpMessageConverter处理的目标类型是Object还好说,如果是其它类型就会出现问题,其中最容易出现问题的就是String类型,因为在所有的HttpMessageConverter实例集合中,StringHttpMessageConverter要比其它的Converter排得靠前一些。我们需要尝试将处理Object类型的HttpMessageConverter放得靠前一些,这可以在一个Configuration类中完成:
import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration; import java.util.List; @Configuration public class ResponseResultConfig extends DelegatingWebMvcConfiguration { @Override protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(0, new MappingJackson2HttpMessageConverter()); super.configureMessageConverters(converters); } }
3.4 重启服务后再次测试返回String类型,返回结果如下:
3.5 测试返回其他基本数据类型,也都没问题。
下篇写全局业务异常封装,加油!
加载全部内容