项目场景:
今天新接手项目的产品反馈图片显示不了了。
初一听跟网上编排程序员的段子一样,哪里有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等目录。
总结:
- 升级spring-boot-starter-parent版本,官宣的一写说明不会特别详细(或者我没有看详细)
- idea还有优化的空间,要是有一天能将过时的配置都标识出来就好了
- 是有方法查看配置项是否过时的
光标放在配置项上就会有提示。
特别说明:
升级spring-boot-starter-parent版本的同学们,一定要注意,网上百度到的配置映射本地文件目录的配置项已经失效了,这里是正解。