Spring Boot:注入自定义上下文路径
我正在运行带有嵌入式Tomcat的Spring Boot" title="Spring Boot">Spring Boot 1.2.3应用程序。
我想基于URL的第一部分在每个请求上注入自定义contextPath。
例子:
http://localhost:8080/foo
有默认情况下contextPath=""
,应该得到contextPath="foo"
http://localhost:8080/foo/bar
有默认情况下contextPath=""
,应该得到contextPath="foo"
(没有路径的网址应保持原样)
我试着写一个定制的javax.servlet.Filter
带@Order(Ordered.HIGHEST_PRECEDENCE)
,但好像我失去了一些东西。这是代码:
@Component @Order(Ordered.HIGHEST_PRECEDENCE)public class MultiTenancyFilter implements Filter {
private final static Pattern pattern = Pattern.compile("^/(?<contextpath>[^/]+).*$");
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest) request;
final String requestURI = req.getRequestURI();
Matcher matcher = pattern.matcher(requestURI);
if(matcher.matches()) {
chain.doFilter(new HttpServletRequestWrapper(req) {
@Override
public String getContextPath() {
return "/"+matcher.group("contextpath");
}
}, response);
}
}
@Override public void init(FilterConfig filterConfig) throws ServletException {}
@Override public void destroy() {}
}
这应该只是在第一个字符串之后/
和第二个字符串之前(如果有)之前获取String /
,然后将其用作返回值getContextPath()
。
但是Spring @Controller @RequestMapping和Spring Security
antMatchers("/")
似乎并不尊重它。两者仍然像工作contextPath=""
。
如何动态覆盖每个请求的上下文路径?
回答:
得到它的工作!
Spring Security docs ( http://docs.spring.io/spring-
security/site/docs/3.1.x/reference/security-filter-chain.html ) say: “Spring
Security is only interested in securing paths within the application, so the
contextPath is ignored. Unfortunately, the servlet spec does not define
exactly what the values of servletPath and pathInfo will contain for a
particular request URI. […] The strategy is implemented in the class
AntPathRequestMatcher which uses Spring’s AntPathMatcher to perform a case-
insensitive match of the pattern against the concatenated servletPath and
pathInfo, ignoring the queryString.”
所以我只是重写了servletPath
and contextPath
(即使Spring
Security不使用它)。另外,我添加了一些小的重定向,因为通常在命中时将http://localhost:8080/myContext
您重定向到,http://localhost:8080/myContext/
并且Spring
Securities Ant Matcher不喜欢缺少的斜杠。
所以这是我的MultiTenancyFilter
代码:
@Component @Order(Ordered.HIGHEST_PRECEDENCE)public class MultiTenancyFilter extends OncePerRequestFilter {
private final static Pattern pattern = Pattern.compile("^(?<contextPath>/[^/]+)(?<servletPath>.*)$");
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Matcher matcher = pattern.matcher(request.getServletPath());
if(matcher.matches()) {
final String contextPath = matcher.group("contextPath");
final String servletPath = matcher.group("servletPath");
if(servletPath.trim().isEmpty()) {
response.sendRedirect(contextPath+"/");
return;
}
filterChain.doFilter(new HttpServletRequestWrapper(request) {
@Override
public String getContextPath() {
return contextPath;
}
@Override
public String getServletPath() {
return servletPath;
}
}, response);
} else {
filterChain.doFilter(request, response);
}
}
@Override
protected String getAlreadyFilteredAttributeName() {
return "multiTenancyFilter" + OncePerRequestFilter.ALREADY_FILTERED_SUFFIX;
}
}
它仅使用此处提到的URL模式提取contextPath和servletPath:https
://theholyjava.wordpress.com/2014/03/24/httpservletrequest-
requesturirequesturlcontextpathservletpathpathinfoquerystring/
另外,我必须提供一个自定义getAlreadyFilteredAttributeName
方法,因为否则过滤器将被调用两次。(这导致contextPath
两次剥离)
以上是 Spring Boot:注入自定义上下文路径 的全部内容, 来源链接: utcz.com/qa/426628.html