Spring Boot:2.2.6
@Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {
@Value("${external.resource.path.type.a}")
private String externalResourcePathTypeA;
@Value("${external.resource.path.type.b}")
private String externalResourcePathTypeB;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/typea/**").addResourceLocations(externalResourcePathTypeA);
registry.addResourceHandler("/typeb/**").addResourceLocations(externalResourcePathTypeB);
}
}
external.resource.path.type.a=file:E:/test/typea
external.resource.path.type.b=file:E:/test/typeb
E:\test
├─typea
│ └─1
│ 1.png
│
└─typeb
└─04e417e185c64f00b58ef4b1f18defeb
2.png
external.resource.path.type.a=file:E:/test/typea/
external.resource.path.type.b=file:E:/test/typeb/
[nio-8080-exec-3] o.s.w.s.DispatcherServlet : GET "/typea/1/1.png", parameters={}, headers={masked} in DispatcherServlet ‘dispatcherServlet‘
[nio-8080-exec-3] o.s.w.s.h.SimpleUrlHandlerMapping : Matching patterns [/typea/**, /**]
[nio-8080-exec-3] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped to HandlerExecutionChain with [ResourceHttpRequestHandler ["file:E:/test/typea"]] and 3 interceptors
[nio-8080-exec-3] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
[nio-8080-exec-3] o.s.w.s.DispatcherServlet : No view rendering, null ModelAndView returned.
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// For very general mappings (e.g. "/") we need to check 404 first
Resource resource = getResource(request);
if (resource == null) {
logger.debug("Resource not found");
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
//...
}
@Nullable
protected Resource getResource(HttpServletRequest request) throws IOException {
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
if (path == null) {
throw new IllegalStateException("Required request attribute ‘" +
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE + "‘ is not set");
}
path = processPath(path);
if (!StringUtils.hasText(path) || isInvalidPath(path)) {
return null;
}
if (isInvalidEncodedPath(path)) {
return null;
}
Assert.notNull(this.resolverChain, "ResourceResolverChain not initialized.");
Assert.notNull(this.transformerChain, "ResourceTransformerChain not initialized.");
Resource resource = this.resolverChain.resolveResource(request, path, getLocations());
if (resource != null) {
resource = this.transformerChain.transform(request, resource);
}
return resource;
}
@Nullable
private Resource getResource(String resourcePath, @Nullable HttpServletRequest request,
List<? extends Resource> locations) {
for (Resource location : locations) {
try {
String pathToUse = encodeIfNecessary(resourcePath, request, location);
Resource resource = getResource(pathToUse, location);
if (resource != null) {
return resource;
}
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
String error = "Skip location [" + location + "] due to error";
if (logger.isTraceEnabled()) {
logger.trace(error, ex);
}
else {
logger.debug(error + ": " + ex.getMessage());
}
}
}
}
return null;
}
@Nullable
protected Resource getResource(String resourcePath, Resource location) throws IOException {
Resource resource = location.createRelative(resourcePath);
if (resource.isReadable()) {
if (checkResource(resource, location)) {
return resource;
}
else if (logger.isWarnEnabled()) {
Resource[] allowedLocations = getAllowedLocations();
logger.warn("Resource path \"" + resourcePath + "\" was successfully resolved " +
"but resource \"" + resource.getURL() + "\" is neither under the " +
"current location \"" + location.getURL() + "\" nor under any of the " +
"allowed locations " + (allowedLocations != null ? Arrays.asList(allowedLocations) : "[]"));
}
}
return null;
}
protected URL createRelativeURL(String relativePath) throws MalformedURLException {
if (relativePath.startsWith("/")) {
relativePath = relativePath.substring(1);
}
// # can appear in filenames, java.net.URL should not treat it as a fragment
relativePath = StringUtils.replace(relativePath, "#", "%23");
// Use the URL constructor for applying the relative path as a URL spec
return new URL(this.url, relativePath);
}
protected void parseURL(URL u, String spec, int start, int limit) {
//...
// Parse the file path if any
if (start < limit) {
if (spec.charAt(start) == ‘/‘) {
path = spec.substring(start, limit);
} else if (path != null && path.length() > 0) {
isRelPath = true;
int ind = path.lastIndexOf(‘/‘);
String seperator = "";
if (ind == -1 && authority != null)
seperator = "/";
path = path.substring(0, ind + 1) + seperator +
spec.substring(start, limit);
} else {
String seperator = (authority != null) ? "/" : "";
path = seperator + spec.substring(start, limit);
}
}
//...
}
a) All but the last segment of the base URI‘s path component is
copied to the buffer. In other words, any characters after the
last (right-most) slash character, if any, are excluded.
Spring Boot--带着问题看源码2--实现WebMvcConfigurer接口addResourceHandlers方法,无法访问外部资源
原文:https://www.cnblogs.com/wxyzyu/p/12664043.html