Add custom RequestMappingHandlerMapping for enable static resources access (#558)

pull/559/head
John Niang 2020-02-10 23:48:07 +08:00 committed by GitHub
parent 028268c698
commit 49494abbbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 16 deletions

View File

@ -15,15 +15,20 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import run.halo.app.config.properties.HaloProperties;
@ -32,11 +37,9 @@ import run.halo.app.factory.StringToEnumConverterFactory;
import run.halo.app.model.support.HaloConst;
import run.halo.app.security.resolver.AuthenticationArgumentResolver;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
import static run.halo.app.model.support.HaloConst.HALO_ADMIN_RELATIVE_PATH;
@ -50,16 +53,23 @@ import static run.halo.app.utils.HaloUtils.*;
*/
@Slf4j
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "run.halo.app.controller")
@PropertySource(value = "classpath:application.yaml", ignoreResourceNotFound = true, encoding = "UTF-8")
public class WebMvcAutoConfiguration implements WebMvcConfigurer {
public class WebMvcAutoConfiguration extends WebMvcConfigurationSupport {
private static final String FILE_PROTOCOL = "file:///";
private final PageableHandlerMethodArgumentResolver pageableResolver;
private final SortHandlerMethodArgumentResolver sortResolver;
private final HaloProperties haloProperties;
public WebMvcAutoConfiguration(HaloProperties haloProperties) {
public WebMvcAutoConfiguration(PageableHandlerMethodArgumentResolver pageableResolver,
SortHandlerMethodArgumentResolver sortResolver,
HaloProperties haloProperties) {
this.pageableResolver = pageableResolver;
this.sortResolver = sortResolver;
this.haloProperties = haloProperties;
}
@ -80,6 +90,8 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new AuthenticationArgumentResolver());
resolvers.add(pageableResolver);
resolvers.add(sortResolver);
}
/**
@ -190,4 +202,54 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
resolver.setContentType("text/html; charset=UTF-8");
registry.viewResolver(resolver);
}
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return new HaloRequestMappingHandlerMapping(haloProperties);
}
private static class HaloRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
private final Set<String> blackPatterns = new HashSet<>(16);
private final PathMatcher pathMatcher;
private final HaloProperties haloProperties;
public HaloRequestMappingHandlerMapping(HaloProperties haloProperties) {
this.haloProperties = haloProperties;
this.initBlackPatterns();
pathMatcher = new AntPathMatcher();
}
@Override
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
log.debug("Looking path: [{}]", lookupPath);
for (String blackPattern : blackPatterns) {
if (this.pathMatcher.match(blackPattern, lookupPath)) {
log.info("Skipped path [{}] with pattern: [{}]", lookupPath, blackPattern);
return null;
}
}
return super.lookupHandlerMethod(lookupPath, request);
}
private void initBlackPatterns() {
String uploadUrlPattern = ensureBoth(haloProperties.getUploadUrlPrefix(), URL_SEPARATOR) + "**";
String adminPathPattern = ensureBoth(haloProperties.getAdminPath(), URL_SEPARATOR) + "**";
blackPatterns.add("/themes/**");
blackPatterns.add("/js/**");
blackPatterns.add("/images/**");
blackPatterns.add("/fonts/**");
blackPatterns.add("/css/**");
blackPatterns.add("/assets/**");
blackPatterns.add("/swagger-ui.html");
blackPatterns.add("/csrf");
blackPatterns.add("/webjars/**");
blackPatterns.add(uploadUrlPattern);
blackPatterns.add(adminPathPattern);
}
}
}

View File

@ -33,6 +33,7 @@ public class ContentArchiveController {
private final StringCacheStore cacheStore;
public ContentArchiveController(PostService postService,
OptionService optionService,
StringCacheStore cacheStore) {
@ -41,14 +42,14 @@ public class ContentArchiveController {
this.cacheStore = cacheStore;
}
@GetMapping(value = "{url}/password")
@GetMapping(value = "{url:.*}/password")
public String password(@PathVariable("url") String url,
Model model) {
model.addAttribute("url", url);
return "common/template/post_password";
}
@PostMapping(value = "{url}/password")
@PostMapping(value = "{url:.*}/password")
@CacheLock(traceRequest = true, expired = 2)
public String password(@PathVariable("url") String url,
@RequestParam(value = "password") String password) {

View File

@ -77,7 +77,7 @@ public class ContentContentController {
}
}
@GetMapping("{prefix}/page/{page}")
@GetMapping("{prefix}/page/{page:\\d+}")
public String content(@PathVariable("prefix") String prefix,
@PathVariable(value = "page") Integer page,
Model model) {
@ -89,7 +89,7 @@ public class ContentContentController {
}
}
@GetMapping("{prefix}/{url}")
@GetMapping("{prefix}/{url:.+}")
public String content(@PathVariable("prefix") String prefix,
@PathVariable("url") String url,
@RequestParam(value = "token", required = false) String token,
@ -115,7 +115,7 @@ public class ContentContentController {
}
}
@GetMapping("{prefix}/{url}/page/{page}")
@GetMapping("{prefix}/{url}/page/{page:\\d+}")
public String content(@PathVariable("prefix") String prefix,
@PathVariable("url") String url,
@PathVariable("page") Integer page,
@ -132,7 +132,7 @@ public class ContentContentController {
}
}
// @GetMapping("{year:^[^A-Za-z]*$}/{month:^[^A-Za-z]*$}/{url}")
@GetMapping("{year:\\d+}/{month:\\d+}/{url:.+}")
public String content(@PathVariable("year") Integer year,
@PathVariable("month") Integer month,
@PathVariable("url") String url,
@ -147,7 +147,7 @@ public class ContentContentController {
}
}
// @GetMapping("{year:^[^A-Za-z]*$}/{month:^[^A-Za-z]*$}/{day:^[^A-Za-z]*$}/{url}")
@GetMapping("{year:\\d+}/{month:\\d+}/{day:\\d+}/{url:.+}")
public String content(@PathVariable("year") Integer year,
@PathVariable("month") Integer month,
@PathVariable("day") Integer day,