文章出處

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>

結果展示還真不好弄, 得弄成 動態圖片, 額, 個人比較懶, 就算了. 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()