Article From:https://www.cnblogs.com/raphael5200/p/9968057.html

 

Then the code of the last blog continues to write.

1.Interface Version Control

A system will be updated iteratively and the demand will change constantly after it is put on line. It is possible that the parameters of the interface will change. If the original parameters are modified directly, it may affect the normal operation of the online system. At this time, we need to set different versions, so even if the parameters change, because the old version does not exist.There are changes, so it will not affect the operation of the online system.

Generally, we can put version number on the address, or on the parameters, or in the header, where we put version number on the address, such as: http://api.example.com/v1/test.Among them, V1 represents the version number. See the code for details:

import org.springframework.web.bind.annotation.Mapping;

import java.lang.annotation.*;

/**
 * version control*@author XIHONGLEI
 * @date 2018-11-15
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface ApiVersion {
    int value();
}
import org.springframework.web.servlet.mvc.condition.RequestCondition;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author XIHONGLEI
 * @date 2018-11-15
 */
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
    // The prefix of the version in the path, in the form of / V [1-9]/.
    private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+)/");
    private int apiVersion;

    public ApiVersionCondition(int apiVersion) {
        this.apiVersion = apiVersion;
    }

    @Override
    public ApiVersionCondition combine(ApiVersionCondition other) {
        // With the principle of final definition priority, the method definition covers the definition above the class.
        return new ApiVersionCondition(other.getApiVersion());
    }

    @Override
    public ApiVersionCondition getMatchingCondition(HttpServletRequest request) {
        Matcher m = VERSION_PREFIX_PATTERN.matcher(request.getRequestURI());
        if (m.find()) {
            Integer version = Integer.valueOf(m.group(1));
            if (version >= this.apiVersion) {
                return this;
            }
        }
        return null;
    }

    @Override
    public int compareTo(ApiVersionCondition other, HttpServletRequest request) {
        // Match the latest version number first
        return other.getApiVersion() - this.apiVersion;
    }

    public int getApiVersion() {
        return apiVersion;
    }
}
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;

/**
 * @author XIHONGLEI
 * @date 2018-11-15
 */
public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    @Override
    protected RequestCondition<ApiVersionCondition> getCustomTypeCondition(Class<?> handlerType) {
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
        return createCondition(apiVersion);
    }

    @Override
    protected RequestCondition<ApiVersionCondition> getCustomMethodCondition(Method method) {
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
        return createCondition(apiVersion);
    }

    private RequestCondition<ApiVersionCondition> createCondition(ApiVersion apiVersion) {
        return apiVersion == null ? null : new ApiVersionCondition(apiVersion.value());
    }
}
#Then inject Bean into the WebConfig configuration classimport com.hello.config.CustomRequestMappingHandlerMapping;
import com.hello.filter.ApiInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * Configuration class*@author XIHONGLEI
 * @date 2018-10-31
 */
@SpringBootConfiguration
public class WebConfig extends WebMvcConfigurationSupport {

   

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        // Add the ApiInterceptor interceptor class
        registry.addInterceptor(new ApiInterceptor());
    }

   

    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = new CustomRequestMappingHandlerMapping();
        handlerMapping.setOrder(0);
        handlerMapping.setInterceptors(getInterceptors());
        return handlerMapping;
    }
}
#Finally, define an interface with version controlimport com.hello.WebConfig;
import com.hello.config.ApiVersion;
import com.hello.entity.ContractDetailDto;
import com.hello.service.CheckPositionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController

public class HelloController {

    @Autowired
    private WebConfig webConfig;

    @ApiVersion(1)
    @RequestMapping("{version}/getName")
    public String vGetName() {
        return "Hello World! version 1";
    }
    @ApiVersion(2)
    @RequestMapping("{version}/getName")
    public String getName() {
        return "Hello World! version 2";
    }
}

View the effect:

 

2.template engine

In the traditional Spring MVC architecture, we usually put JSP and HTML pages under the webapps directory, but Spring Book does not have webapps, let alone web. xml, if we want to write the interface.What should we do?

Spring Boot Officially, several template engines are available: FreeMarker, Velocity, Thymeleaf, Groovy, mustache, JSP.

Here, FreeMarker is used as an example to illustrate the use of Spring Boot.

First, FreeMarker dependencies are introduced:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

Under resources, create two directories: static and templates, as shown in the figure:

The static directory is used to store static resources, such as CSS, JS, HTML and so on. The templates directory stores template engine files. We can create a file under templates: index. FTL (freema).The default suffix for rker is.ftl),And add content:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello ${name}!</title>
</head>
<body>
        Hello ${name}!
</body>
</html>

Then when configuring resources in POM, make sure that all resource files include:

<resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

New Contrlller:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {
    @RequestMapping(value = "/index")
    public ModelAndView index() {
        ModelAndView view = new ModelAndView("/index");
        view.addObject("name","Tom");
        return view;
    }
}

See the result:

 

Leave a Reply

Your email address will not be published. Required fields are marked *