spring boot 与 filter

spring boot 里面用拦截器好像比用过滤器多一些. 在过滤器中, 并不能获取到action的相关信息, 会造成很多的麻烦和功能欠缺.

那, 这里就用过滤器做一个小栗子, 实际使用过程中, 不会这么做的. 

用过滤器做一个不完善的登录权限判断.

一. 过滤器

package org.elvin.springboot.filter;

import org.thymeleaf.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginFilter implements Filter {


    private String passUrl;

    private String loginUrl;

    //region getter / setter
    public String getPassUrl() {
        return passUrl;
    }

    public void setPassUrl(String passUrl) {
        this.passUrl = passUrl;
    }

    public String getLoginUrl() {
        return loginUrl;
    }

    public void setLoginUrl(String loginUrl) {
        this.loginUrl = loginUrl;
    }
    //endregion

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        if(isPassUrl(req)){
            filterChain.doFilter(req, resp);
            return;
        }

        HttpSession session = req.getSession();
        String token = (String)session.getAttribute("token");
        if(StringUtils.isEmpty(token)){
            resp.sendRedirect(req.getContextPath() + loginUrl);
            return ;
        }

        filterChain.doFilter(req, resp);
    }

    /**
     * 判断是否不需要权限
     * @param req
     * @return
     */
    public boolean isPassUrl(HttpServletRequest req){
        String requestURI = req.getRequestURI() + ";";
        String contextPath = req.getContextPath();
        if(!requestURI.startsWith(contextPath)){
            return false;
        }
        requestURI = requestURI.substring(contextPath.length());
        if(0 <= passUrl.indexOf(requestURI)){
            return true;
        }
        return false;
    }
}

在这里栗子里, 应该在过滤器里面加个文件请求过滤. 不过, 好像没有影响到结果, 所以, 懒得处理了, 后面拦截器的时候, 会再实现一遍这个功能.

 

二. 拦截器的java配置文件

package org.elvin.springboot.config;

import org.elvin.springboot.filter.LoginFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;

@Configuration
public class LoginConfig {

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

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

    @Bean(name="loginFilter")
    public Filter loginFilter(){
        LoginFilter filter = new LoginFilter();
        filter.setPassUrl(passUrl);
        filter.setLoginUrl(loginUrl);
        return filter;
    }

    @Bean
    public FilterRegistrationBean registrationBean(){
        FilterRegistrationBean reg = new FilterRegistrationBean();
        reg.setFilter(loginFilter());
        reg.addUrlPatterns("/*");
        reg.setName("loginFilter");
        reg.setOrder(Integer.MAX_VALUE);
        return reg;
    }

}

这里面没有写注释了, 看到方法名, 应该能看明白方法是干啥的.

 

三. yml配置文件

passUrl: /login/index;/login/checkOut;
loginUrl: /login/index

loginUrl 是登录页面地址, passUrl 是不需要登录的页面地址

到这里, 过滤器已经结束了. 接下来, 加入控制器和视图.

 

四. controller / view

package org.elvin.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

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

@Controller
@RequestMapping("login")
public class LoginController {

    @Autowired
    private HttpServletRequest request;

    @GetMapping("index")
    public String index(){
        HttpSession session = request.getSession();
        session.setAttribute("token", "token");

        return "login/index";
    }

    @PostMapping("checkOut")
    @ResponseBody
    public String checkOut(){
        HttpSession session = request.getSession();
        session.setAttribute("token", null);
        return "success";
    }
}

html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>index</title>
    <link rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.css}" />
</head>
<body>
    <div class="container">
        <input type="button" th:value="登出" id="checkout"/>
    </div>


    <script th:src="@{/js/jquery-1.11.3.js}"></script>
    <script th:src="@{/bootstrap/js/bootstrap.js}" ></script>
    <script th:inline="javascript">
        $(function(){
            $(".container").delegate("#checkout", "click", function(){
                $.ajax({
                    url: [[@{/login/checkOut}]],
                    type:'post',
                    data:'',
                    success: function(res){
                        if(res == "success"){
                            alert("登出成功!");
                        }
                    }
                });
            });
        });
    </script>
</body>
</html>

结果展示还真不好弄, 得弄成 动态图片, 额, 个人比较懒, 就算了. 

 

posted @ 2017-12-19 20:52  Sniper_ZL  阅读(1072)  评论(1编辑  收藏  举报