From d8aa3fc09fc797844d92f044826ed7620ee69ac3 Mon Sep 17 00:00:00 2001 From: zhengjw22 Date: Thu, 15 Aug 2024 19:55:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tech/smartboot/servlet/Container.java | 2 + .../smartboot/servlet/DefaultServlet.java | 2 +- .../servlet/ServletContextRuntime.java | 2 +- .../smartboot/servlet/WebXmlParseEngine.java | 4 +- .../servlet/conf/DeploymentInfo.java | 9 +++++ .../servlet/conf/FilterMappingInfo.java | 22 +---------- .../servlet/conf/SecurityConstraint.java | 4 +- .../servlet/conf/ServletMappingInfo.java | 19 +--------- .../smartboot/servlet/conf/UrlPattern.java | 38 +++++++++++++++++++ .../servlet/handler/FilterMatchHandler.java | 2 +- .../servlet/handler/SecurityHandler.java | 23 ++++++++++- .../impl/ApplicationServletRegistration.java | 4 +- .../servlet/impl/HttpServletMappingImpl.java | 2 +- .../servlet/impl/HttpServletRequestImpl.java | 18 ++++----- .../dispatcher/RequestDispatcherImpl.java | 6 +-- .../ServletRequestDispatcherWrapper.java | 18 ++++----- .../plugins/mapping/MappingPlugin.java | 6 +-- .../plugins/mapping/MappingProviderImpl.java | 10 ++--- .../servlet/util/PathMatcherUtil.java | 33 +++++++++------- 19 files changed, 134 insertions(+), 90 deletions(-) create mode 100644 servlet-core/src/main/java/tech/smartboot/servlet/conf/UrlPattern.java diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/Container.java b/servlet-core/src/main/java/tech/smartboot/servlet/Container.java index f071fa71..dd5ff702 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/Container.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/Container.java @@ -414,6 +414,8 @@ private ServletContextRuntime getServletRuntime(String localPath, String context webAppInfo.getMimeMappings().forEach((key, value) -> servletRuntime.getServletContext().putMimeTypes(key, value)); + webAppInfo.getSecurityConstraints().forEach(deploymentInfo::addSecurityConstraint); + deploymentInfo.setContextUrl(contextFile.toURI().toURL()); //如果 web.xml 描述符中的 metadata-complete 元素设置为 true, diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/DefaultServlet.java b/servlet-core/src/main/java/tech/smartboot/servlet/DefaultServlet.java index 5ff3671a..f57392a7 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/DefaultServlet.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/DefaultServlet.java @@ -233,7 +233,7 @@ private String matchForwardWelcome(HttpServletRequest request) throws MalformedU return uri + file; } //是否匹配 Servlet url-pattern - if (deploymentInfo.getServletMappings().stream().anyMatch(mapping -> mapping.getMapping().equals("/" + file))) { + if (deploymentInfo.getServletMappings().stream().anyMatch(mapping -> mapping.getUrlPattern().equals("/" + file))) { return file; } } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/ServletContextRuntime.java b/servlet-core/src/main/java/tech/smartboot/servlet/ServletContextRuntime.java index 1664f3bb..dd4e1f36 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/ServletContextRuntime.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/ServletContextRuntime.java @@ -186,7 +186,7 @@ private void newServletsInstance(DeploymentInfo deploymentInfo) throws Instantia servletInfo.setServlet(servlet); } //绑定 default Servlet - if (deploymentInfo.getServletMappings().stream().noneMatch(mapping -> mapping.getMapping().equals("/"))) { + if (deploymentInfo.getServletMappings().stream().noneMatch(mapping -> mapping.getUrlPattern().equals("/"))) { ServletInfo servletInfo = new ServletInfo(); servletInfo.setServletName(ServletInfo.DEFAULT_SERVLET_NAME); servletInfo.setServlet(new DefaultServlet(deploymentInfo)); diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/WebXmlParseEngine.java b/servlet-core/src/main/java/tech/smartboot/servlet/WebXmlParseEngine.java index a74929b2..5664495b 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/WebXmlParseEngine.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/WebXmlParseEngine.java @@ -26,6 +26,7 @@ import tech.smartboot.servlet.conf.SecurityConstraint; import tech.smartboot.servlet.conf.ServletInfo; import tech.smartboot.servlet.conf.ServletMappingInfo; +import tech.smartboot.servlet.conf.UrlPattern; import tech.smartboot.servlet.conf.WebAppInfo; import tech.smartboot.servlet.conf.WebFragmentInfo; import tech.smartboot.servlet.enums.FilterMappingType; @@ -366,7 +367,7 @@ private void parseSecurityConstraint(WebAppInfo webAppInfo, Element parentElemen Node webResourceCollection = Objects.requireNonNull(getChildNode(node, "web-resource-collection")); // Map> data = getNodeValues(webResourceCollection, Arrays.asList("web-resource-name", "url-pattern", "http-method")); securityConstraint.getHttpMethods().addAll(getNodeValues(webResourceCollection, "http-method")); - securityConstraint.getUrlPatterns().addAll(getNodeValues(webResourceCollection, "url-pattern")); + getNodeValues(webResourceCollection, "url-pattern").forEach(urlPattern -> securityConstraint.getUrlPatterns().add(new UrlPattern(urlPattern))); // securityConstraint.getResourceNames().addAll(getNodeValues(webResourceCollection, "web-resource-name")); @@ -379,6 +380,7 @@ private void parseSecurityConstraint(WebAppInfo webAppInfo, Element parentElemen if (userDataConstraint != null) { securityConstraint.getTransportGuarantees().addAll(getNodeValues(userDataConstraint, "transport-guarantee")); } + webAppInfo.getSecurityConstraints().add(securityConstraint); } } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/conf/DeploymentInfo.java b/servlet-core/src/main/java/tech/smartboot/servlet/conf/DeploymentInfo.java index 090f91d2..8fee4fd2 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/conf/DeploymentInfo.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/conf/DeploymentInfo.java @@ -64,6 +64,7 @@ public class DeploymentInfo { private List welcomeFiles = Collections.emptyList(); private final Set securityRoles = new HashSet<>(); private final Map localeEncodingMappings = new HashMap<>(); + private final List securityConstraints = new ArrayList<>(); private final ClassLoader classLoader; private String displayName; private URL contextUrl; @@ -123,6 +124,14 @@ public Map getServlets() { return servlets; } + public void addSecurityConstraint(SecurityConstraint securityConstraint) { + securityConstraints.add(securityConstraint); + } + + public List getSecurityConstraints() { + return securityConstraints; + } + public void addErrorPage(final ErrorPageInfo servlet) { if (servlet.getErrorCode() != null) { errorStatusPages.put(servlet.getErrorCode(), servlet); diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/conf/FilterMappingInfo.java b/servlet-core/src/main/java/tech/smartboot/servlet/conf/FilterMappingInfo.java index 4b6bb46b..766a2a01 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/conf/FilterMappingInfo.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/conf/FilterMappingInfo.java @@ -11,9 +11,7 @@ package tech.smartboot.servlet.conf; import jakarta.servlet.DispatcherType; -import jakarta.servlet.http.MappingMatch; import tech.smartboot.servlet.enums.FilterMappingType; -import tech.smartboot.servlet.util.PathMatcherUtil; import java.util.Set; @@ -21,28 +19,19 @@ * @author 三刀 * @version V1.0 , 2020/11/14 */ -public class FilterMappingInfo { +public class FilterMappingInfo extends UrlPattern { private final String filterName; private final FilterMappingType mappingType; private final Set dispatcher; - private final MappingMatch mappingMatch; - private final String urlPattern; private final String servletNameMapping; public FilterMappingInfo(final String filterName, final FilterMappingType mappingType, final String servletNameMapping, String urlPattern, final Set dispatcher) { + super(urlPattern); this.filterName = filterName; this.mappingType = mappingType; this.servletNameMapping = servletNameMapping; this.dispatcher = dispatcher; - if (mappingType == FilterMappingType.URL) { - this.urlPattern = PathMatcherUtil.getUrlPattern(urlPattern); - this.mappingMatch = PathMatcherUtil.getMappingType(this.urlPattern); - } else { - this.urlPattern = null; - this.mappingMatch = null; - } - } public FilterMappingType getMappingType() { @@ -61,11 +50,4 @@ public String getFilterName() { return filterName; } - public String getUrlPattern() { - return urlPattern; - } - - public MappingMatch getMappingMatch() { - return mappingMatch; - } } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/conf/SecurityConstraint.java b/servlet-core/src/main/java/tech/smartboot/servlet/conf/SecurityConstraint.java index 8383f0a7..349ec87e 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/conf/SecurityConstraint.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/conf/SecurityConstraint.java @@ -15,13 +15,13 @@ public class SecurityConstraint { // private final List resourceNames = new ArrayList<>(); - private final List urlPatterns = new ArrayList<>(); + private final List urlPatterns = new ArrayList<>(); private final List httpMethods = new ArrayList<>(); private final List roleNames = new ArrayList<>(); private final List transportGuarantees = new ArrayList<>(); - public List getUrlPatterns() { + public List getUrlPatterns() { return urlPatterns; } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/conf/ServletMappingInfo.java b/servlet-core/src/main/java/tech/smartboot/servlet/conf/ServletMappingInfo.java index c9f90e59..840ecefd 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/conf/ServletMappingInfo.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/conf/ServletMappingInfo.java @@ -10,33 +10,18 @@ package tech.smartboot.servlet.conf; -import jakarta.servlet.http.MappingMatch; -import tech.smartboot.servlet.util.PathMatcherUtil; - /** * @author 三刀 * @version V1.0 , 2020/10/11 */ -public class ServletMappingInfo { +public class ServletMappingInfo extends UrlPattern { private final String servletName; - private final String mapping; - private final MappingMatch mappingType; public ServletMappingInfo(String servletName, String mapping) { - this.mapping = PathMatcherUtil.getUrlPattern(mapping); + super(mapping); this.servletName = servletName; - this.mappingType = PathMatcherUtil.getMappingType(this.mapping); - } - - public String getMapping() { - return mapping; } - public MappingMatch getMappingType() { - return mappingType; - } - - public String getServletName() { return servletName; } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/conf/UrlPattern.java b/servlet-core/src/main/java/tech/smartboot/servlet/conf/UrlPattern.java new file mode 100644 index 00000000..374659cf --- /dev/null +++ b/servlet-core/src/main/java/tech/smartboot/servlet/conf/UrlPattern.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) [2022] smartboot [zhengjunweimail@163.com] + * + * 企业用户未经smartboot组织特别许可,需遵循AGPL-3.0开源协议合理合法使用本项目。 + * + * Enterprise users are required to use this project reasonably + * and legally in accordance with the AGPL-3.0 open source agreement + * without special permission from the smartboot organization. + */ + +package tech.smartboot.servlet.conf; + +import jakarta.servlet.http.MappingMatch; +import tech.smartboot.servlet.util.PathMatcherUtil; + +public class UrlPattern { + private final String urlPattern; + private final MappingMatch mappingMatch; + + public UrlPattern(String urlPattern) { + if (urlPattern == null) { + this.urlPattern = null; + this.mappingMatch = null; + } else { + this.urlPattern = PathMatcherUtil.getUrlPattern(urlPattern); + this.mappingMatch = PathMatcherUtil.getMappingType(this.urlPattern); + } + + } + + public String getUrlPattern() { + return urlPattern; + } + + public MappingMatch getMappingMatch() { + return mappingMatch; + } +} diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/handler/FilterMatchHandler.java b/servlet-core/src/main/java/tech/smartboot/servlet/handler/FilterMatchHandler.java index 6579e5a6..47d775ba 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/handler/FilterMatchHandler.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/handler/FilterMatchHandler.java @@ -84,7 +84,7 @@ private List matchFilters(HandlerContext handlerContext) { if (request.getDispatcherType() == DispatcherType.INCLUDE) { requestURI = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); } - if (PathMatcherUtil.matches(requestURI, contextPath.length(), mappingInfo) > -1) { + if (PathMatcherUtil.matches(requestURI, contextPath.length(), mappingInfo)) { filters.add(handlerContext.getServletContext().getDeploymentInfo().getFilters().get(mappingInfo.getFilterName())); } } else if (mappingInfo.getMappingType() == FilterMappingType.SERVLET) { diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/handler/SecurityHandler.java b/servlet-core/src/main/java/tech/smartboot/servlet/handler/SecurityHandler.java index df821c46..8fe5fea2 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/handler/SecurityHandler.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/handler/SecurityHandler.java @@ -11,13 +11,34 @@ package tech.smartboot.servlet.handler; import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import tech.smartboot.servlet.conf.SecurityConstraint; +import tech.smartboot.servlet.conf.UrlPattern; +import tech.smartboot.servlet.util.PathMatcherUtil; import java.io.IOException; public class SecurityHandler extends Handler { @Override public void handleRequest(HandlerContext handlerContext) throws ServletException, IOException { - + HttpServletRequest request = (HttpServletRequest) handlerContext.getRequest(); + for (SecurityConstraint securityConstraint : handlerContext.getServletContext().getDeploymentInfo().getSecurityConstraints()) { + boolean match = false; + for (UrlPattern urlPattern : securityConstraint.getUrlPatterns()) { + if (PathMatcherUtil.matches((HttpServletRequest) handlerContext.getRequest(), urlPattern)) { + match = true; + break; + } + } + if (!match) { + continue; + } + if (!securityConstraint.getHttpMethods().isEmpty() && !securityConstraint.getHttpMethods().contains(request.getMethod())) { + ((HttpServletResponse) handlerContext.getResponse()).sendError(403); + return; + } + } doNext(handlerContext); } } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/impl/ApplicationServletRegistration.java b/servlet-core/src/main/java/tech/smartboot/servlet/impl/ApplicationServletRegistration.java index b7836ee0..0c2639e3 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/impl/ApplicationServletRegistration.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/impl/ApplicationServletRegistration.java @@ -68,7 +68,7 @@ public void setAsyncSupported(boolean isAsyncSupported) { public Set addMapping(String... urlPatterns) { //If any of the specified URL patterns are already mapped to a different Servlet, no updates will be performed. Set mappingSet = new HashSet<>(Arrays.asList(urlPatterns)); - Set existingMapping = deploymentInfo.getServletMappings().stream().map(ServletMappingInfo::getMapping).filter(mappingSet::contains).collect(Collectors.toSet()); + Set existingMapping = deploymentInfo.getServletMappings().stream().map(ServletMappingInfo::getUrlPattern).filter(mappingSet::contains).collect(Collectors.toSet()); if (!existingMapping.isEmpty()) { //the (possibly empty) Set of URL patterns that are already mapped to a different Servlet return existingMapping; @@ -81,7 +81,7 @@ public Set addMapping(String... urlPatterns) { @Override public Collection getMappings() { - return deploymentInfo.getServletMappings().stream().filter(mapping -> mapping.getServletName().equals(servletInfo.getServletName())).map(ServletMappingInfo::getMapping).collect(Collectors.toList()); + return deploymentInfo.getServletMappings().stream().filter(mapping -> mapping.getServletName().equals(servletInfo.getServletName())).map(ServletMappingInfo::getUrlPattern).collect(Collectors.toList()); } @Override diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletMappingImpl.java b/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletMappingImpl.java index 7428b822..7a7c6e00 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletMappingImpl.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletMappingImpl.java @@ -32,7 +32,7 @@ public String getMatchValue() { @Override public String getPattern() { - return servletMappingInfo.getMapping(); + return servletMappingInfo.getUrlPattern(); } @Override diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletRequestImpl.java b/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletRequestImpl.java index 232199c9..8be22898 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletRequestImpl.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/impl/HttpServletRequestImpl.java @@ -315,9 +315,9 @@ private void initPath() { return; } pathInit = true; - switch (servletMappingInfo.getMappingType()) { + switch (servletMappingInfo.getMappingMatch()) { case EXACT -> { - servletPath = servletMappingInfo.getMapping(); + servletPath = servletMappingInfo.getUrlPattern(); pathInfo = null; } case EXTENSION -> { @@ -325,7 +325,7 @@ private void initPath() { pathInfo = null; } case PATH -> { - servletPath = servletMappingInfo.getMapping().substring(0, servletMappingInfo.getMapping().length() - 2); + servletPath = servletMappingInfo.getUrlPattern().substring(0, servletMappingInfo.getUrlPattern().length() - 2); if (getContextPath().length() + servletPath.length() < getRequestURI().length()) { pathInfo = getRequestURI().substring(getContextPath().length() + servletPath.length()); } @@ -387,8 +387,8 @@ public HttpServletMapping getHttpServletMapping() { return null; } String matchValue; - MappingMatch mappingMatch = servletMappingInfo.getMappingType(); - switch (servletMappingInfo.getMappingType()) { + MappingMatch mappingMatch = servletMappingInfo.getMappingMatch(); + switch (servletMappingInfo.getMappingMatch()) { case DEFAULT: matchValue = ""; if (StringUtils.isBlank(servletContext.getContextPath())) { @@ -396,17 +396,17 @@ public HttpServletMapping getHttpServletMapping() { } break; case EXACT: - matchValue = servletMappingInfo.getMapping(); + matchValue = servletMappingInfo.getUrlPattern(); if (matchValue.startsWith("/")) { matchValue = matchValue.substring(1); } break; case PATH: String servletPath = getServletPath(); - if (servletMappingInfo.getMapping().length() >= servletPath.length() + 2) { + if (servletMappingInfo.getUrlPattern().length() >= servletPath.length() + 2) { matchValue = ""; } else { - matchValue = getServletPath().substring(servletMappingInfo.getMapping().length() - 1); + matchValue = getServletPath().substring(servletMappingInfo.getUrlPattern().length() - 1); } if (matchValue.startsWith("/")) { @@ -414,7 +414,7 @@ public HttpServletMapping getHttpServletMapping() { } break; case EXTENSION: - matchValue = getServletPath().substring(getServletPath().charAt(0) == '/' ? 1 : 0, getServletPath().length() - servletMappingInfo.getMapping().length() + 1); + matchValue = getServletPath().substring(getServletPath().charAt(0) == '/' ? 1 : 0, getServletPath().length() - servletMappingInfo.getUrlPattern().length() + 1); break; default: throw new IllegalStateException(); diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/RequestDispatcherImpl.java b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/RequestDispatcherImpl.java index 1f12fc24..05fa4fcb 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/RequestDispatcherImpl.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/RequestDispatcherImpl.java @@ -182,15 +182,15 @@ public void include(ServletRequest request, ServletResponse response) throws Ser } private String getServerPath(ServletMappingInfo servletMappingInfo, String requestUri) { - switch (servletMappingInfo.getMappingType()) { + switch (servletMappingInfo.getMappingMatch()) { case EXACT -> { - return servletMappingInfo.getMapping(); + return servletMappingInfo.getUrlPattern(); } case EXTENSION -> { return requestUri.substring(servletContext.getContextPath().length()); } case PATH -> { - return servletMappingInfo.getMapping().substring(0, servletMappingInfo.getMapping().length() - 2); + return servletMappingInfo.getUrlPattern().substring(0, servletMappingInfo.getUrlPattern().length() - 2); } } return null; diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/ServletRequestDispatcherWrapper.java b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/ServletRequestDispatcherWrapper.java index a6a2b6c4..152667db 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/ServletRequestDispatcherWrapper.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/dispatcher/ServletRequestDispatcherWrapper.java @@ -123,9 +123,9 @@ private void initPath() { return; } pathInit = true; - switch (servletMappingInfo.getMappingType()) { + switch (servletMappingInfo.getMappingMatch()) { case EXACT -> { - servletPath = servletMappingInfo.getMapping(); + servletPath = servletMappingInfo.getUrlPattern(); pathInfo = null; } case EXTENSION -> { @@ -133,7 +133,7 @@ private void initPath() { pathInfo = null; } case PATH -> { - servletPath = servletMappingInfo.getMapping().substring(0, servletMappingInfo.getMapping().length() - 2); + servletPath = servletMappingInfo.getUrlPattern().substring(0, servletMappingInfo.getUrlPattern().length() - 2); if (getContextPath().length() + servletPath.length() < getRequestURI().length()) { pathInfo = getRequestURI().substring(getContextPath().length() + servletPath.length()); } @@ -177,8 +177,8 @@ public HttpServletMapping getHttpServletMapping() { return null; } String matchValue; - MappingMatch mappingMatch = servletMappingInfo.getMappingType(); - switch (servletMappingInfo.getMappingType()) { + MappingMatch mappingMatch = servletMappingInfo.getMappingMatch(); + switch (servletMappingInfo.getMappingMatch()) { case DEFAULT: matchValue = ""; if (StringUtils.isBlank(getServletContext().getContextPath())) { @@ -186,17 +186,17 @@ public HttpServletMapping getHttpServletMapping() { } break; case EXACT: - matchValue = servletMappingInfo.getMapping(); + matchValue = servletMappingInfo.getUrlPattern(); if (matchValue.startsWith("/")) { matchValue = matchValue.substring(1); } break; case PATH: String servletPath = getServletPath(); - if (servletMappingInfo.getMapping().length() >= servletPath.length() + 2) { + if (servletMappingInfo.getUrlPattern().length() >= servletPath.length() + 2) { matchValue = ""; } else { - matchValue = getServletPath().substring(servletMappingInfo.getMapping().length() - 1); + matchValue = getServletPath().substring(servletMappingInfo.getUrlPattern().length() - 1); } if (matchValue.startsWith("/")) { @@ -204,7 +204,7 @@ public HttpServletMapping getHttpServletMapping() { } break; case EXTENSION: - matchValue = getServletPath().substring(getServletPath().charAt(0) == '/' ? 1 : 0, getServletPath().length() - servletMappingInfo.getMapping().length() + 1); + matchValue = getServletPath().substring(getServletPath().charAt(0) == '/' ? 1 : 0, getServletPath().length() - servletMappingInfo.getUrlPattern().length() + 1); break; default: throw new IllegalStateException(); diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingPlugin.java b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingPlugin.java index a2a546d4..32cbdb13 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingPlugin.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingPlugin.java @@ -19,19 +19,19 @@ public void onContainerStartSuccess(ServletContextRuntime servletContextRuntime) MappingProviderImpl provider = new MappingProviderImpl(servletContextRuntime.getServletContext().getContextPath().length()); servletContextRuntime.setMappingProvider(provider); servletContextRuntime.getDeploymentInfo().getServletMappings().forEach(mapping -> { - switch (mapping.getMappingType()) { + switch (mapping.getMappingMatch()) { case DEFAULT: provider.setDefaultMapping(mapping); break; case EXACT: - provider.getExactMapping().put(mapping.getMapping(), mapping); + provider.getExactMapping().put(mapping.getUrlPattern(), mapping); break; case EXTENSION: provider.getExtensionMappings().add(mapping); break; case PATH: provider.getPathMappings().add(mapping); - provider.getPathMappings().sort((o1, o2) -> o2.getMapping().length() - o1.getMapping().length()); + provider.getPathMappings().sort((o1, o2) -> o2.getUrlPattern().length() - o1.getUrlPattern().length()); break; } }); diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingProviderImpl.java b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingProviderImpl.java index 01083a66..df8d2236 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingProviderImpl.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/plugins/mapping/MappingProviderImpl.java @@ -40,7 +40,7 @@ public ServletMappingInfo matchServlet(String requestUri) { //路径匹配 int remaining = requestUri.length() - offset; for (ServletMappingInfo mappingInfo : pathMappings) { - int matchLength = mappingInfo.getMapping().length() - 2; + int matchLength = mappingInfo.getUrlPattern().length() - 2; if (remaining < matchLength) { //后续一定更短 continue; @@ -48,7 +48,7 @@ public ServletMappingInfo matchServlet(String requestUri) { boolean match = true; for (int i = 0; i < matchLength; i++) { - if (requestUri.charAt(i + offset) != mappingInfo.getMapping().charAt(i)) { + if (requestUri.charAt(i + offset) != mappingInfo.getUrlPattern().charAt(i)) { match = false; break; } @@ -61,9 +61,9 @@ public ServletMappingInfo matchServlet(String requestUri) { //后缀匹配 for (ServletMappingInfo mappingInfo : extensionMappings) { boolean match = true; - for (int i = 1; i < mappingInfo.getMapping().length() - 1; i++) { - if (requestUri.charAt(requestUri.length() - i) != mappingInfo.getMapping().charAt(mappingInfo - .getMapping().length() - i)) { + for (int i = 1; i < mappingInfo.getUrlPattern().length() - 1; i++) { + if (requestUri.charAt(requestUri.length() - i) != mappingInfo.getUrlPattern().charAt(mappingInfo + .getUrlPattern().length() - i)) { match = false; break; } diff --git a/servlet-core/src/main/java/tech/smartboot/servlet/util/PathMatcherUtil.java b/servlet-core/src/main/java/tech/smartboot/servlet/util/PathMatcherUtil.java index eb4eb67d..35fe0bb9 100644 --- a/servlet-core/src/main/java/tech/smartboot/servlet/util/PathMatcherUtil.java +++ b/servlet-core/src/main/java/tech/smartboot/servlet/util/PathMatcherUtil.java @@ -10,9 +10,9 @@ package tech.smartboot.servlet.util; +import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.MappingMatch; -import tech.smartboot.servlet.conf.FilterMappingInfo; -import tech.smartboot.servlet.conf.ServletMappingInfo; +import tech.smartboot.servlet.conf.UrlPattern; import java.net.URI; import java.net.URISyntaxException; @@ -59,20 +59,25 @@ public static MappingMatch getMappingType(String urlPattern) { } } + public static boolean matches(HttpServletRequest request, UrlPattern mappingInfo) { + String uri = request.getRequestURI(); + return matches(uri, request.getContextPath().length(), mappingInfo); + } + /** * @param uri * @param startIndex * @param mappingInfo * @return 0:根目录匹配 */ - public static int matches(String uri, int startIndex, FilterMappingInfo mappingInfo) { + public static boolean matches(String uri, int startIndex, UrlPattern mappingInfo) { String pattern = mappingInfo.getUrlPattern(); MappingMatch mappingTypeEnum = mappingInfo.getMappingMatch(); int servletPathEndIndex = -1; switch (mappingTypeEnum) { case DEFAULT: if ("/".equals(pattern)) { - return 0; + return true; } break; //精准匹配 @@ -82,15 +87,15 @@ public static int matches(String uri, int startIndex, FilterMappingInfo mappingI // 即,http://host:port// 请求形式。 // 在这种情况下,路径信息是‘/’且 servlet 路径和上下文路径是空字符串(“”)。 if (uri.length() == startIndex || "/".equals(pattern)) { - return 0; + return true; } if (uri.length() - startIndex != pattern.length()) { - return -1; + return false; } //第一位肯定是"/",从第二位开始匹配 for (int i = 1; i < pattern.length(); i++) { if (uri.charAt(startIndex + i) != pattern.charAt(i)) { - return -1; + return false; } } servletPathEndIndex = startIndex + pattern.length(); @@ -103,22 +108,22 @@ public static int matches(String uri, int startIndex, FilterMappingInfo mappingI // 在这种情况下,路径信息是‘/’且 servlet 路径和上下文路径是空字符串(“”)。 //pattern.length() == 2 等同于 "/*".equals(pattern) if (uri.length() == startIndex && pattern.length() == 2) { - return 0; + return true; } //舍去"/ab/*"最后一位"/*" int matchLen = pattern.length() - 2; int remainingLen = uri.length() - startIndex; if (remainingLen < matchLen) { - return -1; + return false; } if (remainingLen >= matchLen + 1 && uri.charAt(startIndex + matchLen) != '/') { - return -1; + return false; } //第一位肯定是"/",从第二位开始匹配 for (int i = 1; i < matchLen; i++) { if (uri.charAt(startIndex + i) != pattern.charAt(i)) { - return -1; + return false; } } @@ -129,11 +134,11 @@ public static int matches(String uri, int startIndex, FilterMappingInfo mappingI // 不比较"*.xx" 中的 * int uriStartIndex = uri.length() - pattern.length(); if (uriStartIndex <= 0) { - return -1; + return false; } for (int i = 1; i < pattern.length(); i++) { if (uri.charAt(uriStartIndex + i) != pattern.charAt(i)) { - return -1; + return false; } } servletPathEndIndex = uri.length(); @@ -141,6 +146,6 @@ public static int matches(String uri, int startIndex, FilterMappingInfo mappingI default: throw new IllegalStateException("unSupport mappingType " + mappingTypeEnum); } - return servletPathEndIndex; + return true; } } \ No newline at end of file