请求结果返回封装
以下是对返回结果的封装,这样可以让开发者明确的知道代码的业务性
1.对返回结果的设计
public class Result {
private Integer code;
private String message;
private Object data;
}
2.code和message的关系,
code是状态码,message是返回的消息
code,和message是一一对应的关系,为了规范和便于维护,我们采用枚举,此处为了猜测,所以并没有枚举更多code和message.以后有更多的code和message,可以直接在这里进行维护
public enum ResultCode {
/*成功状态码*/
SUCCESS(1, "成功"),
/*参数错误*/
PARAM_IS_INVALID(1001, "参数无效"),
PARAM_IS_BLANK(1002, "参数类型错误");
/*用户错误*/
private Integer code;
private String message;
ResultCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer code() {
return this.code;
}
public String message() {
return this.message;
}
}
3.result和ResultCode的关系
public class Result {
private Integer code;
private String message;
private Object data;
public Result() {
}
public Result(ResultCode resultCode, Object data) {
this.code = resultCode.code();
this.message = resultCode.message();
this.data = data;
}
private void setResultCode(ResultCode resultCode) {
this.code = resultCode.code();
this.message = resultCode.message();
}
//此处省略get和set
}
4.为了不在controller层对返回结果进行封装,此时我们在result类下提供静态方法
//返回成功
public static Result successs(){
Result result = new Result();
result.setResultCode(ResultCode.SUCCESS);
return result;
}
public static Result successs(Object data){
Result result = new Result();
result.setResultCode(ResultCode.SUCCESS);
result.setData(data);
return result;
}
//返回失败
public static Result failure(ResultCode resultCode){
Result result = new Result();
result.setResultCode(resultCode);
return result;
}
public static Result failure(ResultCode resultCode,Object data){
Result result = new Result();
result.setResultCode(resultCode);
result.setData(data);
return result;
}
5.编写自定义注解,确定该类或该方法将被我们进行封装
@Retention(RUNTIME)
@Target({TYPE,METHOD})
@Documented
public @interface ResponseResult {
}
6.拦截器的实现
@Component
public class ResponseResultInterceptor extends HandlerInterceptorAdapter {
public static final String RESPONSE_RESULT_ANN ="RESPONSE_RESULT_ANN";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod){
final HandlerMethod handlerMethod = (HandlerMethod) handler;
final Class<?> clazz = handlerMethod.getBeanType();
final Method method = handlerMethod.getMethod();
//判断是否在类对象上加了注解
if (clazz.isAnnotationPresent(ResponseResult.class)){
request.setAttribute(RESPONSE_RESULT_ANN,clazz.getAnnotation(ResponseResult.class));
}else if (method.isAnnotationPresent(ResponseResult.class)){//方法体是否有注解
request.setAttribute(RESPONSE_RESULT_ANN,method.getAnnotation(ResponseResult.class));
}
}
return true;
}
}
7.真正操作返回结果的
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {
//标记名称
public static final String RESPONSE_RESULT_ANN ="RESPONSE_RESULT_ANN";
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
//是否请求,包含了 包装注解,没有就直接返回,不需要重写返回体
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
//判断请求是否有包装标记
ResponseResult responseResultAnn = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANN);
return responseResultAnn==null?false:true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
return Result.successs(body);
}
}
8.controller此时只需要注重逻辑,对返回结果格式化不需要controller进行考虑
@RestController
@RequestMapping("/api")
public class IndexController {
@Autowired
private GoodsService goodsService;
@Autowired
private SellerService sellerService;
@GetMapping("/seller")
@ResponseResult
public Seller seller() {
Seller seller = sellerService.query();
return seller;
}
}
此时只要我们的被请求类或者方法由我们的自定义注解,那我们就可以只注重我们的业务了
最终请求后得到的数据会是
{
code: 1,
message: "成功",
data: {
id: 1,
name: "雨荷塘",
avatar: "http://static.galileo.xiaojukeji.com/static/tms/seller_avatar_256px.jpg",
score: 0,
description: "蜂鸟专送",
deliveryTime: "38",
bulletin: "粥品香坊其烹饪粥料的秘方源于中国千年古法,在融和现代制作工艺,由世界烹饪大师屈浩先生领衔研发。坚守纯天然、0添加的良心品质深得消费者青睐,发展至今成为粥类的引领品牌。是2008年奥运会和2013年园博会指定餐饮服务商。",
supports: [
{
id: 0,
type: "0",
description: "蜂鸟专送"
},
{
id: 0,
type: "1",
description: "蜂鸟专送"
},
{
id: 0,
type: "2",
description: "蜂鸟专送"
},
{
id: 0,
type: "3",
description: "蜂鸟专送"
},
{
id: 0,
type: "4",
description: "蜂鸟专送"
}
]
}
}
code,massage,以及data都会自动被封装好
版权声明:本文为TowerTan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。