In the spring mvc, we know that user-initiated request can be matched by the url to us by @RequestMapping
the service endpoint defined; do not know if we have had a few questions to think
A project, whether there is exactly the same url?
Http protocol has an understanding of students may soon be able to give the answer, of course, be the same url, different methods can be requested; it can appear the same url and the request method l also do the same?
This article will explain how to use the RequestCondition
combination RequestMappingHandlerMapping
to achieve the expansion url matching rules to support the case presented above
I. environment-related
This article describes the content and practical case will be based on spring-boot-2.2.1.RELEASE
version, if at the time of the test and found that some places can not compatible, determine what version
1. Project to build
First, we need to build a web project to facilitate the subsequent examples demonstrate servelt registered, you can create a project by spring boot official website, you can also create a maven project, the following configuration in pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
复制代码
2. RequestCondition Introduction
In the spring mvc by DispatchServlet
receiving a request initiated by the client after the corresponding request will be acquired by HanderMapping processor; and how to find HanderMapping processor can handle this request it, which requires RequestCondition to decide the
Interface is shown below, there are three main methods,
public interface RequestCondition<T> {
// 一个http接口上有多个条件规则时,用于合并
T combine(T other);
// 这个是重点,用于判断当前匹配条件和请求是否匹配;如果不匹配返回null
// 如果匹配,生成一个新的请求匹配条件,该新的请求匹配条件是当前请求匹配条件针对指定请求request的剪裁
// 举个例子来讲,如果当前请求匹配条件是一个路径匹配条件,包含多个路径匹配模板,
// 并且其中有些模板和指定请求request匹配,那么返回的新建的请求匹配条件将仅仅
// 包含和指定请求request匹配的那些路径模板。
@Nullable
T getMatchingCondition(HttpServletRequest request);
// 针对指定的请求对象request发现有多个满足条件的,用来排序指定优先级,使用最优的进行响应
int compareTo(T other, HttpServletRequest request);
}
复制代码
Simply put under the action of the three interfaces
-
combine
: When an interface has multiple rules, merger - such as the class specified@RequestMapping
in the url isroot
- designated method on@RequestMapping
the url ismethod
- when you get this url matching rules interface, class scan once, scan method once, this time you need to merge these two into one, indicating that the interface matchesroot/method
-
getMatchingCondition
: - determine success, failure to return null; otherwise, it returns the matching conditions for success -
compareTo
: - a plurality of conditions are satisfied, to specify a specific choice
In Spring MVC, the default provides the following categories
class | Explanation |
---|---|
PatternsRequestCondition | Path matching, i.e. url |
RequestMethodsRequestCondition | Request method, http request method refers to note |
ParamsRequestCondition | Request parameters that match the criteria |
HeadersRequestCondition | Request header matches |
ConsumesRequestCondition | Consumable MIME matching condition |
ProducesRequestCondition | MIME matching condition may be generated |
II. Example illustrates
Simply look at the instructions, may do not really understand how it is used, then we pass a practical case, to demonstrate the use posture
1. Scene Description
We have a service simultaneously for app / wap / pc three platforms, we want to specify some interfaces can only provide services for a particular platform
2. Implement
First we define by request header x-platform
to distinguish platform; that is user-initiated requests, the need to carry this request header
Define enumeration class platform
public enum PlatformEnum {
PC("pc", 1), APP("app", 1), WAP("wap", 1), ALL("all", 0);
@Getter
private String name;
@Getter
private int order;
PlatformEnum(String name, int order) {
this.name = name;
this.order = order;
}
public static PlatformEnum nameOf(String name) {
if (name == null) {
return ALL;
}
name = name.toLowerCase().trim();
for (PlatformEnum sub : values()) {
if (sub.name.equals(name)) {
return sub;
}
}
return ALL;
}
}
复制代码
Then define a comment @Platform
, if you need to specify an interface platform, you can add this comment
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Platform {
PlatformEnum value() default PlatformEnum.ALL;
}
复制代码
Definition of matching rules PlatformRequestCondition
inherited from RequestCondition
achieve three interfaces, the request header acquisition platform, according to whether or not the same over the internet can be supported is determined whether a request
public class PlatformRequestCondition implements RequestCondition<PlatformRequestCondition> {
@Getter
@Setter
private PlatformEnum platform;
public PlatformRequestCondition(PlatformEnum platform) {
this.platform = platform;
}
@Override
public PlatformRequestCondition combine(PlatformRequestCondition other) {
return new PlatformRequestCondition(other.platform);
}
@Override
public PlatformRequestCondition getMatchingCondition(HttpServletRequest request) {
PlatformEnum platform = this.getPlatform(request);
if (this.platform.equals(platform)) {
return this;
}
return null;
}
/**
* 优先级
*
* @param other
* @param request
* @return
*/
@Override
public int compareTo(PlatformRequestCondition other, HttpServletRequest request) {
int thisOrder = this.platform.getOrder();
int otherOrder = other.platform.getOrder();
return otherOrder - thisOrder;
}
private PlatformEnum getPlatform(HttpServletRequest request) {
String platform = request.getHeader("x-platform");
return PlatformEnum.nameOf(platform);
}
}
复制代码
After completion of the specified matching rules need to register to take effect on HandlerMapping, here we have a customPlatformHandlerMapping
public class PlatformHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
return buildFrom(AnnotationUtils.findAnnotation(handlerType, Platform.class));
}
@Override
protected RequestCondition<?> getCustomMethodCondition(Method method) {
return buildFrom(AnnotationUtils.findAnnotation(method, Platform.class));
}
private PlatformRequestCondition buildFrom(Platform platform) {
return platform == null ? null : new PlatformRequestCondition(platform.value());
}
}
复制代码
Finally, there is the need to register to our HandlerMapping Spring MVC container, where we use WebMvcConfigurationSupport
to manually register (note the different versions, the following method may be not the same oh)
@Configuration
public class Config extends WebMvcConfigurationSupport {
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
PlatformHandlerMapping handlerMapping = new PlatformHandlerMapping();
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
return handlerMapping;
}
}
复制代码
3. Test
Next, enter the actual link, defined several interfaces, specify different platforms
@RestController
@RequestMapping(path = "method")
public class DemoMethodRest {
@Platform
@GetMapping(path = "index")
public String allIndex() {
return "default index";
}
@Platform(PlatformEnum.PC)
@GetMapping(path = "index")
public String pcIndex() {
return "pc index";
}
@Platform(PlatformEnum.APP)
@GetMapping(path = "index")
public String appIndex() {
return "app index";
}
@Platform(PlatformEnum.WAP)
@GetMapping(path = "index")
public String wapIndex() {
return "wap index";
}
}
复制代码
If our normal rules can take effect, set different in the request header x-platform
, the returned results should be different, the measured results are as follows
Note that the last two, one specifies a request header does not match our platform is not a corresponding request header, are both the default matching rules; this is because we are PlatformRequestCondition
made compatible, it can not match the platform when assigned to the defaultPlatform.ALL
Then there is a little doubt that if there is no distinction between a service platform, so do not add @Platform
annotations if you can do?
@GetMapping(path = "hello")
public String hello() {
return "hello";
}
复制代码
Of course, it can be measured as follows:
Without plus @Platform
when annotation thing to note, at this time can not appear the same multiple url and request method, the startup will be directly thrown oh
III. Other
web series Bowen
- 191206-SpringBoot series of tutorials web registration papers Listener four kinds of postures
- 191122-SpringBoot series of tutorials web articles Servlet registered four postures
- 191120-SpringBoot Web tutorial series of articles open GZIP Data Compression
- 191018-SpringBoot chapter of the series of tutorials web filter Filter Guide extension piece
- 191016-SpringBoot chapter of the series of tutorials web filter Filter Guide
- 191012-SpringBoot series of tutorials custom web articles of exception handling HandlerExceptionResolver
- 191010-SpringBoot global web tutorial series of articles Exception Handling
- 404, 500 exception page 190930-SpringBoot chapter of the series of tutorials web configuration
- 190929-SpringBoot series of articles tutorials web redirection
- 190913-SpringBoot chapter of the return series of tutorials web text, web pages, images operation posture
- 190905-SpringBoot series of tutorials web articles solve the problem of Chinese garbled
- 190831-SpringBoot web tutorial series of articles on how to customize parameter parser
- 190828-SpringBoot series of tutorials web articles Post request parameter parsing posture Summary
- 190824-SpringBoot series of tutorials web articles Get request parameter parsing posture Summary
- 190822-SpringBoot chapter of the series of tutorials web environment to build Beetl
- 190820-SpringBoot chapter of the series of tutorials web environment to build Thymeleaf
- 190816-SpringBoot chapter of the series of tutorials web environment to build Freemaker
- websocket the advanced part of the WEB 190421-SpringBoot instructions
- 190327-Spring-RestTemplate urlencode parameter analysis of abnormal full analysis
- 190317-Spring MVC-based web application of java config xml configuration without building
- 190316-Spring MVC-based web application to build the xml configuration
- 190213-SpringBoot file upload prompts anomalies The temporary upload location xxx is not valid
Source Project
- Project: github.com/liuyueyi/sp...
- Project: github.com/liuyueyi/sp...
1. A gray Blog
Believe everything the book is not as good, above, is purely one of the words, due to limited personal capacity, it is inevitable omissions and mistakes, such as find a bug or have better suggestions are welcome criticism and generous gratitude
Here a gray personal blog, recording all study and work in the blog, welcome to go around
- A gray Blog personal blog blog.hhui.top
- A gray Blog-Spring thematic blog spring.hhui.top