当前位置: 首页 > news >正文

山东省网站建设_网站建设公司_电商网站_seo优化

高端交互式网站建设,福州网站模板建站,惠州seo外包费用,网店的运营模式有哪些在SpringBoot的开发中#xff0c;为了提高程序运行的鲁棒性#xff0c;我们经常需要对各种程序异常进行处理#xff0c;但是如果在每个出异常的地方进行单独处理的话#xff0c;这会引入大量业务不相关的异常处理代码#xff0c;增加了程序的耦合#xff0c;同时未来想改… 在SpringBoot的开发中为了提高程序运行的鲁棒性我们经常需要对各种程序异常进行处理但是如果在每个出异常的地方进行单独处理的话这会引入大量业务不相关的异常处理代码增加了程序的耦合同时未来想改变异常的处理逻辑也变得比较困难。这篇文章带大家了解一下如何优雅的进行全局异常处理。 为了实现全局拦截这里使用到了Spring中提供的两个注解RestControllerAdvice和ExceptionHandler结合使用可以拦截程序中产生的异常并且根据不同的异常类型分别处理。下面我会先介绍如何利用这两个注解优雅的完成全局异常的处理接着解释这背后的原理。 1. 如何实现全局拦截 1.1 自定义异常处理类 在下面的例子中我们继承了ResponseEntityExceptionHandler并使用RestControllerAdvice注解了这个类接着结合ExceptionHandler针对不同的异常类型来定义不同的异常处理方法。这里可以看到我处理的异常是自定义异常后续我会展开介绍。 ResponseEntityExceptionHandler中包装了各种SpringMVC在处理请求时可能抛出的异常的处理处理结果都是封装成一个ResponseEntity对象。ResponseEntityExceptionHandler是一个抽象类通常我们需要定义一个用来处理异常的使用RestControllerAdvice注解标注的异常处理类来继承自ResponseEntityExceptionHandler。ResponseEntityExceptionHandler中为每个异常的处理都单独定义了一个方法如果默认的处理不能满足你的需求则可以重写对某个异常的处理。 Log4j2 RestControllerAdvice public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { /** * 定义要捕获的异常 可以多个 ExceptionHandler({}) * * param request request * param e exception * param response response * return 响应结果 */ ExceptionHandler(AuroraRuntimeException.class) public GenericResponse customExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) { AuroraRuntimeException exception (AuroraRuntimeException) e; if (exception.getCode() ResponseCode.USER_INPUT_ERROR) { response.setStatus(HttpStatus.BAD_REQUEST.value()); } else if (exception.getCode() ResponseCode.FORBIDDEN) { response.setStatus(HttpStatus.FORBIDDEN.value()); } else { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); } return new GenericResponse(exception.getCode(), null, exception.getMessage()); } ExceptionHandler(NotLoginException.class) public GenericResponse tokenExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) { log.error(token exception, e); response.setStatus(HttpStatus.FORBIDDEN.value()); return new GenericResponse(ResponseCode.AUTHENTICATION_NEEDED); } }1.2 定义异常码 这里定义了常见的几种异常码主要用在抛出自定义异常时对不同的情形进行区分。 Getter public enum ResponseCode { SUCCESS(0, Success), INTERNAL_ERROR(1, 服务器内部错误), USER_INPUT_ERROR(2, 用户输入错误), AUTHENTICATION_NEEDED(3, Token过期或无效), FORBIDDEN(4, 禁止访问), TOO_FREQUENT_VISIT(5, 访问太频繁请休息一会儿); private final int code; private final String message; private final Response.Status status; ResponseCode(int code, String message, Response.Status status) { this.code code; this.message message; this.status status; } ResponseCode(int code, String message) { this(code, message, Response.Status.INTERNAL_SERVER_ERROR); } }1.3 自定义异常类 这里我定义了一个AuroraRuntimeException的异常就是在上面的异常处理函数中用到的异常。每个异常实例会有一个对应的异常码也就是前面刚定义好的。 Getter public class AuroraRuntimeException extends RuntimeException { private final ResponseCode code; public AuroraRuntimeException() { super(String.format(%s, ResponseCode.INTERNAL_ERROR.getMessage())); this.code ResponseCode.INTERNAL_ERROR; } public AuroraRuntimeException(Throwable e) { super(e); this.code ResponseCode.INTERNAL_ERROR; } public AuroraRuntimeException(String msg) { this(ResponseCode.INTERNAL_ERROR, msg); } public AuroraRuntimeException(ResponseCode code) { super(String.format(%s, code.getMessage())); this.code code; } public AuroraRuntimeException(ResponseCode code, String msg) { super(msg); this.code code; } }1.4 自定义返回类型 为了保证各个接口的返回统一这里专门定义了一个返回类型。 Getter Setter public class GenericResponseT { private int code; private T data; private String message; public GenericResponse() {}; public GenericResponse(int code, T data) { this.code code; this.data data; } public GenericResponse(int code, T data, String message) { this(code, data); this.message message; } public GenericResponse(ResponseCode responseCode) { this.code responseCode.getCode(); this.data null; this.message responseCode.getMessage(); } public GenericResponse(ResponseCode responseCode, T data) { this(responseCode); this.data data; } public GenericResponse(ResponseCode responseCode, T data, String message) { this(responseCode, data); this.message message; } }实际测试异常 下面的例子中我们想获取到用户的信息如果用户的信息不存在可以直接抛出一个异常这个异常会被我们上面定义的全局异常处理方法所捕获然后根据不同的异常编码完成不同的处理和返回。 public User getUserInfo(Long userId) { // some logicUser user daoFactory.getExtendedUserMapper().selectByPrimaryKey(userId); if (user null) { throw new AuroraRuntimeException(ResponseCode.USER_INPUT_ERROR, 用户id不存在); }// some logic.... }以上就完成了整个全局异常的处理过程接下来重点说说为什么RestControllerAdvice和ExceptionHandler结合使用可以拦截程序中产生的异常 全局拦截的背后原理 下面会提到ControllerAdvice注解简单地说RestControllerAdvice与ControllerAdvice的区别就和RestController与Controller的区别类似RestControllerAdvice注解包含了ControllerAdvice注解和ResponseBody注解。 接下来我们深入Spring源码看看是怎么实现的首先DispatcherServlet对象在创建时会初始化一系列的对象这里重点关注函数initHandlerExceptionResolvers(context);. public class DispatcherServlet extends FrameworkServlet {// ......protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);initHandlerMappings(context);initHandlerAdapters(context);// 重点关注initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);}// ...... }在initHandlerExceptionResolvers(context)方法中会取得所有实现了HandlerExceptionResolver接口的bean并保存起来其中就有一个类型为ExceptionHandlerExceptionResolver的bean这个bean在应用启动过程中会获取所有被ControllerAdvice注解标注的bean对象做进一步处理关键代码在这里 public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolverimplements ApplicationContextAware, InitializingBean {// ......private void initExceptionHandlerAdviceCache() {// ......ListControllerAdviceBean adviceBeans ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());AnnotationAwareOrderComparator.sort(adviceBeans);for (ControllerAdviceBean adviceBean : adviceBeans) {ExceptionHandlerMethodResolver resolver new ExceptionHandlerMethodResolver(adviceBean.getBeanType());if (resolver.hasExceptionMappings()) {// 找到所有ExceptionHandler标注的方法并保存成一个ExceptionHandlerMethodResolver类型的对象缓存起来this.exceptionHandlerAdviceCache.put(adviceBean, resolver);if (logger.isInfoEnabled()) {logger.info(Detected ExceptionHandler methods in adviceBean);}}// ......}}// ...... }当Controller抛出异常时DispatcherServlet通过ExceptionHandlerExceptionResolver来解析异常而ExceptionHandlerExceptionResolver又通过ExceptionHandlerMethodResolver 来解析异常 ExceptionHandlerMethodResolver 最终解析异常找到适用的ExceptionHandler标注的方法是这里 public class ExceptionHandlerMethodResolver {// ......private Method getMappedMethod(Class? extends Throwable exceptionType) {ListClass? extends Throwable matches new ArrayListClass? extends Throwable();// 找到所有适用于Controller抛出异常的处理方法,例如Controller抛出的异常// 是AuroraRuntimeException(继承自RuntimeException),那么ExceptionHandler(AuroraRuntimeException.class)和// ExceptionHandler(Exception.class)标注的方法都适用此异常for (Class? extends Throwable mappedException : this.mappedMethods.keySet()) {if (mappedException.isAssignableFrom(exceptionType)) {matches.add(mappedException);}}if (!matches.isEmpty()) {/* 这里通过排序找到最适用的方法,排序的规则依据抛出异常相对于声明异常的深度,例如Controller抛出的异常是是AuroraRuntimeException(继承自RuntimeException),那么AuroraRuntimeException相对于ExceptionHandler(AuroraRuntimeException.class)声明的AuroraRuntimeException.class其深度是0,相对于ExceptionHandler(Exception.class)声明的Exception.class其深度是2,所以ExceptionHandler(BizException.class)标注的方法会排在前面 */Collections.sort(matches, new ExceptionDepthComparator(exceptionType));return this.mappedMethods.get(matches.get(0));}else {return null;}}// ...... }整个RestControllerAdvice处理的流程就是这样结合ExceptionHandler就完成了对不同异常的灵活处理。 最后推荐一款应用开发神器 关于目前低代码在技术领域很活跃 低代码是什么一组数字技术工具平台能基于图形化拖拽、参数化配置等更为高效的方式实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。它能缓解甚至解决庞大的市场需求与传统的开发生产力引发的供需关系矛盾问题是数字化转型过程中降本增效趋势下的产物。 这边介绍一款好用的低代码平台——JNPF快速开发平台。近年在市场表现和产品竞争力方面表现较为突出采用的是最新主流前后分离框架SpringBootMybatis-plusAnt-DesignVue3。代码生成器依赖性低灵活的扩展能力可灵活实现二次开发。 以JNPF为代表的企业级低代码平台为了支撑更高技术要求的应用开发从数据库建模、Web API构建到页面设计与传统软件开发几乎没有差异只是通过低代码可视化模式减少了构建“增删改查”功能的重复劳动还没有了解过低代码的伙伴可以尝试了解一下。 应用https://www.jnpfsoft.com/?csdn 有了它开发人员在开发过程中就可以轻松上手充分利用传统开发模式下积累的经验。所以低代码平台对于程序员来说有着很大帮助。
http://www.ihoyoo.com/news/101648.html

相关文章:

  • 厦门做英文网站网站购物商城功能模块图
  • 电脑网页打不开建设银行网站手机建站图片
  • php做网站软件郑州网络开发公司有哪些
  • 网站引导页是什么问题网站ip如何做跳转
  • 青岛网站关键词推广有个可以做图片的网站
  • 光谷做网站推广哪家好自动的小企业网站建设
  • 福州做网站建设成都有哪些网站建设的公司
  • 网站做第三方支付公司建设网站价格
  • 赤峰建设业协会的官方网站wordpress 媒体分类
  • WordPress标签伪搜索引擎优化与推广技术
  • 网站描述修改专业合肥网站建设
  • 游戏推广网站如何做的做网站流量怎么赚钱吗
  • 高端品牌裙子怎么把做的网站优化到百度
  • 男的怎么做直播网站字体设计转换器
  • 搜狗搜索引擎入口手机网站免费优化
  • 怎么制作一个免费的网站模板7下载wordpress
  • 站外推广内容策划企业网站价格多少钱
  • 怎样让网站优化的方式公司网站如何做百度收录
  • 江苏关键词推广seo做seo有什么好处
  • 学校网站作用男女做爰视频网站
  • 天猫网站建设论文辽宁省建设工程信息网锁丢失
  • 银川建设公司网站电脑做网站教学
  • 东丽开发区做网站公司下面软件是网页制作平台的是( )
  • 如何建立自己的网站去推广义乌 网站建设推广营销
  • 公司网站建设合规吗网站单页seo
  • 哈尔滨网站设计福州seo
  • 无锡制作网站价格周至县做网站
  • 网站评论列表模板东莞网页网站制作
  • 上海网站推广排名公司小程序打包成app
  • 加强局网站建设手机网站logo