zoukankan      html  css  js  c++  java
  • springBoot之配置文件的读取以及过滤器和拦截器的使用

    前言

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

    读取配置文件

    在使用maven项目中,配置文件会放在resources根目录下。
    我们的springBoot是用Maven搭建的,所以springBoot的默认配置文件和自定义的配置文件都放在此目录。
    springBoot的 默认配置文件为 application.propertiesapplication.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

  • 相关阅读:
    第十四周总结
    《走出软件作坊》读后感
    航空公司信息可视化
    周总结
    REDIS实验
    第二阶段个人总结07
    第二阶段个人总结06
    第二阶段个人总结05
    第二阶段个人总结04
    第二阶段个人总结03
  • 原文地址:https://www.cnblogs.com/xuwujing/p/8485832.html
Copyright © 2011-2022 走看看