Reading of configuration files of springBoot and use of filters and interceptors

foreword

In the previous study of springBoot , the basic service of Restful style was successfully implemented. But to think of the previous project as a project, those are just not enough. It may also be necessary to obtain custom configuration and add filters and interceptors. As for why these are written together, just because these are relatively simple and often used, so they are simply written together.

read configuration file

In a maven project, the configuration file will be placed in the resources root directory.
Our springBoot is built with Maven, so the default configuration files and custom configuration files of springBoot are placed in this directory.
The default configuration file of springBoot is application.properties or application.yml , here we use application.properties .

First add the data we want to read in application.properties .
springBoot supports a hierarchical structure.
E.g:

web:
  pancm:
    title: SpringBoot
    description: test

Note the leading spaces!

After application.properties is added, we read it in the code.
Here we use the @Value method.
First add the @Component and @ConfigurationProperties annotations to the class.
The first annotation indicates that this class is to obtain the configuration file, and the second annotation indicates that the data obtained from the configuration file is converted into an object. Because we use the hierarchical structure to obtain the parameters in the web.pancm directory, we add prefix = "web.pancm" to indicate that the data after this is obtained, which avoids repeated writing below.
Then the code is as follows:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * 
* Title: MyProperties
* Description:
* 从application.properties 获取 配置
* Version:1.0.0  
* @author pancm
* @date 2018年1月11日
 */
@Component
@ConfigurationProperties(prefix = "web.pancm")  
public class MyProperties {
    /**
     * 获取个人标题
     * 
     */
    @Value("${title}")
    private String title;

    /**
     * 获取个人描述
     */
    @Value("${description}")
    private String description;

    /** get和set略 */

}

This property can be obtained directly in this class, but when the external class is called, @Autowired needs to be added .

E.g:

@Autowired
MyProperties myProperties;


System.out.println(myProperties.getTitle());
System.out.println(myProperties.getDescription());

The above is to get the method in application.properties .
If you want to customize the configuration file and properties, just add another @PropertySource annotation, and then add the value attribute to point to the file path.
E.g:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
 * 
* Title: MyConfig
* Description:
* 自定义配置文件 
* Version:1.0.0  
* @author pancm
* @date 2018年1月20日
 */
@Component 
@ConfigurationProperties(prefix = "myconfig") 
@PropertySource(value = "classpath:myconfig.proferties")
public class MyConfig {  

    @Value("${test}") 
    private String test;  

    public String getTest() {  
        return test;  
    }  

    public void setTest(String test) {  
        this.test = test;  
    }  
}

The calling method is the same as above!

Note: The @ConfigurationProperties annotation of the previous springBoot version can use the locations method to specify the custom configuration file path, but the location attribute is no longer supported in springBoot 1.5 and above, so the PropertySource is used here.

filter

What is a filter?
Simply put, a filter is the function of filtering, filtering some of the URLs we specify in web development.
What does the filter mainly do?
Filter out some unwanted things, such as some bad requests.
The request and corresponding content can also be modified.

The code realization of the
filter There are three methods for the filter, among which the initialization (init) and destroy (destroy) methods are generally not used, and the doFilter method is mainly used.
And how to filter it? If the filter is passed, execute this method
in doFilter .filterChain.doFilter(request,response);

Here we set the time of the request in the filter, and it will pass if it matches. Otherwise return an error message!
Code example:

 class MyFilter implements Filter {
        @Override
        public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
                throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) srequest;
            //执行过滤操作...
            System.out.println("请求的url :"+request.getRequestURI());
            // 获取系统时间
            Calendar ca = Calendar.getInstance();
            int hour = ca.get(Calendar.HOUR_OF_DAY);
            // 设置限制运行时间 
            if (0<hour && hour < 18) {
                  HttpServletResponse response = (HttpServletResponse) sresponse;
                  response.setCharacterEncoding("UTF-8");
                  response.setContentType("application/json; charset=utf-8");
                  // 消息
                  Map<String, Object> messageMap = new HashMap<>();
                  messageMap.put("status", "1");
                  messageMap.put("message", "此接口可以请求时间为:18-24点");
                  ObjectMapper objectMapper=new ObjectMapper();
                  String writeValueAsString = objectMapper.writeValueAsString(messageMap);
                  response.getWriter().write(writeValueAsString);
                return;
            }

            filterChain.doFilter(srequest, sresponse);
        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("参数初始化:"+filterConfig);
        }

        @Override
        public void destroy() {
            System.out.println("开始销毁...");
        }
    }

So how to use filters in springBoot?
Generally, the two annotations Component and WebFilter are used, but here we just call the method directly.
Add a Bean annotation to this method, and springBoot will call it at startup. And specify the request that needs to be filtered.

Code sample:

    @Bean
    public FilterRegistrationBean testFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        //过滤掉 /getUser 和/hello 的请求
        registration.addUrlPatterns("/getUser","/hello");
        //过滤掉所有请求
//      registration.addUrlPatterns("/*");
        registration.setName("MyFilter");
        registration.setOrder(1);
        return registration;
    }

Description: The registration.setOrder() method is to set the priority. The larger the value, the higher the priority.

interceptor

What is an interceptor?
Simply put, it is a valve that intercepts unwanted things.
What does the interceptor mainly do?
Intervene in a running process.

The code implementation of the interceptor.
The interceptor also has three main methods, among which preHandle is called before the request, if the request needs to be intercepted, it returns false, otherwise true; postHandle is called after the request, no return value; afterCompletion is at the end of the request When the call is made, there is no return value.

Here we simply simulate and intercept non-whitelisted IP requests.
Code example:

class MyInterceptor implements HandlerInterceptor {

        @Autowired  
        private IpConfig ipconfig; 

        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
            String ip = getIpAddr(request);
            // 获取可以访问系统的白名单
            String ipStr = ipconfig.getIpWhiteList();
            String[] ipArr = ipStr.split("\\|");
            List<String> ipList = Arrays.asList(ipArr);

            if (ipList.contains(ip)) {
                 System.out.println("该IP: " + ip+"通过!");
                 return true;
            } else {
                System.out.println("该IP: " + ip+"不通过!");
                  response.setCharacterEncoding("UTF-8");
                  response.setContentType("application/json; charset=utf-8");
                  // 消息
                  Map<String, Object> messageMap = new HashMap<>();
                  messageMap.put("status", "1");
                  messageMap.put("message", "您好,ip为" + ip + ",暂时没有访问权限,请联系管理员开通访问权限。");
                  ObjectMapper objectMapper=new ObjectMapper();
                  String writeValueAsString = objectMapper.writeValueAsString(messageMap);
                  response.getWriter().write(writeValueAsString);
                return false;
            }
        }

        public  String getIpAddr(HttpServletRequest request) {
            String ip = request.getHeader("X-Forwarded-For");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            return ip;
        }

        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle被调用");
        }

        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
            System.out.println("afterCompletion被调用");
        }
    }

Still start the interceptor when springBoot is started again, and specify the intercepted request.

Code sample:

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pancm.springboot_config.config.IpConfig;


@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {

    @Bean   
    public HandlerInterceptor getMyInterceptor(){
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 用于添加拦截规则, 这里假设拦截 /url 后面的全部链接
        // excludePathPatterns 用户排除拦截
        registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

Epilogue

The acquisition of springBoot configuration files and the use of filters and interceptors are briefly introduced here. If the description is not clear enough or is not correct in some aspects, I hope the reader will point out.
I put the complete code of this project on github, you can take a look if you are interested.
https://github.com/xuwujing/springBoot

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325477956&siteId=291194637