SpringMvc改装为SpringBoot的问题总结

#SpringMvc改造SpringBoot问题汇总

特殊说明

## 原来项目环境
1. spring-webmvc-4.0.4.RELEASE
2. mybatis-spring-1.2.2
    ↓↓↓↓↓↓
    ↓↓↓↓↓↓
    ↓↓↓↓↓↓
3. JSP页面项目
## 改造环境信息
1. spring-webmvc-5.0.7.RELEASE
2. mybatis-spring-1.3.2; mybatis-spring-boot-starter-1.3.2
3. spring-boot-starter-2.0.2.RELEASE

首先需要SpringBoot的Jar包支持

    <!--SpringBoot的基础支持-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>


    
    <!--jsp页面的jstl表达式的支持-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    
    <!--jsp解析-->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <!--如果采用内置Tomcat,不使用外部Tomcat请把此注释掉-->
      <!--<scope>provided</scope>-->
    </dependency>

    <!--直接内嵌tomcat-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <!--如果采用内置Tomcat,不使用外部Tomcat请把此注释掉-->
      <!--<scope>provided</scope>-->
    </dependency>

使用外置Tomcat特殊说明


## 说明:需要继承SpringBootServletInitializer然后实现configure方法就可以了,示例如下



@EnableCat
@EnablePay
@EnableApolloConfig
@EnableRedisCache
@EnableRedisLock
@EnableElasticJob
@EnableGlobalTransaction
@EnableTransactionManagement
@SpringBootApplication
@ServletComponentScan(basePackages = {"com.hhz", "com.zhiyi"})
public class HhzAdminApplication extends SpringBootServletInitializer {

  public static void main(String[] args) {
    SpringApplication.run(HhzAdminApplication.class, args);
  }

  /**
   * @Description: 使用外置TOMCAT
   * @Param: builder
   * @return: org.springframework.boot.builder.SpringApplicationBuilder
   * @Author: peikunkun
   * @Date: 2020/6/8 0008 上午 9:54
   */
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(HhzAdminApplication.class);
  }
}

logback的日志配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan = "true" scanPeriod = "10 seconds">
  <contextName>logback</contextName>

  <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 -->
  <property name = "log.path" value = "logs" />

  <!--0. 日志格式和颜色渲染 -->
  <!-- 彩色日志依赖的渲染类 -->
  <conversionRule conversionWord = "clr" converterClass = "org.springframework.boot.logging.logback.ColorConverter" />
  <conversionRule conversionWord = "wex"
    converterClass = "org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
  <conversionRule conversionWord = "wEx"
    converterClass = "org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
  <!-- 彩色日志格式 -->
  <property name = "CONSOLE_LOG_PATTERN"
    value = "${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />

  <!--1. 输出到控制台-->
  <appender name = "CONSOLE" class = "ch.qos.logback.core.ConsoleAppender">
    <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
    <filter class = "ch.qos.logback.classic.filter.ThresholdFilter">
      <level>INFO</level>
    </filter>
    <encoder>
      <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
      <!-- 设置字符集 -->
      <charset>UTF-8</charset>
    </encoder>
  </appender>


  <appender name = "LOG_FILE" class = "ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 正在记录的日志文档的路径及文档名 -->
    <file>${log.path}/log.log</file>
    <!--日志文档输出格式-->
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
      <charset>UTF-8</charset>
    </encoder>
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
    <rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- 每天日志归档路径以及格式 -->
      <fileNamePattern>${log.path}/%d{yyyy-MM-dd}/log-%i.log</fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>50MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
      <!--日志文档保留天数-->
      <maxHistory>15</maxHistory>
    </rollingPolicy>
  </appender>

  <!--
      使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
      第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
      第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
      【logging.level.org.mybatis=debug logging.level.dao=debug】
   -->

  <!-- 4.1 开发环境:打印控制台-->
  <springProfile name = "dev">
    <root level = "info">
      <appender-ref ref = "CONSOLE" />
    </root>
  </springProfile>


  <!--4.2 生产环境:输出到文档-->
  <springProfile name = "prod">
    <root level = "INFO">
      <appender-ref ref = "LOG_FILE" />
    </root>
  </springProfile>
</configuration>

改装之后出现的问题

WebMvcConfigurationSupport,WebMvcConfigurerAdapter,WebMvcConfigurer配置多个不生效的问题的问题

-> 问题描述
> 在代码中继承WebMvcConfigurationSupport配置了jsp资源解析配置了,继承WebMvcConfigurerAdapter这个配置了跨域了,继承WebMvcConfigurer这个配置了静态资源管理了

-> 简单说明
> WebMvcConfigurationSupport:更丰富的配置,he 另外两个没有关系,内部有基础的具体实现,我们可重写方法实现自定义配置
> WebMvcConfigurer:是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制。基于java-based方式的spring mvc配置,需要创建一个配置类并实现WebMvcConfigurer 接口
> WebMvcConfigurerAdapter :WebMvcConfigurer的默认实现,在SpringBoot2.0及Spring5.0中WebMvcConfigurerAdapter已被废弃 。官方推荐直接实现WebMvcConfigurer(推荐)或者直接继承WebMvcConfigurationSupport(配置齐全)
  • WebMvcConfigurerAdapter的继承结构
    在这里插入图片描述
  • 问题关键点
    在这里插入图片描述

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
意思是项目中没有WebMvcConfigurationSupport类型的bean时,自动配置类才会生效;如果继承 WebMvcConfigurationSupport,则需要自己再重写相应的方法;

所以一般我们在项目中可以使用实现WebMvcConfigurer来配置我们的WebMvc(也可以继承WebMvcConfigurerAdapter[这个已经被废弃了在新版中,里面没有什么具体实现]),或者继承类WebMvcConfigurationSupport来重写特定的方法来实现自己的配置,但是两个不可冲突使用(混用),否则会导致一方配置失效;

SpringBoot启动嵌入式Tomcat时出现jar包扫描找不到问题解决

springboot启动嵌入式tomcat报错找不到jar包,关键字:FileNotFoundException,derbyLocale_cs.jar,StandardJarScanner.scan…

因为Tomcat在扫描包路径的时候感觉,扫描路径有问题,追踪源码在TomcatEmbeddedServletContainerFactory#prepareContext()有个tldSkipPatterns的东西,可以告诉Tomcat不扫描指定Jar包的配置

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.LegacyCookieProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @description: tomcat容器扫描包路径配置问题
 * @author: peikunkun
 * @create: 2020-06-11 09:32
 **/
@Slf4j
@Configuration
public class TomcatContainerConfig {

  /**
   * 跳过tomcat的扫描配置
   */
  @Value("${com.pkk.tomcat.tldSkipPatterns:}")
  private String[] tldSkipPatterns;

  /**
   * @Description: tomcat的后置处理器
   * @return: org.springframework.beans.factory.config.BeanPostProcessor
   * @Author: peikunkun
   * @Date: 2020/6/11 0011 上午 9:38
   */
  @Bean
  public BeanPostProcessor tomcatContainerPostProcessor() {
    List<String> notEmptyTldSkipPatterns = Arrays.stream(tldSkipPatterns)
        .filter(tldSkipPattern -> !tldSkipPattern.trim().isEmpty())
        .collect(Collectors.toList());
    log.info("[Tomcat container scan]-[Postprocessing configuration]-Exclude jar package[{}]", notEmptyTldSkipPatterns);
    return new BeanPostProcessor() {
      @Override
      public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
      }

      @Override
      public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("tomcatServletWebServerFactory") && bean instanceof TomcatServletWebServerFactory) {
          TomcatServletWebServerFactory factory = (TomcatServletWebServerFactory) bean;
          if (!notEmptyTldSkipPatterns.isEmpty()) {
            factory.addTldSkipPatterns(notEmptyTldSkipPatterns.toArray(new String[0]));
          }
        }
        return bean;
      }
    };
  }
}



#然后在配置文件中配置就可以了
com.pkk.tomcat.tldSkipPatterns = mchange-commons-java-0.2.10.jar,jaxb-api.jar,activation.jar,jsr173_1.0_api.jar,jaxb1-impl.jar

Tomcat8.5前与后Cookie的处理机制改变,造成解析异常的处理

>异常信息:An invalid domain [.xxx.com] was specified for this cookie
>异常分析:tomcat8.5之后,其对cookie的处理机制就变的不同了
>解决方法:其实就两种处理方式,一种Rfc6265CookieProcessor,一种是LegacyCookieProcessor,而8.5之后默认使用Rfc6265CookieProcessor;Rfc6265CookieProcessor的domain域只能以字母或数字开头,LegacyCookieProcessor是以 . 开头;



/**
   * @Description: 一种Rfc6265CookieProcessor,一种是LegacyCookieProcessor,而8.5之后默认使用前者,这两种在用法上可以自行百度,前面一种的domain域只能以字母或数字开头,而后者则是以
   * . 开头,所以有两种方法
   * <p>
   * 解析cookie的方式不同
   * @return: org.springframework.boot.web.server.WebServerFactoryCustomizer<org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory>
   * @Author: peikunkun
   * @Date: 2020/6/16 0016 下午 1:22
   */
  @Bean
  public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
    return (factory) -> factory.addContextCustomizers(
        //不以 . 开头的用这个
        //(context) -> context.setCookieProcessor(new Rfc6265CookieProcessor()));
        //以.开头用这个 
        (context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
  }

Tomcat的外置内置的不同打包方式

  • jar打包方式[内置Tomcat],内置Tomcat上面也讲过
<!--将packaging指定为jar-->
<packaging>jar</packaging>



 <!--jsp解析-->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <!--如果采用内置Tomcat,不使用外部Tomcat请把此注释掉-->
      <!--<scope>provided</scope>-->
    </dependency>

    <!--直接内嵌tomcat-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <!--如果采用内置Tomcat,不使用外部Tomcat请把此注释掉-->
      <!--<scope>provided</scope>-->
    </dependency>



  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <!-- 高版本springboot要访问jsp页面,只能用这个版本的打包插件,否则计算jsp打进入也访问不了 -->
          <version>1.4.2.RELEASE</version>
          <configuration>
            <includeSystemScope>true</includeSystemScope>
          </configuration>
          <executions>
            <execution>
              <goals>
                <goal>repackage</goal>
              </goals>
            </execution>
          </executions>
        </plugin>

        <!--打包web.xml没有的问题-->
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>${maven-war-plugin.version}</version>
          <configuration>
            <!--如果想在没有web.xml文件的情况下构建WAR,请设置为false。-->
            <failOnMissingWebXml>false</failOnMissingWebXml>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>


    <!--maven编译插件-->
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
          <!--使项目是按照maven标准目录结构来构建,即第三方jar包放在src/main/webapp/WEB-INF/lib中,maven-compiler-plugin仍然不会自动去寻找第三方jar包,仍然需要手动配置 < extdirs>-->
          <compilerArguments>
            <extdirs>${project.basedir}/src/main/lib</extdirs>
          </compilerArguments>
        </configuration>
      </plugin>
    </plugins>

    <!--资源打包资源管理-->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/*</include>
        </includes>
      </resource>
      <!-- springboot访问jsp页面必须打包到META-INF/resources目录下 -->
      <resource>
        <directory>src/main/webapp</directory>
        <targetPath>META-INF/resources</targetPath>
        <includes>
          <include>**/**</include>
        </includes>
      </resource>
    </resources>
  </build>

war打包方式[外部Tomcat]

<!--将packaging指定为war-->
<packaging>war</packaging>


 <!--jsp解析-->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <!--如果采用内置Tomcat,不使用外部Tomcat请把此注释掉-->
      <scope>provided</scope>
    </dependency>

    <!--直接内嵌tomcat-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <!--如果采用内置Tomcat,不使用外部Tomcat请把此注释掉-->
      <scope>provided</scope>
    </dependency>



<build>
    <plugins>
        <!--忽略Junit代码-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.4.2</version>
            <configuration>
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
    </plugins>
</build>


//修改为Tomcat外置容器启动的配置
@SpringBootApplication
public class HhzAdminApplicationextends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(HhzAdminApplication.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(HhzAdminApplication.class);
    }
}

阿里云的健康Http/Https健康检测导致Nginx一会出现502

100.116.186.46 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.68 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.24 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.2 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.25 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.101 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.73 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.83 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.35 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.100 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.39 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.97 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.92 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.23 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.9 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.125 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.69 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.91 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.105 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.112 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.10 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.121 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.21 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.87 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.13 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.71 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.83 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.120 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.64 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.46 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.67 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.75 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.45 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.24 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.116 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"
100.116.186.25 - - [17/Jun/2020:11:22:14 +0800] "HEAD / HTTP/1.0" 404 0 "-" "-"

改造完成之后不上线上,一会请求就变成502了,打印nginx的请求日志,发现大量的HEAD请求,并且返回404
原因分析:经过一番排查,发现是阿里云的健康Http/Https检测,发送head请求(路径为“/”),然后根据返回的状态进行验证服务的状态是否正常
健康云检测的文档:
在这里插入图片描述

是因为SpringBoot的路径“/”这边我没有配置,然后请求返回404和与设定的状态不符,阿里云负载认为服务有问题,就不再往负载上操作了,就直接返回502了

 /**
   * @Description: 健康检查
   * @Param: request
   * @return: void
   * @Author: peikunkun
   * @Date: 2020/6/17 0017 下午 10:02
   */
  @RequestMapping("/")
  @ResponseBody
  public void healthCheck(HttpServletRequest request) {
    log.debug(request.getRemoteAddr() + "--->HEALTH CHECK");
  }

异常的页面的错误,比如404,502,500状态码的处理

import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @description: 异常控制处理器
 * @author: peikunkun
 * @create: 2020-06-17 16:30
 **/
@Slf4j
@Controller
public class ExceptionHandleController implements ErrorController {



  /**
   * 错误页面路径
   */
  public static final String ERROR_PATH = "/error";

  /**
   * Returns the path of the error page.
   *
   * @return the error path
   */
  @Override
  public String getErrorPath() {
    return ERROR_PATH;
  }


  /**
   * @Description: 重写错误页面
   * @Param: request
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2020/6/17 0017 下午 4:32
   */
  @RequestMapping("/error")
  public String handleError(HttpServletRequest request) {
    //获取statusCode:401,404,500
    Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
    if (null == statusCode) {
      statusCode = 500;
    }

    String redirect = "";
    switch (statusCode) {
      case 401:
      case 404:
      case 403:
      case 500:
      default:
        redirect= "/badpage/index/noparam";
    }
    return "redirect:" + redirect;
  }
}

web端基础设置,静态资源配置,jsp解析配置->参考示例

/**
 * @description: 过滤器的配置
 * @author: peikunkun
 * @create: 2020-06-08 17:58
 **/
@Slf4j
public class WebMvcResolveConfig extends WebMvcConfigurationSupport {

  /**
   * @Description: jsp视图解析器
   * @return: org.springframework.web.servlet.view.InternalResourceViewResolver
   * @Author: peikunkun
   * @Date: 2020/6/9 0009 上午 9:54
   */
  @Bean
  public InternalResourceViewResolver viewResolver() {
    log.info("[Resource Configuretion]-[Configure JSP resolution resource configuration]");
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/WEB-INF/jsp/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
  }


  /**
   * @Description: Override this method to add resource handlers for serving static resources.
   * <p>
   * 修改支持我们的静态资源信息
   * @Param: registry
   * @return: void
   * @Author: peikunkun
   * @Date: 2020/6/9 0009 上午 9:58
   */
  @Override
  protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    log.info("[Resource Configuration]-[Configure static / profile resource path configuration]");
    //请求路径
    registry.addResourceHandler("/**")
        //在项目中的资源路径
        .addResourceLocations("classpath:/META-INF/resources/")
        .addResourceLocations("classpath:/resources/")
        .addResourceLocations("classpath:/static/")
        .addResourceLocations("classpath:/public/");
    super.addResourceHandlers(registry);
  }
}

------------------------


@Slf4j
@Configuration
public class WebConfigurationHandleConfig extends WebMvcResolveConfig {


  @Bean
  public LoginHandlerInterceptor loginHandlerInterceptor() {
    return new LoginHandlerInterceptor();
  }

  /**
   * Override this method to add Spring MVC interceptors for pre- and post-processing of controller invocation.
   *
   * @param registry
   * @see InterceptorRegistry
   */
  @Override
  protected void addInterceptors(InterceptorRegistry registry) {
    super.addInterceptors(registry);
    log.info("[Resource Configuretion]-[Resource configuration filter]");

    //拦截匹配PATH请求
    registry.addInterceptor(loginHandlerInterceptor())
        .addPathPatterns("/**/**")
        .excludePathPatterns("/static/**");
  }


  /**
   * @Description: 配置默认的静态资源处理器[SpringMvc会默认的识别]
   * @Param: configurer
   * @return: void
   * @Author: peikunkun
   * @Date: 2020/6/17 0017 下午 7:54
   */
  @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable("default");
  }
}


扩展知识

  1. WebMvcConfigurer接口方法说明

public interface WebMvcConfigurer {
    void configurePathMatch(PathMatchConfigurer var1);
    //这个方法是专门用来配置内容裁决的一些参数的(/* 是否通过请求Url的扩展名来决定media type */configurer.favorPathExtension(true)  /* 不检查Accept请求头 */.ignoreAcceptHeader(true).parameterName("mediaType")/* 设置默认的media yype */.defaultContentType(MediaType.TEXT_HTML) /* 请求以.html结尾的会被当成MediaType.TEXT_HTML*/.mediaType("html", MediaType.TEXT_HTML)/* 请求以.json结尾的会被当成MediaType.APPLICATION_JSON*/.mediaType("json", MediaType.APPLICATION_JSON);)
    void configureContentNegotiation(ContentNegotiationConfigurer var1);
    void configureAsyncSupport(AsyncSupportConfigurer var1);
    /* 默认静态资源处理器 (这个Handler也是用来处理静态文件的,它会尝试映射/。当DispatcherServelt映射/时(/ 和/ 是有区别的),并且没有找到合适的Handler来处理请求时,就会交给DefaultServletHttpRequestHandler 来处理。注意:这里的静态资源是放置在web根目录下,而非WEB-INF 下)*/
    void configureDefaultServletHandling(DefaultServletHandlerConfigurer var1);
    //类型转换器和格式化器
    void addFormatters(FormatterRegistry var1);
    /* 拦截器配置addPathPatterns("/")对所有请求都拦截.excludePathPatterns("/index.html","/","/user/login","/static/");排除指定拦截*/
    void addInterceptors(InterceptorRegistry var1);
   /*静态资源处理如registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");*/
    void addResourceHandlers(ResourceHandlerRegistry var1);
    //跨域
    void addCorsMappings(CorsRegistry var1);
   /* 视图跳转控制器 */
    void addViewControllers(ViewControllerRegistry var1);
   /* 配置视图解析器 */
    void configureViewResolvers(ViewResolverRegistry var1);
    void addArgumentResolvers(List<HandlerMethodArgumentResolver> var1);
    void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> var1);
    //配置消息转换器
    void configureMessageConverters(List<HttpMessageConverter<?>> var1);
    void extendMessageConverters(List<HttpMessageConverter<?>> var1);
    void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
    void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
    Validator getValidator();
    MessageCodesResolver getMessageCodesResolver();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章