Spring Boot GET请求中对静态资源的UTF-8解码

时间:2018-11-18 10:08:40

标签: spring encoding utf-8 get character-encoding

我有这个@Bean将请求重定向到我的Spring Boot后端。

@Bean
WebMvcConfigurer configurer () {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addResourceHandlers (ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/data/static/images/**")
                    .addResourceLocations("file:" + System.getProperty("user.dir") + "/static/img/");
        }
    };
}

它非常适合以下URL:

http://localhost:4200/data/static/images/champion/tiles/Ahri_0.jpg

但不适用于以下网址:

http://localhost:4200/data/static/images/champion/tiles/Tahm%20Kench_0.jpg

如果champion名称不包含以下任何字符,则该图像将正确显示在Angular2前端:空格,&符号或单引号字符。

我运行了跟踪级别的日志记录调试,并发出了两种类型的请求-一个带有和不带有“坏”字符的请求。当前,似乎后端在搜索正确的文件。但是,事实证明它声称找不到它。我五倍地疯狂地检查了文件,我知道它在那里,并且打印的路径是正确的。

这是示例日志消息:

2018-11-18 05:07:14.496 TRACE 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Testing handler map [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@4d0bdef0] in DispatcherServlet with name 'dispatcherServlet'
2018-11-18 05:07:14.497 DEBUG 9897 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/data/static/images/champion/tiles/Tahm Kench_0.jpg] are [/data/static/images/**, /**]
2018-11-18 05:07:14.497 DEBUG 9897 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/data/static/images/champion/tiles/Tahm Kench_0.jpg] are {}
2018-11-18 05:07:14.497 DEBUG 9897 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/data/static/images/champion/tiles/Tahm Kench_0.jpg] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[URL [file:/home/nuradin/Development/Java/riot-api-interface/static/img/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@5b5b59]]] and 1 interceptor
2018-11-18 05:07:14.497 TRACE 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@132f4851]
2018-11-18 05:07:14.497 TRACE 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Testing handler adapter [org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@5b8d72dc]
2018-11-18 05:07:14.498 DEBUG 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/data/static/images/champion/tiles/Tahm%20Kench_0.jpg] is: -1
2018-11-18 05:07:14.498 DEBUG 9897 --- [on(7)-127.0.0.1] sun.rmi.transport.tcp                    : RMI TCP Connection(7)-127.0.0.1: (port 34127) op = 82
2018-11-18 05:07:14.498 TRACE 9897 --- [nio-8080-exec-1] o.s.w.s.resource.PathResourceResolver    : Resolving resource for request path "champion/tiles/Tahm Kench_0.jpg"
2018-11-18 05:07:14.498 TRACE 9897 --- [nio-8080-exec-1] o.s.w.s.resource.PathResourceResolver    : Checking location: URL [file:/home/nuradin/Development/Java/riot-api-interface/static/img/]

编辑:我已经在接受的答案中实现了该类,并且它肯定可以正常工作,因为我打印了资源名称(在对遇到问题的字符进行编码之后。)但是,结果仍然是404错误。

下面是日志。 champion/Aatrox2Epng位归因于下面发布的方法@slimane中的println语句。

2018-11-18 05:56:40.509 TRACE 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@465ac973]
2018-11-18 05:56:40.509 TRACE 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Testing handler adapter [org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@37df7ae5]
2018-11-18 05:56:40.509 DEBUG 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/data/static/images/champion/Aatrox.png] is: -1
2018-11-18 05:56:40.509 TRACE 12951 --- [nio-8080-exec-1] o.s.w.s.r.CachingResourceResolver        : Resolving resource for request path "champion/Aatrox.png"
2018-11-18 05:56:40.510 TRACE 12951 --- [nio-8080-exec-1] o.e.r.c.EncodedPathResourceResolver      : Resolving resource for request path "champion/Aatrox.png"
2018-11-18 05:56:40.510 TRACE 12951 --- [nio-8080-exec-1] o.e.r.c.EncodedPathResourceResolver      : Checking location: URL [file:/home/nuradin/Development/Java/riot-api-interface/static/8.23.1/img]
champion/Aatrox2Epng
2018-11-18 05:56:40.511 TRACE 12951 --- [nio-8080-exec-1] o.e.r.c.EncodedPathResourceResolver      : No match for location: URL [file:/home/nuradin/Development/Java/riot-api-interface/static/8.23.1/img]
2018-11-18 05:56:40.511 TRACE 12951 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler     : No matching resource found - returning 404
2018-11-18 05:56:40.511 DEBUG 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling

另一个编辑-抱歉,我更改了路径,因为我认为带有句点的路径现在可以使用。

@Bean
WebMvcConfigurer configurer () {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addResourceHandlers (ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/data/static/images/**")
                    .addResourceLocations("file:" + System.getProperty("user.dir") + "/static/8.23.1/img")
                    .resourceChain(true)
                    .addResolver(encodedPathResourceResolver());
        }
    };
}

1 个答案:

答案 0 :(得分:1)

如下定义您自己的PathResourceResolver:

import org.springframework.core.io.Resource;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceResolver;
import java.io.IOException;

public class CustomPathResourceResolver extends PathResourceResolver implements ResourceResolver {

    @Override
    protected Resource getResource(String resourcePath, Resource location) throws IOException {
        //fixes problems with whitespaces in url
        resourcePath = resourcePath.replace(" ","%20");
        return super.getResource(resourcePath, location);
    }
}

,然后在您的配置中注册它:

@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/data/static/images/**")
                .addResourceLocations("file:" + System.getProperty("user.dir") + "/static/img/")
                .resourceChain(true)
                .addResolver(new CustomPathResourceResolver())
                ;
    }