5.springBoot自定义的WebMVC配置
- 添加静态资源配置的映射
添加静态资源配置的原因是我们在访问spring的任意地址时,都会经过spring拦截,它利用dispatcherServlet来处理映射,达到访问我们action地址的作用,因此,如果不做映射,我们是无法访问到我们的静态资源配置的。
首先,我们需要重写个配置类去继承WebMvcConfigurationSupport ,然后加入@Configuration注解,告诉spring这是个配置类
@Configuration
public class CustomWebMvcConfig extends WebMvcConfigurationSupport {}
添加静态资源配置需要重写WebMvcConfigurationSupport中的addResourceHandlers方法,如下所示:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
super.addResourceHandlers(registry);
registry.addResourceHandler("/img/**")
.addResourceLocations("classpath:/img/");
}
registry.addResourceHandler("/img/**").addResourceLocations(“classpath:/img/”);这句话的意思就是将所有/localhos:8080t/img/下的访问地址都指向类路径下的/img/路径。类路径classpath可以这样理解,打开target文件目录
类路径就是classes下面的目录,在resource下生成的文件夹经过编译之后是默认放到classes目录下的。
- 添加拦截器配置
添加拦截器需要重写WebMvcConfigurationSupport中的addInterceptors,因此,我们还需要另外写一个拦截器
addPathPatterns是添加路径拦截,/**是指拦截所有路径,excludePathPatterns是排除拦截.
@Override
public void addInterceptors(InterceptorRegistry registry){
CustomInterceptor customInterceptor = new CustomInterceptor();
registry.addInterceptor(customInterceptor).addPathPatterns("/**")
.excludePathPatterns("/**");
}
拦截器需要继承HandlerInterceptorAdapter类,并且重写preHandler方法,在访问目标地址前,执行preHandler里面的代码,拦截器作用很多,可以实现很多aop的功能。之前我做过角色拦截,角色切换,数据过滤等等,还是比较方便的。
public class CustomInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
return false;
}
}
-
添加跨域配置
-
添加视图控制器配置
试图控制器的配置就是重写addViewControllers如下所示,该写法就跟在springmvc里面返回modelAndView的时候添加的视图,这里需要跟我们的视图解析器去配合。setViewName表示该请求会转向user/error_jsp地址,返回这个地址的时候,ModelAndView会经过视图解析器,视图解析器会根据我们写的配置去包装该请求地址,如果我们在配置里面添加.jsp后缀,/view前缀。之前可以在静态资源路径配置的时候添加/view映射,因此,所有返回的地址都会调向静态资源。再然后,经过视图解析器添加的jsp后缀,我们就可以访问到对应的jsp页面。
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/user/error/").setViewName("/user/error_jsp");
}
- 添加视图解析器配置
视图解析器的作用在上面
@Override
public void configureViewResolvers(ViewResolverRegistry resolverRegistry){
FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
viewResolver.setPrefix("/view");
viewResolver.setSuffix(".jsp");
}
6.全局异常处理
- 使用@ControllerAdvice和@ExceptionHandler来处理controller层所有的异常。
@ExcetionHandler里面的参数是判断何种类型的异常会进入defaultErrorHandler方法。捕获到异常之后就可以处理指定的异常,并且可以返回所需要的逻辑对象。
@ControllerAdvice
public class CustomExceptionHandler {
private Logger logger = LoggerFactory.getLogger(CustomExceptionHandler.class);
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest request,HttpServletResponse response,Exception e){
logger.info("异常类型名称为"+e.getMessage());
e.printStackTrace();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("errorMessage",e.getMessage());
modelAndView.setView(new RedirectView("/user/error"));
request.setAttribute("errorMessage",e.getMessage());
return modelAndView;
}
}
- 实现HandlerExceptionResolver接口并重写resolveException方法,这个可以用来统一的异常处理。
public class CustomExceptionHandler2 implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
return null;
}
}
7.AOP编程
springboot里面的aop编程跟springmvc里面的aop一样。
这里就简单的贴下我做数据校验的代码吧
@Component
@Aspect
public class ExistAspect {
@Autowired
private UserReposity2 userReposity2;
private Logger logger = LoggerFactory.getLogger(ExistAspect.class);
@Pointcut("@annotation(com.gc.firstappdemo.aop.Exist)")
public void existLocation(){}
@Before("existLocation()")
public boolean before(JoinPoint joinPoint) throws Exception{
Object[] args = joinPoint.getArgs();
User user = null;
for(Object o : args){
if(o instanceof User){
user = (User)o;
break;
}
}
if(user.getUserName()==null){
logger.info("参数没有user");
throw new Exception("参数有误");
}
List<User> userByUserName = userReposity2.findUsersByUserNameIs(user.getUserName());
if(userByUserName.size()!=0){
logger.info("用户名已存在");
throw new Exception("用户名已存在");
}
return true;
}
}
@Component注解告诉spring将此类添加到容器中,@Aspect告诉spring这是一个切面类, @Pointcut表示切点,告诉spring在哪儿“切”,这里我是利用自定义的注解,也可以使用execution来表示对方法“切”。这里的语法可以自己去搜搜看。
aop中有五个通知注解,按执行顺序就是@Before,@Around,@AfterReturning,@AfterThrowing,@After分别表示在切点之前,切点进行时,切点正常返回时,切点抛出异常,切点进行后执行切面代码。