rename to package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x

This commit is contained in:
luyanbo 2024-02-27 20:51:09 +08:00 committed by LearningGp
parent 0ca82b63b7
commit 6c475480eb
28 changed files with 442 additions and 129 deletions

View File

@ -33,8 +33,13 @@ jobs:
java-version: 17
distribution: 'temurin'
- name: Test with Maven
- name: Maven Test With Spring 6.x
run: mvn --batch-mode test -Dsurefire.jdk-toolchain-version=${{ matrix.java }}
if: ${{ matrix.java >= 17 }}
- name: Maven Test Without Spring 6.x
run: mvn --batch-mode test -Dsurefire.jdk-toolchain-version=${{ matrix.java }} -Dskip.spring.v6x.test=true
if: ${{ matrix.java < 17 }}
- name: Build with Maven
run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -DminimumPriority=1

View File

@ -159,6 +159,13 @@
<artifactId>sentinel-cluster-common-default</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-adapter-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-adapter</artifactId>

View File

@ -27,8 +27,9 @@
<module>sentinel-spring-webflux-adapter</module>
<module>sentinel-api-gateway-adapter-common</module>
<module>sentinel-spring-cloud-gateway-adapter</module>
<module>sentinel-web-adapter-common</module>
<module>sentinel-spring-webmvc-adapter</module>
<module>sentinel-spring-webmvc-6x-adapter</module>
<module>sentinel-spring-webmvc-v6x-adapter</module>
<module>sentinel-zuul2-adapter</module>
<module>sentinel-okhttp-adapter</module>
<module>sentinel-jax-rs-adapter</module>

View File

@ -25,6 +25,8 @@ import org.springframework.web.servlet.HandlerMapping;
/**
* Spring Web MVC interceptor that integrates with Sentinel.
* <p>
* This will record resource as `${uri}`.
*
* @author kaizi2009
* @since 1.7.1

View File

@ -9,7 +9,7 @@ Add the following dependency in `pom.xml` (if you are using Maven):
```xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-webmvc-adapter</artifactId>
<artifactId>sentinel-spring-webmvc-v6x-adapter</artifactId>
<version>x.y.z</version>
</dependency>
```

View File

@ -5,21 +5,21 @@
<parent>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-adapter</artifactId>
<version>2.0.0-SNAPSHOT</version>
<version>1.8.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-spring-webmvc-6x-adapter</artifactId>
<artifactId>sentinel-spring-webmvc-v6x-adapter</artifactId>
<packaging>jar</packaging>
<properties>
<spring.version>6.0.2</spring.version>
<spring.boot.version>3.0.0</spring.boot.version>
<servlet.api.version>6.0.0</servlet.api.version>
<java.source.version>17</java.source.version>
<java.target.version>17</java.target.version>
<slf4j-api.version>2.0.4</slf4j-api.version>
<jakarta.xml.bind-api.version>4.0.0</jakarta.xml.bind-api.version>
<slf4j-api.version>2.0.4</slf4j-api.version>
<skip.spring.v6x.test>false</skip.spring.v6x.test>
</properties>
<dependencies>
@ -27,6 +27,11 @@
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-adapter-common</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
@ -39,7 +44,6 @@
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -52,6 +56,12 @@
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
@ -62,6 +72,15 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
@ -83,12 +102,17 @@
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.version}</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.2.5</version>
</dependency>
</dependencies>
<configuration>
<source>${java.source.version}</source>
<target>${java.target.version}</target>
<encoding>${java.encoding}</encoding>
<skipTests>${skip.spring.v6x.test}</skipTests>
</configuration>
</plugin>
</plugins>

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,23 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.ResourceTypeConstants;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.BaseWebMvcConfig;
import com.alibaba.csp.sentinel.*;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config.BaseWebMvcConfig;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@ -37,20 +31,19 @@ import org.springframework.web.servlet.ModelAndView;
* Since request may be reprocessed in flow if any forwarding or including or other action
* happened (see {@link jakarta.servlet.ServletRequest#getDispatcherType()}) we will only
* deal with the initial request. So we use <b>reference count</b> to track in
* dispathing "onion" though which we could figure out whether we are in initial type "REQUEST".
* dispatching "onion" though which we could figure out whether we are in initial type "REQUEST".
* That means the sub-requests which we rarely meet in practice will NOT be recorded in Sentinel.
* <p>
* How to implement a forward sub-request in your action:
* <pre>
* initalRequest() {
* initialRequest() {
* ModelAndView mav = new ModelAndView();
* mav.setViewName("another");
* return mav;
* }
* </pre>
*
* @author kaizi2009
* @since 1.7.1
* @since 1.8.8
*/
public abstract class AbstractSentinelInterceptor implements HandlerInterceptor {
@ -71,7 +64,7 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor
* @param step
* @return reference count after increasing (initial value as zero to be increased)
*/
private Integer increaseReferece(HttpServletRequest request, String rcKey, int step) {
private Integer increaseReference(HttpServletRequest request, String rcKey, int step) {
Object obj = request.getAttribute(rcKey);
if (obj == null) {
@ -87,17 +80,15 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String resourceName = "";
try {
String resourceName = getResourceName(request);
resourceName = getResourceName(request);
if (StringUtil.isEmpty(resourceName)) {
return true;
}
if (increaseReferece(request, this.baseWebMvcConfig.getRequestRefName(), 1) != 1) {
if (increaseReference(request, this.baseWebMvcConfig.getRequestRefName(), 1) != 1) {
return true;
}
// Parse the request origin using registered origin parser.
String origin = parseOrigin(request);
String contextName = getContextName(request);
@ -107,7 +98,7 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor
return true;
} catch (BlockException e) {
try {
handleBlockException(request, response, e);
handleBlockException(request, response, resourceName, e);
} finally {
ContextUtil.exit();
}
@ -136,7 +127,7 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
if (increaseReferece(request, this.baseWebMvcConfig.getRequestRefName(), -1) != 0) {
if (increaseReference(request, this.baseWebMvcConfig.getRequestRefName(), -1) != 0) {
return;
}
@ -148,6 +139,11 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor
return;
}
// Record the status code here.
// String resourceName = entry.getResourceWrapper().getName();
// int status = response.getStatus();
// StatusCodeMetricManager.getInstance().recordStatusCode(resourceName, status);
traceExceptionAndExit(entry, ex);
removeEntryInRequest(request);
ContextUtil.exit();
@ -176,12 +172,18 @@ public abstract class AbstractSentinelInterceptor implements HandlerInterceptor
}
}
protected void handleBlockException(HttpServletRequest request, HttpServletResponse response, BlockException e)
protected void handleBlockException(HttpServletRequest request, HttpServletResponse response, String resourceName,
BlockException e)
throws Exception {
if (baseWebMvcConfig.getBlockExceptionHandler() != null) {
baseWebMvcConfig.getBlockExceptionHandler().handle(request, response, e);
baseWebMvcConfig.getBlockExceptionHandler().handle(request, response, resourceName, e);
// Record status when blocked
// int status = response.getStatus();
// StatusCodeMetricManager.getInstance().recordStatusCode(resourceName, status);
} else {
// Throw BlockException directly. Users need to handle it in Spring global exception handler.
// NOTE: the status code statistics will be lost here!
throw e;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,21 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.SentinelWebMvcConfig;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config.SentinelWebMvcConfig;
import com.alibaba.csp.sentinel.adapter.web.common.UrlCleaner;
import jakarta.servlet.http.HttpServletRequest;
import com.alibaba.csp.sentinel.util.StringUtil;
import org.springframework.web.servlet.HandlerMapping;
/**
* Spring Web MVC interceptor that integrates with Sentinel.
* <p>
* This will record resource as `${uri}`.
*
* @author kaizi2009
* @since 1.7.1
* @since 1.8.8
*/
public class SentinelWebInterceptor extends AbstractSentinelInterceptor {
@ -59,9 +59,8 @@ public class SentinelWebInterceptor extends AbstractSentinelInterceptor {
if (urlCleaner != null) {
resourceName = urlCleaner.clean(resourceName);
}
// Add method specification if necessary
if (StringUtil.isNotEmpty(resourceName) && config.isHttpMethodSpecify()) {
resourceName = request.getMethod().toUpperCase() + ":" + resourceName;
if (config.isContextPathSpecify() && request.getContextPath() != null) {
resourceName = request.getContextPath() + resourceName;
}
return resourceName;
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import com.alibaba.csp.sentinel.util.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
/**
* Spring Web MVC interceptor that integrates with Sentinel.
* <p>
* This will record resource as `${httpMethod}:${uri}`.
*
* @since 1.8.8
*/
public class SentinelWebPrefixInterceptor extends SentinelWebInterceptor {
@Override
protected String getResourceName(HttpServletRequest request) {
String resourceName = super.getResourceName(request);
// Add method specification
if (StringUtil.isNotEmpty(resourceName)) {
resourceName = request.getMethod().toUpperCase() + ":" + resourceName;
}
return resourceName;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.SentinelWebMvcTotalConfig;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config.SentinelWebMvcTotalConfig;
import jakarta.servlet.http.HttpServletRequest;
@ -23,8 +23,7 @@ import jakarta.servlet.http.HttpServletRequest;
* The web interceptor for all requests, which will unify all URL as
* a single resource name (configured in {@link SentinelWebMvcTotalConfig}).
*
* @author kaizi2009
* @since 1.7.1
* @since 1.8.8
*/
public class SentinelWebTotalInterceptor extends AbstractSentinelInterceptor {

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.callback;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback;
import com.alibaba.csp.sentinel.slots.block.BlockException;
@ -23,7 +23,7 @@ import jakarta.servlet.http.HttpServletResponse;
/**
* Handler for the blocked request.
*
* @author kaizi2009
* @since 1.8.8
*/
public interface BlockExceptionHandler {
@ -32,9 +32,11 @@ public interface BlockExceptionHandler {
*
* @param request Servlet request
* @param response Servlet response
* @param resourceName resource name
* @param e the block exception
* @throws Exception users may throw out the BlockException or other error occurs
*/
void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception;
void handle(HttpServletRequest request, HttpServletResponse response, String resourceName, BlockException e)
throws Exception;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,23 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.callback;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* Default handler for the blocked request.
*
* @author kaizi2009
* @since 1.8.8
*/
public class DefaultBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
public void handle(HttpServletRequest request, HttpServletResponse response, String resourceName, BlockException ex)
throws Exception {
// Return 429 (Too Many Requests) by default.
response.setStatus(429);
@ -38,5 +39,4 @@ public class DefaultBlockExceptionHandler implements BlockExceptionHandler {
out.flush();
out.close();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.callback;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback;
import jakarta.servlet.http.HttpServletRequest;
/**
* The origin parser parses request origin (e.g. IP, user, appName) from HTTP request.
*
* @author kaizi2009
* @since 1.8.8
*/
public interface RequestOriginParser {

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,22 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.config;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.DefaultBlockExceptionHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.RequestOriginParser;
/**
* Common base configuration for Spring Web MVC adapter.
*
* @author kaizi2009
* @since 1.7.1
* @since 1.8.8
*/
public abstract class BaseWebMvcConfig {
protected String requestAttributeName;
protected String requestRefName;
protected BlockExceptionHandler blockExceptionHandler;
protected BlockExceptionHandler blockExceptionHandler = new DefaultBlockExceptionHandler();
protected RequestOriginParser originParser;
public String getRequestAttributeName() {

View File

@ -0,0 +1,57 @@
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
import com.alibaba.csp.sentinel.adapter.web.common.UrlCleaner;
/**
* @since 1.8.8
*/
public class SentinelPreWebMvcConfig extends BaseWebMvcConfig {
public static final String DEFAULT_REQUEST_ATTRIBUTE_NAME = "$$sentinel_pre_spring_web_entry_attr";
private UrlCleaner urlCleaner;
/**
* Specify whether the URL resource name should contain the HTTP method prefix (e.g. {@code POST:}).
*/
private boolean httpMethodSpecify;
/**
* Specify whether unify web context(i.e. use the default context name), and is true by default.
*
* @since 1.7.2
*/
private boolean webContextUnify = true;
public SentinelPreWebMvcConfig() {
super();
setRequestAttributeName(DEFAULT_REQUEST_ATTRIBUTE_NAME);
}
public boolean isHttpMethodSpecify() {
return httpMethodSpecify;
}
public SentinelPreWebMvcConfig setHttpMethodSpecify(boolean httpMethodSpecify) {
this.httpMethodSpecify = httpMethodSpecify;
return this;
}
public boolean isWebContextUnify() {
return webContextUnify;
}
public SentinelPreWebMvcConfig setWebContextUnify(boolean webContextUnify) {
this.webContextUnify = webContextUnify;
return this;
}
public UrlCleaner getUrlCleaner() {
return urlCleaner;
}
public SentinelPreWebMvcConfig setUrlCleaner(UrlCleaner urlCleaner) {
this.urlCleaner = urlCleaner;
return this;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,13 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.config;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import com.alibaba.csp.sentinel.adapter.web.common.UrlCleaner;
/**
* @author kaizi2009
* @since 1.7.1
* @since 1.8.8
*/
public class SentinelWebMvcConfig extends BaseWebMvcConfig {
@ -35,6 +34,12 @@ public class SentinelWebMvcConfig extends BaseWebMvcConfig {
*/
private boolean httpMethodSpecify;
/**
* Specify whether the URL resource name should contain the HTTP method prefix in MSE (e.g. {@code GET:}).
*/
private static boolean mseHttpMethodSpecify;
/**
* Specify whether unify web context(i.e. use the default context name), and is true by default.
*
@ -42,9 +47,25 @@ public class SentinelWebMvcConfig extends BaseWebMvcConfig {
*/
private boolean webContextUnify = true;
/**
* Specify whether the URL resource name should contain the context-path
*/
private boolean contextPathSpecify = true;
public SentinelWebMvcConfig() {
super();
setRequestAttributeName(DEFAULT_REQUEST_ATTRIBUTE_NAME);
try {
String enable = System.getProperty("spring.cloud.mse.sentinel.web.http-method-prefix","true");
if(enable != null){
mseHttpMethodSpecify = Boolean.parseBoolean(enable);
}
String enableContextPath = System.getProperty("spring.cloud.ahas.sentinel.web.context-path", "true");
if (enableContextPath != null) {
contextPathSpecify = Boolean.parseBoolean(enableContextPath);
}
} catch (Exception ignore) {
}
}
public UrlCleaner getUrlCleaner() {
@ -65,6 +86,10 @@ public class SentinelWebMvcConfig extends BaseWebMvcConfig {
return this;
}
public static boolean isMseHttpMethodSpecify() {
return mseHttpMethodSpecify;
}
public boolean isWebContextUnify() {
return webContextUnify;
}
@ -74,12 +99,22 @@ public class SentinelWebMvcConfig extends BaseWebMvcConfig {
return this;
}
public boolean isContextPathSpecify() {
return contextPathSpecify;
}
public SentinelWebMvcConfig setContextPathSpecify(boolean contextPathSpecify) {
this.contextPathSpecify = contextPathSpecify;
return this;
}
@Override
public String toString() {
return "SentinelWebMvcConfig{" +
"urlCleaner=" + urlCleaner +
", httpMethodSpecify=" + httpMethodSpecify +
", webContextUnify=" + webContextUnify +
", contextPathSpecify=" + contextPathSpecify +
", requestAttributeName='" + requestAttributeName + '\'' +
", blockExceptionHandler=" + blockExceptionHandler +
", originParser=" + originParser +

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.config;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
/**
* @author kaizi2009
* @since 1.7.1
* @since 1.8.8
*/
public class SentinelWebMvcTotalConfig extends BaseWebMvcConfig {

View File

@ -0,0 +1,87 @@
/*
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.util.StringUtil;
/**
* The configuration center for Web Servlet adapter (ported to Spring Web adapter).
*
* @since 1.8.8
*/
public final class WebServletLocalConfig {
public static final String BLOCK_PAGE_URL_CONF_KEY = "csp.sentinel.web.servlet.block.page";
public static final String BLOCK_PAGE_HTTP_STATUS_CONF_KEY = "csp.sentinel.web.servlet.block.status";
public static final String BLOCK_PAGE_ALLOW_ORIGINS_CONF_KEY = "csp.sentinel.web.servlet.block.cors-allow-origins";
private static final int HTTP_STATUS_TOO_MANY_REQUESTS = 429;
/**
* Get redirecting page when blocked by Sentinel.
*
* @return the block page URL, maybe null if not configured.
*/
public static String getBlockPage() {
return SentinelConfig.getConfig(BLOCK_PAGE_URL_CONF_KEY);
}
public static void setBlockPage(String blockPage) {
SentinelConfig.setConfig(BLOCK_PAGE_URL_CONF_KEY, blockPage);
}
/**
* <p>Get the HTTP status when using the default block page.</p>
* <p>You can set the status code with the {@code -Dcsp.sentinel.web.servlet.block.status}
* property. When the property is empty or invalid, Sentinel will use 429 (Too Many Requests)
* as the default status code.</p>
*
* @return the HTTP status of the default block page
*/
public static int getBlockPageHttpStatus() {
String value = SentinelConfig.getConfig(BLOCK_PAGE_HTTP_STATUS_CONF_KEY);
if (StringUtil.isEmpty(value)) {
return HTTP_STATUS_TOO_MANY_REQUESTS;
}
try {
int s = Integer.parseInt(value);
if (s <= 0) {
throw new IllegalArgumentException("Invalid status code: " + s);
}
return s;
} catch (Exception e) {
RecordLog.warn("[WebServletConfig] Invalid block HTTP status (" + value + "), using default 429");
setBlockPageHttpStatus(HTTP_STATUS_TOO_MANY_REQUESTS);
}
return HTTP_STATUS_TOO_MANY_REQUESTS;
}
/**
* Set the HTTP status of the default block page.
*
* @param httpStatus the HTTP status of the default block page
*/
public static void setBlockPageHttpStatus(int httpStatus) {
if (httpStatus <= 0) {
throw new IllegalArgumentException("Invalid HTTP status code: " + httpStatus);
}
SentinelConfig.setConfig(BLOCK_PAGE_HTTP_STATUS_CONF_KEY, String.valueOf(httpStatus));
}
private WebServletLocalConfig() {}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import com.alibaba.fastjson.JSONObject;

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,14 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.SentinelWebMvcConfig;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config.SentinelWebMvcConfig;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @author Eric Zhao
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* @author kaizi2009

View File

@ -0,0 +1,25 @@
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import static org.junit.Assert.assertEquals;
public class DefaultBlockExceptionHandlerTest {
@Test
public void handle_writeBlockPage() throws Exception {
DefaultBlockExceptionHandler h = new DefaultBlockExceptionHandler();
MockHttpServletRequest req = new MockHttpServletRequest("GET", "/a/b/c");
req.setQueryString("a=1&b=2");
MockHttpServletResponse resp = new MockHttpServletResponse();
String resourceName = "/a/b/c";
BlockException ex = new FlowException("msg");
h.handle(req, resp, resourceName, ex);
assertEquals(429, resp.getStatus());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.config;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebTotalInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.SentinelWebInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.SentinelWebTotalInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.RequestOriginParser;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@ -50,8 +50,8 @@ public class InterceptorConfig implements WebMvcConfigurer {
config.setBlockExceptionHandler(new BlockExceptionHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
String resourceName = e.getRule().getResource();
public void handle(HttpServletRequest request, HttpServletResponse response, String resourceName, BlockException e) throws Exception {
resourceName = e.getRule().getResource();
//Depending on your situation, you can choose to process or throw
if ("/hello".equals(resourceName)) {
//Do something ......

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.config;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.config;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.ResultWrapper;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.ResultWrapper;
import com.alibaba.csp.sentinel.slots.block.AbstractRule;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.slf4j.Logger;

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.controller;
package com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.controller;
import org.springframework.web.bind.annotation.GetMapping;

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sentinel-adapter</artifactId>
<groupId>com.alibaba.csp</groupId>
<version>1.8.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-web-adapter-common</artifactId>
<packaging>jar</packaging>
<properties>
<java.source.version>8</java.source.version>
<java.target.version>8</java.target.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
* Copyright 1999-2024 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.spring.webmvc.callback;
package com.alibaba.csp.sentinel.adapter.web.common;
/**
* Unify the resource target.
*
* @author kaizi2009
* @since 1.8.8
*/
public interface UrlCleaner {