SpringBoot2.6.x映射本地文件目录为静态资源配置

项目场景:

今天新接手项目的产品反馈图片显示不了了。
初一听跟网上编排程序员的段子一样,哪里有bug,不接受。
经过亲自验证、回忆、成功证明真的不是bug,而是自作自受导致的。为什么这样说,且听下面娓娓道来。


问题描述:

文件上传,存本地磁盘方式的上传正常。上服务器检查文件,文件存在。(以下就用本机演示,因为确定保存是成功的)
在这里插入图片描述


原因分析:

我这里上传本地磁盘存储,前端访问是当静态资源访问的。那么就是配置的静态资源映射出了问题,那么下面就按照节奏一步步撸呗。
我这里是springCloud微服务,但是静态资源文件就是再网关gateway就映射到本地磁盘目录的。
配置:

#设置时间格式
spring:
  global:
    date-format: yyyy-MM-dd HH:mm:ss
  config:
    activate:
      on-profile: dev
  mvc:
    #本地静态文件映射路径
    static-path-pattern: /**
  resources:
    #本地静态资源
    static-locations: file:${
    
    web.upload-path}
    #本地静态资源配置映射目录,应该是下面的方法
#文件上传配置
  servlet:
    multipart:
      enabled: true # 是否支持多部分上传。
      maxFileSize: 20MB # 最大支持文件上传的大小
      maxRequestSize: 200MB # 支持请求最大文件上传的大小
  #允许循环依赖
  main:
    allow-circular-references: true

#zipkin链路配置
  zipkin:
    base-url: http://localhost:9008/  # zipkin服务器的地址
    sender:
      type: web  # 设置使用http的方式传输数据
  sleuth:
    sampler:
      probability: 1  # 设置抽样采集为100%,默认为0.1,即10%

#acturator监控配置
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

#验证码长度配置
verify:
  code:
    length: 6

#resilience4j熔断配置
resilience4j.circuitbreaker:
  configs:
    default:
      registerHealthIndicator: true
      slidingWindowSize: 10
      minimumNumberOfCalls: 5
      slidingWindowType: TIME_BASED
      permittedNumberOfCallsInHalfOpenState: 3
      automaticTransitionFromOpenToHalfOpenEnabled: true
      waitDurationInOpenState: 2s
      failureRateThreshold: 30
      eventConsumerBufferSize: 10
      recordExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException

#feign配置
feign:
  httpclient:
    connection-timeout: 3000000
#请求压缩 开启会导致部分接口请求出现 Required request body is missing,原因还没找到
#  compression:
#    request:
#      enabled: true
#      mime-types: text/xml,application/xml,application/json
#      min-request-size: 2048
#    response:
#      enabled: true
#      max-request-size: 20480000

#容器中间件undertow配置
server:
  shutdown: graceful    # 优雅停机
  connection-timeout: 5000
  compression:
    enabled: true
    min-response-size: 2048
  undertow:
    accesslog:
      dir: logs
      enabled: false
    buffer-size: 1024
    direct-buffers: true
    max-http-post-size: -1B
    threads:
      io: 8
      worker: 256

#不校验token放行url
web:
  #本地磁盘存储路径,注意不要最后目录的/
  upload-path: C:\test\upload


#TLog轻量级日志追踪
tlog:
  pattern: '[$preApp][$preIp][$spanId][$traceId]'

配置说明:
配置方式就是配置文件或配置类。我这里是配置文件,关键配置项就是:

spring.mvc.static-path-pattern: /**
spring.resources.static-locations: file:${web.upload-path}
web.upload-path: C:\test\upload

static-path-pattern可省,因为默认的就是/**


排查过程:

1、改配置类方式



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fillersmart.fsihouse.data.constant.ConstantsEnum;
import com.fillersmart.fsihouse.data.core.Result;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Spring MVC 配置
 *
 * @author zhengwen
 */
@Configuration
@Slf4j
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    
    



    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(new MyHandlerInterceptorAdapter()).addPathPatterns("/**").excludePathPatterns("/upload");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
        registry.addResourceHandler("/upload/**").addResourceLocations("file:C:\\test\\upload");
    }
}

结果:失败
2、降低spring-boot-starter-parent版本
我这里因为一直再跟着新版本走(个人有版本洁癖)。因为之前升级过,升级后是没有回归测试这块的,所以降低到2.5.5。但是提示好多版本要同步降低,太没法了,而且改会低版本也不是我所喜,所以终止。
结果:失败
3、查看自动配置项
因为我这里没有自定义配置项,那么就是默认的自动配置项,所以在Libraries找到spring的autoconfig
在这里插入图片描述
找resources的配置项,发现居然没有spring.resources开头的配置项,只有spring.web开头的
在这里插入图片描述
到这里可能有人已经发现问题的所在了,就是配置项过时了,不支持,那下面验证下。
在idea的配置文件yml里直接从spring开始打spring.resources:
在这里插入图片描述
看到没,全是过时的。


解决方案:

使用最新的配置项替代:将spring.resources.static-locations改为spring.web.resources.static-locations


验证效果:

效果:
在这里插入图片描述
查看gateway的日志(info看不到可以调成debug)
在这里插入图片描述
在没有正确的配置项时,默认去找的classpath:static、resource、public等目录。


总结:

  1. 升级spring-boot-starter-parent版本,官宣的一写说明不会特别详细(或者我没有看详细)
  2. idea还有优化的空间,要是有一天能将过时的配置都标识出来就好了
  3. 是有方法查看配置项是否过时的在这里插入图片描述
    光标放在配置项上就会有提示。
    特别说明:
    升级spring-boot-starter-parent版本的同学们,一定要注意,网上百度到的配置映射本地文件目录的配置项已经失效了,这里是正解。

猜你喜欢

转载自blog.csdn.net/zwrlj527/article/details/122950341
今日推荐