Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize Interface Grayscale Publishing with springboot

2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "how to achieve interface grayscale release by springboot". In daily operation, I believe many people have doubts about how to achieve interface grayscale release by springboot. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to achieve interface grayscale release by springboot". Next, please follow the editor to study!

Preface

Students who know something about grayscale publishing should know that one of the purposes of grayscale publishing is to be able to take different forms interactively according to the adjustment of business rules. For example, there are currently two versions, V1.0 and V2.0. Then the possible forms of expression are as follows:

V1.0, and the interaction on the interface is in the form of B on the interface of version 2. 0.

For an interaction, for the same interface A, V1.0, request interface A, the required return value includes 5 fields; V2.0, request interface A, the required return value includes 10 fields

An interaction, in V1.0 and V2.0, will use different interfaces

The actual situation may be more complicated. Today, when micro-services are widely used, the general idea is that through an API to obtain configuration, the frontend gets all the parameter configurations. Depending on the parameter configuration, the specific implementation ideas are as follows:

For example, in V1, a configuration with a value of 1 is used to interact with A; if you want to use interaction B, you only need to change the value of the configuration center to 2, and the front end can cut the interaction to bit B.

In other words, the interaction remains the same, but the processing logic of the interaction becomes more complex, so the original interface can no longer meet the requirements. At this time, a new interface can be provided, which can also be controlled by different configuration parameters.

Therefore, from the back-end interface level, a more common and common processing method is to configure the interface to achieve the purpose of switching interaction, or grayscale publishing. The core essence of grayscale publishing is to switch from one data form to another in some way.

Minimize the transformation mode

It is talked about above that the grayscale can be achieved by configuring the parameter interface. In fact, in some smaller projects without access to the distributed configuration center, the above solution may not be a very good way.

For example, the purpose of grayscale is that the interface for obtaining the user list of V1.0 returns the users added this month, while V2.0 requires that the users registered in the last 2 months be returned, and the interface address remains unchanged. The most important thing is to allow appropriate changes on the parameters, that is, to minimize the changes at the front end.

This requirement, at first thought, is very incredible. In a controller class, two identical interface mapping paths must not work. For example, take a look at the following example.

RestControllerpublic class UserController {@ Autowired private UserService userService; @ GetMapping ("/ list") public Object getUserLists1 () {return userService.getUserLists1 ();} @ GetMapping ("/ list") public Object getUserLists2 () {return userService.getUserLists2 ();}}

The current request for the interface, directly reported an error, I think everyone can understand this error, I will not explain too much

Principle of springmvc Interface request

A flow chart about the principle of springmvc interface request is posted below, that is, a complete process when a request finally arrives at a specific controller. I believe that students with experience in SSM development or springboot development should be familiar with this diagram.

From the large classification, it mainly includes the following core processing components:

Dispatcher Servlet, request dispatcher, receives a request to call processor mapper HandlerMapping

HandlerMapping,HandlerAdapter, processor mapper and processor adapter, according to the requested url address, locate to the specific controller specific processing method

View Resolver, the view parser, parses the returned data of the interface and returns the specific View to Dispatcher Servlet

Among the above components, we need to focus on this component called HandlerMapping. In order to achieve the grayscale publishing function mentioned above, we need to study the principle of HandlerMapping.

Introduction to HandlerMapping

HandlerMapping plays an important role in this SpringMVC architecture, acting as the mapping configuration between url and Controller, which consists of three main parts:

HandlerMapping mapping registration

Get the corresponding processor according to url

Interceptor registration

In springmvc, the core class is RequestMappingHandlerMapping, which includes all the implementations related to request mapping processing, such as

Match (HttpServletRequest request, String pattern). Through the match method in it, you can match the request path in request with the rule path.

RegisterHandlerMethod, registered processor

In this class, we notice the following two methods, but there is no implementation logic within the method. Students who have a little knowledge of the spring source code should know that this must be the method reserved by the spring framework for this class to be extended in development, and these two methods are the two core methods used to implement this requirement.

We notice that the return value of both methods is RequestCondition, that is, the object of the request condition. We know from the above that HandlerMapping is initialized in the container, so there must be an opportunity. As long as the client rewrites the internal logic of these two methods of HandlerMapping, we can parse the parameters of handleType to meet the requirements of minimizing the front-end transformation in this article.

A few additions to RequestCondition:

RequestCondition is the conceptual modeling of a request matching condition by Spring MVC.

The implementation class may be for one of the following situations: path matching, header matching, request parameter matching, MIME matching, consumable MIME matching, request method matching, or a combination of matching conditions for all of the above cases

The RequestCondition interface defines the merging of public interface RequestCondition {/ / and another request matching condition. The merge logic is provided by the implementation class T combine (T var1). / / check whether the current request matching condition matches the specified request request. If not, return null. / / if there is a match, a new request matching condition is generated. The new request matching condition is the current request matching condition / / tailoring for the specified request request. / / for example, if the current request matching condition is a path matching condition that contains multiple path matching templates, / / and some of the templates match the specified request request, then the returned new request matching condition will contain only those path templates that match the specified request request. @ Nullable T getMatchingCondition (HttpServletRequest var1); / / compare the two request matching conditions for the specified request object request. / / this method assumes that the two request matching conditions being compared are obtained by calling the / / # getMatchingCondition method on the request object request, so as to ensure that the comparison / / is for the same request object request, so that the comparison is meaningful (ultimately used to determine who is / / the more matching condition). Int compareTo (T var1, HttpServletRequest var2);}

As you can see from the interface source code, the interface RequestCondition is a generic interface. In fact, its generic parameter T is usually a RequestCondition object, which can be related to the two methods that are about to be rewritten in the HandlerMapping above.

Code implementation process 1. Add a custom annotation to mark interface classes and interface methods

Through the above analysis, we know that we can read the meta-information in the interface class or interface method, such as interface path, annotation, method name, etc., through the getCustomTypeCondition method and getCustomMethodCondition method in HandlerMapping.

How can we minimize the transformation of the front end? The main idea is that through the form of parameter control, for example, the front end does not need to change the original interface address, but only needs to pass in different parameters to meet the requirements, so you can add annotations to different methods in the form of custom annotations, and achieve this by encapsulating the annotation parameter as RequestCondition.

Import java.lang.annotation.*; @ Documented@Target ({ElementType.TYPE,ElementType.METHOD}) @ Retention (RetentionPolicy.RUNTIME) public @ interface ApiVersion {/ / specific version number double value ();} 2. Custom HandleMapping

Add a new class, inherit RequestMappingHandlerMapping, rewrite the two methods in it, and encapsulate it into RequestCondition to provide subsequent calls.

Import org.springframework.core.annotation.AnnotationUtils;import org.springframework.web.servlet.mvc.condition.RequestCondition;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.lang.reflect.Method / * support multiple versions of the controller * / public class ApiVersionHandleMapping extends RequestMappingHandlerMapping {/ * container initialization execution * all controller will use this method * @ param handlerType * @ return * / @ Override protected RequestCondition getCustomTypeCondition (Class handlerType) {ApiVersion apiVersion = AnnotationUtils.getAnnotation (handlerType, ApiVersion.class); return new ApiVersionRequestCondition (apiVersion! = null? Execute * @ param method * @ return * / @ Override protected RequestCondition getCustomMethodCondition (Method method) {ApiVersion apiVersion = AnnotationUtils.getAnnotation (method, ApiVersion.class); if (apiVersion = = null) {apiVersion = AnnotationUtils.getAnnotation (method.getDeclaringClass (), ApiVersion.class) during container initialization } return new ApiVersionRequestCondition (apiVersion! = null? ApiVersion.value (): 1. 0);}} 3. Custom encapsulation RequestCondition

Encapsulate the custom RequestCondition logic, which will perform a series of logical operations that match the real execution interface according to the input parameters when the client requests the interface. For example, by default, if no parameters are passed into the request URL, the default V1.0 interface will be returned.

Import org.apache.commons.lang.StringUtils;import org.springframework.web.servlet.mvc.condition.RequestCondition; import javax.servlet.http.HttpServletRequest; public class ApiVersionRequestCondition implements RequestCondition {private double apiVersion= 1.0; private static final String VERSION_NAME = "api-version"; public double getApiVersion () {return apiVersion;} public ApiVersionRequestCondition (double apiVersion) {this.apiVersion=apiVersion;} @ Override public ApiVersionRequestCondition combine (ApiVersionRequestCondition method) {return method } @ Override public int compareTo (ApiVersionRequestCondition other, HttpServletRequest request) {return Double.compare (other.getApiVersion (), this.getApiVersion ());} @ Override public ApiVersionRequestCondition getMatchingCondition (HttpServletRequest request) {double reqVersionDouble = 1.0; String reqVersion = request.getHeader (VERSION_NAME); if (StringUtils.isEmpty (reqVersion)) {reqVersion = request.getParameter (VERSION_NAME) } if (! StringUtils.isEmpty (reqVersion)) {reqVersionDouble = Double.parseDouble (reqVersion);} if (this.getApiVersion () = = reqVersionDouble) {return this;} return null;}} 4, register a custom ApiVersionHandleMappingimport org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping Public class ApiVersionMappingRegister implements WebMvcRegistrations {@ Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping () {return new ApiVersionHandleMapping ();}} import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; @ Configurationpublic class BaseConfiguration {@ Bean public WebMvcRegistrations getWebMvcRegistrations () {return new ApiVersionMappingRegister ();}} 5, API test

Make a simple modification to the interface at the beginning of this article and add custom comments

Import com.congge.configs.ApiVersion;import com.congge.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController; @ RestController@ApiVersion public class UserController {@ Autowired private UserService userService; @ GetMapping ("/ list") @ ApiVersion (1.0) public Object getUserLists1 () {return userService.getUserLists1 () } @ GetMapping ("/ list") @ ApiVersion (2.0) public Object getUserLists2 () {return userService.getUserLists2 ();}}

After starting the project, do the following API test:

1. No parameters are added, no parameters are added by default, and the V1 version of the interface will be requested.

2. Add api-version = 2.0 to the API request, and send the request to the interface corresponding to V2.

Through the above demonstration, we basically achieve a springboot-based interface multi-version control interface grayscale publishing function.

At this point, the study on "how to achieve interface grayscale release by springboot" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report