spring boot中常用的配置文件的重写
@Configuration public class viewConfigSolver extends WebMvcConfigurerAdapter { /* spring boot 已经自动配置好了springmvc 配置好了viewResolver * 视图解析器(根据方法的返回值得到视图对象,视图对象决定如何渲染(转发或者重定向)) * 我们可以自己给容器中添加一个视图解析器 * ContentNegotiatingViewResolver就会将其组合进来*/ @Override public void addViewControllers(ViewControllerRegistry registry) { super.addViewControllers(registry); //浏览器发送/index.xml这个请求就来到success页面 // 既保留了原有的配置也能使用我们自己的配置 registry.addViewController("/index.html").setViewName("login"); // } // 所有的WebMvcConfigurerAdapter组件都会一起起作用 } @Bean // 将组件注册在容器中 public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){ // 这个类已经过时了,推荐的是WebMvcConfig 它也是实现了WebMvcConfig WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("login"); // 加上一个视图映射 registry.addViewController("/index.html").setViewName("login"); registry.addViewController("/main.html").setViewName("dashboard"); } // 注册拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { // super.addInterceptors(registry); // //静态资源; *.css , *.js 不需要再处理静态资源 //SpringBoot已经做好了静态资源映射 拦截所有请求 排除登录页面的请求 registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/templates/login.html","/","/user/login","/asserts/**","/webjars/**"); } }; return adapter; } //将自定义的国际化添加到容器中 /* @Bean public LocaleResolver localeResolver(){ return new MylocaleResolver(); } */ }
以上是自定义的视图解析器,和拦截器但是这个方法已经过时了,当你点进去查看源码的时候会发现有一个
---------------------------------------------
@Deprecated注解,
科普一下这个注解的意思就是若某类或某方法加上该注解之后,表示此方法或类不再建议使用,
调用时也会出现删除线,但并不代表不能用,只是说,不推荐使用,因为还有更好的方法可以调用。
或许有人会问 为什么会出现加这个注解呢,直接在写方法的时候定义一个新的不就好了吗?
因为在一个项目中,工程比较大,代码比较多,而在后续开发过程中,可能之前的某个方法实现的并不是很合理,这个时候就要新加一个方法,而之前的方法又不能随便删除,因为可能在别的地方有调用它,所以加上这个注解,就方便以后开发人员的方法调用了。
原文:https://blog.csdn.net/alinekang/article/details/79314815
--------------------------------------------------------------------------
所以这里有一个新的实现 下面这个演示是不能直接使用的,能直接使用的在下下面这个是更新后的 类 WebMvcConfigurationSupport
package cn.edu.aynu.zhulina.demo.MyConfig; import cn.edu.aynu.zhulina.demo.component.LoginHandlerInterceptor; import cn.edu.aynu.zhulina.demo.component.MylocaleResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; @Configuration public class MyViewConfig extends WebMvcConfigurationSupport { /*自定义一个方法之后再去声明呢*/ @Bean public WebMvcConfigurationSupport webMvcConfigurationSupport(){ WebMvcConfigurationSupport adapter = new WebMvcConfigurationSupport() { @Override protected void addViewControllers(ViewControllerRegistry registry) { //super.addViewControllers(registry); registry.addViewController("/").setViewName("login"); // 加上一个视图映射 registry.addViewController("/index.html").setViewName("login"); registry.addViewController("/main.html").setViewName("dashboard"); } @Override protected void addInterceptors(InterceptorRegistry registry) { //super.addInterceptors(registry); // registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/login.html","/","/user/login","/asserts/**","/webjars/**"); } }; return adapter; } // 将自定义的国际化添加到容器中 @Bean public LocaleResolver localeResolver(){ return new MylocaleResolver(); } }
但是你如果写会发现发现无法访问静态资源,已经controller都无法访问,为什么呢,是应为因为java8接口具有默认实现
因为在springboot中默认是加载了mvc的配置,可以查看注释@WebMvcAutoConfiguration,这个注释有一个条件注释@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)。也就是说只要在容器中发现有WebMvcConfigurationSupport这个类,那就会失效,我们就必须在我们的主类上添加@EnableWebMvc注解,这样我就无法访问默认的静态资源了。因为WebMvcConfigurerAdapter过时,是因为java8中接口有默认实现,而WebMvcConfigurerAdapter实现的就是WebMvcConfigurer方法,所以我只要实现WebMvcConfigurer接口,然后重写我们需要的方法即可。
原文:https://blog.csdn.net/pengdandezhi/article/details/81182701
-----------------------------------------------------
下面我带你们看一下源码,究竟是为什么
spring mvc自动配置 没事可以研究研究
https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications
@Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration { public static final String DEFAULT_PREFIX = ""; public static final String DEFAULT_SUFFIX = ""; private static final String[] SERVLET_LOCATIONS = { "/" };
那么就是单纯的实现类了
package cn.edu.aynu.zhulina.demo.MyConfig; import cn.edu.aynu.zhulina.demo.component.LoginHandlerInterceptor; import cn.edu.aynu.zhulina.demo.component.MylocaleResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class DefineConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("login"); /*加上一个视图映射*/ registry.addViewController("/index.html").setViewName("login"); registry.addViewController("/main.html").setViewName("dashboard"); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/login.html","/","/user/login","/asserts/**","/webjars/**"); } /*将自定义的国际化添加到容器中*/ @Bean public LocaleResolver localeResolver(){ return new MylocaleResolver(); } }
接下来就是自定义异常了 ,先来看一下注解
@ControllerAdvice的作用
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface ControllerAdvice {
....
}
也被声明为一个组件有两个好处,可以被spring boot 添加到容器中 然后也可以被<context:component-scan>扫描到
作用:@ControllerAdvice
是一个@Component
,用于定义@ExceptionHandler
,@InitBinder
和@ModelAttribute
方法,适用于所有使用@RequestMapping
方法。
@ControllerAdvice常用来处理异常
package cn.edu.aynu.zhulina.demo.Controller; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import javax.servlet.http.HttpServletRequest; import java.nio.file.attribute.UserPrincipalNotFoundException; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class MyExceptionHandler { @ExceptionHandler(UserPrincipalNotFoundException.class) public String handlerException(HttpServletRequest request,Exception e){ Map<String ,Object> map = new HashMap(); //传入我们自己的错误状态码 4xx 5xx /** * Integer statusCode = (Integer) request .getAttribute("javax.servlet.error.status_code"); */ request.setAttribute("javax.servlet.error.status_code",500); map.put("code","user.NotExist"); map.put("message","用户出错啦"); request.setAttribute("ext",map); return "forward:/error"; } }
@ExceptionHandler
和@ResponseStatus
中,如果单使用@ExceptionHandler
,只能在当前Controller中处理异常。但当配合@ControllerAdvice
一起使用的时候,就可以摆脱那个限制了。
package cn.edu.aynu.zhulina.demo.Controller; import cn.edu.aynu.zhulina.demo.exception.UserNotExistException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import java.nio.file.attribute.UserPrincipalNotFoundException; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class MyExceptionHandler { @ExceptionHandler(UserNotExistException.class) public String handlerException(HttpServletRequest request,Exception e){ Map<String ,Object> map = new HashMap(); //传入我们自己的错误状态码 4xx 5xx /** * Integer statusCode = (Integer) request .getAttribute("javax.servlet.error.status_code"); */ request.setAttribute("javax.servlet.error.status_code",500); map.put("code","user.NotExist"); map.put("message","用户出错啦"); request.setAttribute("ext",map); return "forward:/error"; } }
package cn.edu.aynu.zhulina.demo.component; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.stereotype.Component; import org.springframework.web.context.request.WebRequest; import java.util.Map; @Component public class MyErrorAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { Map<String,Object> map = super.getErrorAttributes(webRequest, includeStackTrace); map.put("company","atguigu"); /*我们的异常处理器携带的数据*/ Map<String,Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", 0); map.put("ext",ext); return map; } }
可以自定义异常信息,但是我没有成功并没有显示出我的异常信息,待后续..................