程序员

SpringBoot Web应用范例

2017-09-17  本文已影响0人  圆圆仙人球

本文主要是介绍一个基于SpringBoot的Web应用范例,范例中根据自己多年的工作经验及总结提供了一些使用建议,希望对大家有所启发

public class Response<T> {

    private int status;
    private String msg;
    private T data;

    public Response() {
    }

    public Response(int status, String msg, T data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

其中 status表明接口状态码(成功/失败/其他...,0表示成功), msg是对状态码的简单文字描述(比如:success、失败原因 等等), data是接口返回的具体数据

对返回报文格式进行统一规定,有利于前端做一些公共逻辑:比如对非0状态码记录console日志、对一些特定状态码执行一些统一逻辑等等

返回统一报文格式是通过AOP来实现的,并不需要在业务代码中转换成Response实体,封装代码如下:

  1. 接口正常返回的情况:
@Order(1)
@ControllerAdvice(basePackages = AppContants.API_BASE_PACKAGE)
public class ApiResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    private static final Logger logger = LoggerFactory.getLogger(ApiResponseBodyAdvice.class);

    @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<?>> selectedConverterType, ServerHttpRequest request,
                    ServerHttpResponse response) {
        Response<Object> resp = new Response<>();
        resp.setStatus(0);
        resp.setMsg("success");
        resp.setData(body);

        if(returnType.getMethod().getReturnType() == String.class){
            return JSON.toJSONString(resp);
        }else{
            return resp;
        }
    }
}
  1. 接口抛异常的情况:
@ControllerAdvice(basePackages = AppContants.API_BASE_PACKAGE)
public class ApiExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private static final int UNKNOWN_EXCEPTION_STATUS = -2;
    private static final int ILLEGAL_ARGUMENT_STATUS = -1;

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Response defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        Response response = new Response();
        if (e instanceof AppException) {
            response.setStatus(((AppException) e).getCode());
            response.setMsg(e.getMessage());
        } else if (e instanceof IllegalArgumentException) {
            response.setStatus(ILLEGAL_ARGUMENT_STATUS);
            response.setMsg(e.getMessage());
        } else {
            logger.error("Got exception,url=" + req.getRequestURI(), e);
            response.setStatus(UNKNOWN_EXCEPTION_STATUS);
            response.setMsg("接口异常");
        }
        return response;
    }
}

经过这样的封装后,业务代码中不再涉及Response实体的转换,如下例子所示:

@RestController
@Api(description = "用户相关接口")
@RequestMapping("/api/user")
public class UserEndpoint {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserService userService;

    @ApiOperation(value = "查询用户", notes = "根据用户id查询用户详情")
    @GetMapping("/{userId}")
    public User getUser(@PathVariable("userId") Integer userId) {
        Preconditions.checkNotNull(userId, "user id not provided");
        Preconditions.checkArgument(userId > 0, "user id must greater than 0");

        return this.userService.getUser(userId);
    }

    @ApiOperation(value = "更新用户信息")
    @PostMapping("/update")
    public void updateUser(@RequestBody User user) {
        logger.info("User:{}", user);
    }
}

在这里简单说一下,上面代码有几句关于参数校验的代码(如下所示),我们只需要简单用Preconditions工具类来进行判断,如果条件不满足将会抛出IllegalArgumentException,这个未捕获的异常将会在ApiExceptionHandler得到处理 并将返回status设置为-1,msg设置为异常信息。这样处理后显得代码特别简洁 有木有~

Preconditions.checkNotNull(userId, "user id not provided");
Preconditions.checkArgument(userId > 0, "user id must greater than 0");
上一篇下一篇

猜你喜欢

热点阅读