当前位置: 首页 > Web前端 > vue.js

SpringBoot:如何优雅的进行参数传递、响应数据封装、异常处理?

时间:2023-03-31 14:13:34 vue.js

在项目开发中,接口之间、前后端之间的数据传输均采用JSON格式。1fastjson使用阿里巴巴的fastjson,是目前使用最广泛的JSON解析框架。本文也将使用fastjson。1.1引入依赖com.alibabafastjson1.2.35复制代码2将返回的数据统一封装在web项目中,接口返回的数据一般包括状态码,信息,数据等,例如下面的接口例子:importcom.alibaba.fastjson.JSONObject;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RestController;/**@authorguozhengMu@version1.0@date2019/8/2114:55@description@modify*/@RestController@RequestMapping(value="/test",method=RequestMethod.GET)publicclassTestController{@RequestMapping("/json")publicJSONObjecttest(){JSONObjectresult=newJSONObject();try{//业务逻辑代码result.put("code",0);result.put("msg","操作成功!");result.put("数据","测试数据");}catch(Exceptione){result.put("代码",500);result.put("msg","系统异常,请联系管理员!");}返回result;}}复制代码这种情况下,每个接口都这样处理,很麻烦,需要更优雅的实现方式2.1定义统一的JSON结构统一的JSON结构中的属性包括数据,状态码、提示信息等项目,您可以根据需要添加。一般来说,应该有默认的返回结构,也应该有用户指定的返回结构。由于无法确定返回数据类型,需要泛型,代码如下:publicclassResponseInfo{/***状态码*/protectedStringcode;/***响应信息*/protectedStringmsg;/***返回数据*/privateTdata;/***如果没有返回数据,默认状态码为0,提示信息为“操作成功!”*/publicResponseInfo(){this.code=0;this.msg="OperationSuccess!";}/***如果没有返回数据,可以手动指定状态码和提示信息*@paramcode*@parammsg*/publicResponseInfo(Stringcode,Stringmsg){this.code=代码;这。msg=msg;}/***返回数据时,状态码为0,默认提示信息为“操作成功!”*@paramdata*/publicResponseInfo(Tdata){this.data=data;这个.code=0;this.msg="操作成功!";}/***有数据返回,状态码为0,提示信息手动指定*@paramdata*@parammsg*/publicResponseInfo(Tdata,Stringmsg){this.data=数据;这个.code=0;this.msg=msg;}//省略get和set方法}复制代码2.2使用统一的JSON结构我们封装了统一的返回数据结构后,在接口中是可以直接使用的。如下:importcom.example.demo.model.ResponseInfo;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RestController;/**@authorguozhengMu@version1.0@date2019/8/2114:55@description@modify*/@RestController@RequestMapping(value="/test",method=RequestMethod.GET)publicclassTestController{@RequestMapping("/json")publicResponseInfotest(){try{//模拟异常业务代码intnum=1/0;returnnewResponseInfo("测试数据");}catch(Exceptione){returnnewResponseInfo(500,"系统异常,请联系管理员!");}}}复制上面的代码,接口的返回数据处理就优雅多了。对上面的界面进行测试,启动项目,通过浏览器访问:localhost:8096/test/json,得到响应结果:{"code":500,"msg":"系统异常,请联系administrator!","data":null}复制代码3全局异常处理3.1系统定义的异常处理新建一个ExceptionHandlerAdvice全局异常处理类,然后添加@RestControllerAdvice注解,拦截项目中抛出的异常。下面的代码包含了几个异常处理,比如参数格式异常、参数丢失、系统异常等,看下面的例子:@RestControllerAdvice@Slf4jpublicclassExceptionHandlerAdvice{//参数格式异常处理@ExceptionHandler({IllegalArgumentException.class})@ResponseStatus(HttpStatus.BAD_REQUEST)publicResponseInfobadRequestArgumentException(非法异常){log.error("参数格式无效:"+e.getMessage());returnnewResponseInfo(HttpStatus.BAD_REQUEST.value()+"","参数格式不匹配!");}//权限不足异常处理@ExceptionHandler({AccessDeniedException.class})@ResponseStatus(HttpStatus.FORBIDDEN)publicResponseInfobadRequestException(AccessDeniedExceptionexception){returnnewResponseInfo(HttpStatus.FORBIDDEN.value()+"",exception().get}Mess/参数丢失异常处理@ExceptionHandler({MissingServletRequestParameterException.class})@ResponseStatus(HttpStatuss.BAD_REQUEST)publicResponseInfobadRequestException(Exceptionexception){returnnewResponseInfo(HttpStatus.BAD_REQUEST.value()+"","强制参数丢失!");}//空指针异常@ExceptionHandler(NullPointerException.class)@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)publicResponseInfohandleTypeMismatchException(NullPointerExceptionex){log.error("NullPointerException,{}",ex.getMessage());returnnewJsonResult("500","NullPointerException");}@ExceptionHandler(Exception.class)@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)publicJsonResulthandleUnexpectedServer(Exceptionex){log.error("系统异常:",ex);returnnewJsonResult("500","系统发生异常,请联系管理员");}//系统异常处理@ExceptionHandler(Throwable.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)publicResponseInfoexception(Throwablethrowable){log.error("系统异常",throwable);returnnewResponseInfo(HttpStatus.INTERNAL_SERVER_ERROR.value()+"系统异常,请联系管理员!");}}复制代码@RestControllerAdvice注解包含@Component注解,说明当SpringBoot启动时,这个类也会作为一个组件交给Spring来管理。@RestControllerAdvice注解中包含@ResponseBody注解,用于在处理完异常后向调用方输出一个JSON格式的打包数据。@RestControllerAdvice注解还有一个basePackages属性,用于拦截哪个包中的异常信息。一般我们不指定这个属性,在project项目中拦截所有的异常。通过方法上的@ExceptionHandler注解指定具体的异常,然后在方法中处理异常信息,最后通过统一的JSON结构将结果返回给调用者。但是在项目中,我们一般会比较详细的拦截一些常见的异常。拦截Exception虽然可以一劳永逸,但是不利于我们排查或者定位问题。在实际项目中,可以将拦截的Exception写在GlobalExceptionHandler的最底层。如果没有找到,则最后拦截Exception,保证输出信息友好。下面我们使用一个接口来测试:@RestController@RequestMapping(value="/test",method=RequestMethod.POST)publicclassTestController{@RequestMapping("/json")publicResponseInfotest(@RequestParamStringuserName,@RequestParamStringpassword){try{Stringdata="登录用户:"+userName+",password:"+password;returnnewResponseInfo("0","操作成功!",data);}catch(Exceptione){returnnewResponseInfo("500","系统异常,请联系管理员!");}}}复制代码接口调用,密码故意留空:最后,如果您觉得本文对您有帮助,请点个赞。或者可以加入我的开发交流群:1025263163互相学习,我们会有专业的技术解答。如果您觉得这篇文章对您有用,请给我们的开源项目一个小星星:http://github。crmeb.net/u/defu非常感谢!PHP学习手册:https://doc.crmeb.com技术交流论坛:https://q.crmeb.com