您好,登錄后才能下訂單哦!
前言:
Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Spring Boot致力于在蓬勃發展的快速應用開發領域(rapid application development)成為領導者。
一.使用場景:
1.在前后端接口調用的過程中,某些接口數據是需要加密傳輸的 :比如密碼等,前端編碼后后端接口都必須需要解碼,每個接口都解要做一次解碼工作,這是一個很繁瑣的事情
2.如接口調用過程中,每次調用都需要傳送一個token,我們怎樣去對接口進行攔截
二.定義一個Filter或者OncePerRequestFilter
OncePerRequestFilter:(在spring中,filter都默認繼承OncePerRequestFilter)顧名思義,它能夠確保在一次請求中只通過一次filter,而需要重復的執行。大家常識上都認為,一次請求本來就只filter一次,為什么還要由此特別限定呢,往往我們的常識和實際的實現并不真的一樣,經過一番資料的查閱,此方法是為了兼容不同的web container,也就是說并不是所有的container都入我們期望的只過濾一次,servlet版本不同,執行過程也不同,因此,為了兼容各種不同運行環境和版本,默認filter繼承OncePerRequestFilter是一個比較穩妥的選擇。request.parameter中,但是我們都知道request.parameter中的數據只能進行讀操作,不能進行寫操作,怎么解決呢?
這里會引入一個類 javax.servlet.http.HttpServletRequestWrapper,是一個擴展的通用接口,也就是會對request做一次包裝,我們需要繼承并重寫這個方法。
2.1 代碼部分如下
package com.grand.p1upgrade.filter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper{
// 用于存儲請求參數
private Map<String , String[]> params = new HashMap<String, String[]>();
public MyHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
// 把請求參數添加到我們自己的map當中
this.params.putAll(request.getParameterMap());
}
public void setParameters(Map<String, Object> extraParams) {
for (Map.Entry<String, Object> entry : extraParams.entrySet()) {
setParameter(entry.getKey(), entry.getValue());
}
}
/**
* 添加參數到map中
* @param name
* @param value
*/
public void setParameter(String name, Object value) {
if (value != null) {
if (value instanceof String[]) {
params.put(name, (String[]) value);
} else if (value instanceof String) {
params.put(name, new String[]{(String) value});
} else {
params.put(name, new String[]{String.valueOf(value)});
}
}
}
/**
* 重寫getParameter,代表參數從當前類中的map獲取
* @param name
* @return
*/
@Override
public String getParameter(String name) {
String[]values = params.get(name);
if(values == null || values.length == 0) {
return null;
}
return values[0];
}
/**
* 重寫getParameterValues方法,從當前類的 map中取值
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
}
2.2 繼承OncePerRequestFilter覆蓋doFilterInternal對密碼解碼
package com.grand.p1upgrade.filter;
import java.io.IOException;
import java.util.Base64;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* 參數過濾,對所有請求接口的請求進行攔截是否有pwd參數,有則解密,并將參數放入request.parameter中
*
* @author SanLi
* Created by 2689170096@qq.com/SanLi on 2018/1/28
*/
//@Component
public class RequestParameterFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String pwd=request.getParameter("pwd");
if(pwd!=null) {
pwd= new String(Base64.getDecoder().decode(pwd), "UTF-8");
MyHttpServletRequestWrapper wrapper = new MyHttpServletRequestWrapper(request);
wrapper.setParameter("pwd",pwd);
/**
* 1.一般filter都是一個鏈,web.xml 里面配置了幾個就有幾個。一個一個的連在一起
* request -> filter1 -> filter2 ->filter3 -> …. -> request resource.
*
* 2.chain.doFilter將請求轉發給過濾器鏈下一個filter , 如果沒有filter那就是你請求的資源
*/
filterChain.doFilter(wrapper, response);
}
return;
}
}
2.2 繼承Filter對密碼解碼
package com.grand.p1upgrade.filter;
import java.io.IOException;
import java.util.Base64;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import lombok.extern.java.Log;
/**
* 過濾所有的請求,包含靜態資源,如果請求cookie中含有token或請求為靜態資源,則放行請求,否則進入到登陸頁面
*/
@Log
@Component
public class TokenFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
MyHttpServletRequestWrapper wrapper = null;
String token = null;
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String uri = request.getRequestURI();
//參數過濾,對所有請求接口的請求進行攔截是否有pwd參數,有則解密,并將參數放入request.parameter中
String pwd=request.getParameter("pwd");
wrapper = new MyHttpServletRequestWrapper(request);
if(pwd!=null) {
pwd= new String(Base64.getDecoder().decode(pwd), "UTF-8");
wrapper.setParameter("pwd",pwd);
}
if(uri.contains("/login"))||uri.contains("/static")){
//通過,不攔截
chain.doFilter(wrapper,response);
}else{
// 攔截請求,判斷cookie中是否有token,沒有則跳轉到登陸頁,有則放行
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (Cookie cookie : cookies) {
if("token".equals(cookie.getName())){
// 前端傳遞過來的token包含兩部分:key,value
token = cookie.getValue();
}
}
}
// token有值,且包含"_",就通過
if(StringUtils.isNotEmpty(token)&&token.contains("_")){
chain.doFilter(wrapper,response);
}else{
response.setStatus(401); // 需要權限
}
}
}
@Override
public void destroy() {}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。