• springBoot之配置文件的读取以及过滤器和拦截器的使用


    前言

    在之前的学习springBoot中,成功的实现了Restful风格的基本服务。但是想将之前的工程作为一个项目来说,那些是仅仅不够的。可能还需要获取自定义的配置以及添加过滤器和拦截器。至于为什么将这些写在一起,只是因为这些比较简单而且也会经常用到,所以干脆就一起写出来了。

    读取配置文件

    在使用maven项目中,配置文件会放在resources根目录下。
    我们的springBoot是用Maven搭建的,所以springBoot的默认配置文件和自定义的配置文件都放在此目录。
    springBoot的 默认配置文件为 application.properties 或 application.yml,这里我们使用 application.properties

    首先在application.properties中添加我们要读取的数据。
    springBoot支持分层结构。
    例如:

    web:
      pancm:
        title: SpringBoot
        description: test

    注意前面的空格!

    application.properties添加完之后,我们便在代码中进行读取。
    这里我们使用@Value 方式。
    首先在类中添加 @Component@ConfigurationProperties这两个注解。
    第一个注解表示这个类是获取配置文件,第二个注解表示从配置文件中获取的数据转换为对象。因为我们使用了层级结构,获取web.pancm目录下的参数,所以我们再加上prefix = "web.pancm"这个表示获取这之后的数据,就避免了下面在重复书写。
    那么代码如下:

    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略 */
    
    }

    本类中可以直接获取该属性,不过在外部类调用的时候,需要添加@Autowired

    例如:

    @Autowired
    MyProperties myProperties;
    
    
    System.out.println(myProperties.getTitle());
    System.out.println(myProperties.getDescription());
    

    上面的是获取application.properties中的方法。
    如果想自定义配置文件和属性的话,只需再添加一个@PropertySource注解就可,然后添加 value属性,指向文件路径即可。
    例如:

    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;  
        }  
    }

    调用方法同上!

    注: 之前的springBoot版本的@ConfigurationProperties注解可以使用 locations 方法来指定自定义配置文件路径,不过在 springBoot 1.5以上的就已经不支持 location属性,所以这里使用的是PropertySource。

    过滤器

    过滤器是什么?
    简单的来说,过滤器就是过滤的作用,在web开发中过滤一些我们指定的url。
    过滤器主要做什么?
    过滤掉一些不需要的东西,例如一些错误的请求。
    也可以修改请求和相应的内容。

    过滤器的代码实现
    过滤器(filter)有三个方法,其中初始化(init)和摧毁(destroy)方法一般不会用到,主要用到的是doFilter这个方法。
    而至于怎么过滤呢?
    如果过滤通过,则在doFilter执行filterChain.doFilter(request,response);该方法。

    这里我们在过滤器中设置下请求的时间, 符合就通过。否则返回错误信息!
    代码示例:

     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("开始销毁...");
            }
        }

    那么在springBoot中如何使用过滤器呢?
    一般是使用Component和WebFilter 这两个注解,但是这里我们就直接方法调用。
    在该方法中添加Bean注解,springBoot会在启动的时候进行调用。并指定需要过滤的请求。

    代码示例:

        @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;
        }
    

    说明: registration.setOrder() 方法是设置优先级,数值越大,优先级越高。

    拦截器

    拦截器是什么?
    简单的来说,就是一道阀门,拦截不需要的东西。
    拦截器主要做什么?
    对正在运行的流程进行干预。

    拦截器的代码实现。
    拦截器也主要有三个方法,其中preHandle是在请求之前就进行调用,如果该请求需要被拦截,则返回false,否则true; postHandle是在请求之后进行调用,无返回值;afterCompletion是在请求结束的时候进行调用,无返回值。

    这里我们就简单的模拟下拦截非白名单的IP请求。
    代码示例:

    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被调用");
            }
        }

    依旧再启动springBoot的时候启动拦截器,并指定拦截的请求。

    代码示例:

    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);
        }
    }

    结语

    关于springBoot配置文件的获取以及过滤器和拦截器的使用暂时就介绍到这了。如果在某些方面描述的不够清楚或者说的不太正确,希望读者能指出。
    该项目完整的代码我放到github上了,有兴趣的可以看看。
    https://github.com/xuwujing/springBoot

    如果你对生活感觉到了绝望,请不要气馁。因为这样只会让你更加绝望! 所谓的希望往往都是在绝望中萌发的,所以,请不要放弃希望!
     
    https://www.cnblogs.com/xuwujing/p/8485832.html
  • 相关阅读:
    java文件的读写程序代码
    C#多线程总结
    动态调用WebService接口的几种方式
    Net中Attribute特性的高级使用及自定义验证实现
    进程、线程、多线程
    C#设计模式之单例模式
    C# HttpClient 请求转发
    webapi Model Validation 模型验证
    加密解密方法
    手把手教Electron+vue的使用
  • 原文地址:https://www.cnblogs.com/sjqq/p/10093043.html
Copyright © 2020-2023  润新知