如何建立一个带论坛的网站,安徽住房和城乡建设厅官网,重庆响应式网站方案,外链建设应如何进行一、全局异常处理机制:
1.异常处理两种方式:
开发过程中是不可避免地会出现各种异常情况的#xff0c;例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题#xff0c;甚至直接导致程序崩溃。因此#xff0c;在开发过程中#xff0c;…一、全局异常处理机制:
1.异常处理两种方式:
开发过程中是不可避免地会出现各种异常情况的例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题甚至直接导致程序崩溃。因此在开发过程中合理处理异常、避免异常产生、以及对异常进行有效的调试是非常重要的。
对于异常的处理一般分为两种方式:
(1).编程式异常处理:是指在代码中显式地编写处理异常的逻辑。它通常涉及到对异常类型的检测及其处理例如使用try-catch块来捕获异常然后在catch块中编写特定的处理代码或者在finally块中执行一些清理操作。在编程式异常处理中开发人员需要显式地进行异常处理异常处理代码混杂在业务代码中导致代码可读性较差。
(2).声明式异常处理:则是将异常处理的逻辑从具体的业务逻辑中分离出来通过配置等方式进行统一的管理和处理。在声明式异常处理中开发人员只需要为方法或类标注相应的注解(如Throws或ExceptionHandler)就可以处理特定类型的异常。相较于编程式异常处理声明式异常处理可以使代码更加简洁、易于维护和扩展。
站在宏观角度来看待声明式事务处理:整个项目从架构这个层面设计的异常处理的统一机制和规范。一个项目中会包含很多个模块各个模块需要分工完成。如果张三负责的模块按照 A 方案处理异常李四负责的模块按照 B 方案处理异常……各个模块处理异常的思路、代码、命名细节都不一样那么就会让整个项目非常混乱。使用声明式异常处理可以统一项目处理异常思路项目更加清晰明了
2.基于注解异常声明异常处理:
(1).声明异常处理控制器类:
异常处理控制类统一定义异常处理handler方法
/*** projectName: com.atguigu.execptionhandler* * description: 全局异常处理器,内部可以定义异常处理Handler!*//*** RestControllerAdvice ControllerAdvice ResponseBody* ControllerAdvice 代表当前类的异常处理controller! */
RestControllerAdvice
public class GlobalExceptionHandler {}
(2).声明异常处理hander方法:
异常处理handler方法和普通的handler方法参数接收和响应都一致
只不过异常处理handler方法要映射异常发生对应的异常会调用
普通的handler方法要使用RequestMapping注解映射路径发生对应的路径调用
/*** 异常处理handler * ExceptionHandler(HttpMessageNotReadableException.class) * 该注解标记异常处理Handler,并且指定发生异常调用该方法!* * * param e 获取异常对象!* return 返回handler处理结果!*/
ExceptionHandler(HttpMessageNotReadableException.class)
public Object handlerJsonDateException(HttpMessageNotReadableException e){return null;
}/*** 当发生空指针异常会触发此方法!* param e* return*/
ExceptionHandler(NullPointerException.class)
public Object handlerNullException(NullPointerException e){return null;
}/*** 所有异常都会触发此方法!但是如果有具体的异常处理Handler! * 具体异常处理Handler优先级更高!* 例如: 发生NullPointerException异常!* 会触发handlerNullException方法,不会触发handlerException方法!* param e* return*/
ExceptionHandler(Exception.class)
public Object handlerException(Exception e){return null;
}
(3).配置文件扫描控制器类配置:
确保异常处理控制类被扫描 !-- 扫描controller对应的包,将handler加入到ioc--ComponentScan(basePackages {com.atguigu.controller,com.atguigu.exceptionhandler})
二、拦截器的使用:
1.拦截器的概念:拦截器和过滤器解决问题
在程序中使用拦截器在请求到达具体handler方法前统一执行检测 拦截器Springmvc VS 过滤器javaWeb:
(1).相似点:
a.拦截:必须先把请求拦住才能执行后续操作
b.过滤:拦截器或过滤器存在的意义就是对请求进行统一处理
c.放行:对请求执行了必要操作后放请求过去让它访问原本想要访问的资源
(2).不同点:
a.工作平台不同:
过滤器工作在Servlet容器中
拦截器工作在SpringMVC的基础上
b.拦截的范围:
过滤器能够拦截到的最大范围是整个Web应用
拦截器能够拦截到的最大范围是整个SpringMVC负责的请求
c.IOC容器支持:
过滤器想得到IOC容器需要调用专门的工具方法是间接的
拦截器它自己就在IOC容器中所以可以直接从IOC容器中装配组件也就是可以直接得到IOC容器的支持
选择:功能需要如果用 SpringMVC 的拦截器能够实现就不使用过滤器 2.拦截器的使用:
(1).创建拦截器类:
public class Process01Interceptor implements HandlerInterceptor {// if( ! preHandler()){return;}// 在处理请求的目标 handler 方法前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(request request , response response , handler handler);System.out.println(Process01Interceptor.preHandle);// 返回true放行// 返回false不放行return true;}// 在目标 handler 方法之后handler报错不执行!Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(request request , response response , handler handler , modelAndView modelAndView);System.out.println(Process01Interceptor.postHandle);}// 渲染视图之后执行(最后),一定执行!Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(request request , response response , handler handler , ex ex);System.out.println(Process01Interceptor.afterCompletion);}
}
拦截器方法拦截位置: (2).修改配置类添加拦截器: EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器
Configuration
ComponentScan(basePackages {com.atguigu.controller,com.atguigu.exceptionhandler}) //TODO: 进行controller扫描
//WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
public class SpringMvcConfig implements WebMvcConfigurer {//配置jsp对应的视图解析器Overridepublic void configureViewResolvers(ViewResolverRegistry registry) {//快速配置jsp模板语言对应的registry.jsp(/WEB-INF/views/,.jsp);}//开启静态资源处理 mvc:default-servlet-handler/Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}//添加拦截器Overridepublic void addInterceptors(InterceptorRegistry registry) { //将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求registry.addInterceptor(new Process01Interceptor());}
}
(3).修改配置:
a.默认拦截全部:
Override
public void addInterceptors(InterceptorRegistry registry) {//将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求registry.addInterceptor(new Process01Interceptor());
}b.精准配置:
Override
public void addInterceptors(InterceptorRegistry registry) {//将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求registry.addInterceptor(new Process01Interceptor());//精准匹配,设置拦截器处理指定请求 路径可以设置一个或者多个,为项目下路径即可//addPathPatterns(/common/request/one) 添加拦截路径//也支持 /* 和 /** 模糊路径。 * 任意一层字符串 ** 任意层 任意字符串registry.addInterceptor(new Process01Interceptor()).addPathPatterns(/common/request/one,/common/request/tow);
}c.排除配置:
//添加拦截器
Override
public void addInterceptors(InterceptorRegistry registry) {//将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求registry.addInterceptor(new Process01Interceptor());//精准匹配,设置拦截器处理指定请求 路径可以设置一个或者多个,为项目下路径即可//addPathPatterns(/common/request/one) 添加拦截路径registry.addInterceptor(new Process01Interceptor()).addPathPatterns(/common/request/one,/common/request/tow);//排除匹配,排除应该在匹配的范围内排除//addPathPatterns(/common/request/one) 添加拦截路径//excludePathPatterns(/common/request/tow); 排除路径,排除应该在拦截的范围内registry.addInterceptor(new Process01Interceptor()).addPathPatterns(/common/request/one,/common/request/tow).excludePathPatterns(/common/request/tow);
}
(4).多个拦截器执行顺序:
a.preHandle()方法:SpringMVC会把所有拦截器收集到一起然后按照配置顺序调用各个 preHandle()方法。
b.postHandle()方法:SpringMVC会把所有拦截器收集到一起然后按照配置相反的顺序调用各个 postHandle()方法。
c.afterCompletion()方法:SpringMVC会把所有拦截器收集到一起然后按照配置相反的顺序调用各个 afterCompletion()方法。
三、参数校验:
在Web应用三层架构体系中表述层负责接收浏览器提交的数据业务逻辑层负责数据的处理。为了能够让业务逻辑层基于正确的数据进行处理我们需要在表述层对数据进行检查将错误的数据隔绝在业务逻辑层之外
1.校验概述:
JSR 303是Java为Bean数据合法性校验提供的标准框架它已经包含在JavaEE 6.0标准中。JSR 303通过在Bean属性上标注类似于NotNull、Max等标准的注解指定校验规则并通过标准的验证接口对Bean进行验证
注解规则Null标注值必须为nullNotNull标注值不可为nullAssertTrue标注值必须为trueAssertFalse标注值必须为falseMin(value)标注值必须大于或等于valueMax(value)标注值必须小于或等于valueDecimalMin(value)标注值必须大于或等于valueDecimalMax(value)标注值必须小于或等于valueSize(max,min)标注值大小必须在max和min限定的范围内Digits(integer,fratction)标注值值必须是一个数字且必须在可接受的范围内Past标注值只能用于日期型且必须是过去的日期Future标注值只能用于日期型且必须是将来的日期Pattern(value)标注值必须符合指定的正则表达式
JSR 303只是一套标准需要提供其实现才可以使用。Hibernate Validator是JSR 303的一个参考实现除支持所有标准的校验注解外它还支持以下的扩展注解:
注解规则Email标注值必须是格式正确的 Email 地址Length标注值字符串大小必须在指定的范围内NotEmpty标注值字符串不能是空字符串Range标注值必须在指定的范围内
Spring 4.0版本已经拥有自己独立的数据校验框架同时支持JSR 303标准的校验框架。Spring在进行数据绑定时可同时调用校验框架完成数据校验工作。在SpringMVC 中可直接通过注解驱动EnableWebMvc的方式进行数据校验。Spring 的LocalValidatorFactoryBean既实现了Spring 的Validator接口也实现了JSR 303的Validator接口。只要在Spring容器中定义了一个LocalValidatorFactoryBean即可将其注入到需要数据校验的Bean中。Spring本身并没有提供JSR 303的实现所以必须将JSR 303的实现者的jar包放到类路径下。
配置EnableWebMvc后SpringMVC会默认装配好一个LocalValidatorFactoryBean通过在处理方法的入参上标注Validated注解即可让SpringMVC在完成数据绑定后执行数据校验的工作。
2.操作演示:
导入依赖:
!-- 校验注解 --
dependencygroupIdjakarta.platform/groupIdartifactIdjakarta.jakartaee-web-api/artifactIdversion9.1.0/versionscopeprovided/scope
/dependency!-- 校验注解实现--
!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --
dependencygroupIdorg.hibernate.validator/groupIdartifactIdhibernate-validator/artifactIdversion8.0.0.Final/version
/dependency
!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor --
dependencygroupIdorg.hibernate.validator/groupIdartifactIdhibernate-validator-annotation-processor/artifactIdversion8.0.0.Final/version
/dependency
应用校验注解:
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import org.hibernate.validator.constraints.Length;/*** projectName: com.atguigu.pojo*/
public class User {//age 1 age 150Min(10)private int age;//name 3 name.length 6Length(min 3,max 10)private String name;//email 邮箱格式Emailprivate String email;public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getEmail() {return email;}public void setEmail(String email) {this.email email;}
}handler标记和绑定错误收集:
RestController
RequestMapping(user)
public class UserController {/*** Validated 代表应用校验注解! 必须添加!*/PostMapping(save)public Object save(Validated RequestBody User user,//在实体类参数和 BindingResult 之间不能有任何其他参数, BindingResult可以接受错误信息,避免信息抛出!BindingResult result){//判断是否有信息绑定错误! 有可以自行处理!if (result.hasErrors()){System.out.println(错误);String errorMsg result.getFieldError().toString();return errorMsg;}//没有,正常处理业务即可System.out.println(正常);return user;}
}
测试效果: 3.易混总结:
NotNull、NotEmpty、NotBlank都是用于在数据校验中检查字段值是否为空的注解但是它们的用法和校验规则有所不同。
(1).NotNull(包装类型不为null)
NotNull注解是JSR 303规范中定义的注解当被标注的字段值为null时会认为校验失败而抛出异常。该注解不能用于字符串类型的校验若要对字符串进行校验应该使用NotBlank或 NotEmpty注解。
(2).NotEmpty(集合类型长度大于0)
NotEmpty注解同样是JSR 303规范中定义的注解对于CharSequence、Collection、Map或者数组对象类型的属性进行校验校验时会检查该属性是否为Null或者size()0如果是的话就会校验失败。但是对于其他类型的属性该注解无效。需要注意的是只校验空格前后的字符串如果该字符串中间只有空格不会被认为是空字符串校验不会失败。
(3).NotBlank(字符串不为null不为 字符串)
NotBlank注解是Hibernate Validator附加的注解对于字符串类型的属性进行校验校验时会检查该属性是否为Null或“”或者只包含空格如果是的话就会校验失败。需要注意的是NotBlank 注解只能用于字符串类型的校验。
总之这三种注解都是用于校验字段值是否为空的注解但是其校验规则和用法有所不同。在进行数据校验时需要根据具体情况选择合适的注解进行校验。
SpringMVC总结:
核心点掌握目标springmvc框架主要作用、核心组件、调用流程简化参数接收路径设计、参数接收、请求头接收、cookie接收简化数据响应模板页面、转发和重定向、JSON数据、静态资源restful风格设计主要作用、具体规范、请求方式和请求参数选择功能扩展全局异常处理、拦截器、参数校验注解