<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
攔截器(Interceptor)同 Filter 過濾器一樣,它倆都是面向切面程式設計——AOP 的具體實現(AOP切面程式設計只是一種程式設計思想而已)。
你可以使用 Interceptor 來執行某些任務,例如在 Controller 處理請求之前編寫紀錄檔,新增或更新設定…
在 Spring中,當請求傳送到 Controller 時,在被Controller處理之前,它必須經過 Interceptors(0或多個)。
Spring Interceptor是一個非常類似於Servlet Filter 的概念 。
紀錄檔記錄:記錄請求資訊的紀錄檔,以便進行資訊監控、資訊統計、計算 PV(Page View)等;
許可權檢查:如登入檢測,進入處理器檢測是否登入;
效能監控:通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間。(反向代理,如 Apache 也可以自動記錄)
通用行為:讀取 Cookie 得到使用者資訊並將使用者物件放入請求,從而方便後續流程使用,還有如提取 Locale、Theme 資訊等,只要是多個處理器都需要的即可使用攔截器實現。
如果你需要自定義 Interceptor 的話必須實現 org.springframework.web.servlet.HandlerInterceptor介面或繼承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter類,並且需要重寫下面下面 3 個方法:
preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) 方法在請求處理之前被呼叫。該方法在 Interceptor 類中最先執行,用來進行一些前置初始化操作或是對當前請求做預處理,也可以進行一些判斷來決定請求是否要繼續進行下去。該方法的返回至是 Boolean 型別,當它返回 false 時,表示請求結束,後續的 Interceptor 和 Controller 都不會再執行;當它返回為 true 時會繼續呼叫下一個 Interceptor 的 preHandle 方法,如果已經是最後一個 Interceptor 的時候就會呼叫當前請求的 Controller 方法。
postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 方法在當前請求處理完成之後,也就是 Controller 方法呼叫之後執行,但是它會在 DispatcherServlet 進行檢視返回渲染之前被呼叫,所以我們可以在這個方法中對 Controller 處理之後的 ModelAndView 物件進行操作。
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法需要在當前對應的 Interceptor 類的 postHandler 方法返回值為 true 時才會執行。顧名思義,該方法將在整個請求結束之後,也就是在 DispatcherServlet 渲染了對應的檢視之後執行。此方法主要用來進行資源清理。
接下來結合實際程式碼進行學習。
package com.config; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.support.HttpRequestWrapper; import org.springframework.stereotype.Component; import org.springframework.web.util.UriComponentsBuilder; import java.io.IOException; import java.net.URI; @Component public class Interceptor implements ClientHttpRequestInterceptor { /** * Intercept the given request, and return a response. The given {@link ClientHttpRequestExecution} allows * the interceptor to pass on the request and response to the next entity in the chain. * * <p>A typical implementation of this method would follow the following pattern: * <ol> * <li>Examine the {@linkplain HttpRequest request} and body</li> * <li>Optionally {@linkplain HttpRequestWrapper wrap} the request to filter HTTP attributes.</li> * <li>Optionally modify the body of the request.</li> * <li><strong>Either</strong> * <ul> * <li>execute the request using {@link ClientHttpRequestExecution#execute(HttpRequest, byte[])},</li> * <strong>or</strong> * <li>do not execute the request to block the execution altogether.</li> * </ul> * <li>Optionally wrap the response to filter HTTP attributes.</li> * </ol> * * @param request the request, containing method, URI, and headers * @param body the body of the request * @param execution the request execution * @return the response * @throws IOException in case of I/O errors */ @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { String str = request.getURI().toString(); String str1 = str.replace("https://baidu.com", "http://39.156.66.10:8080"); URI newUri = UriComponentsBuilder.fromUri(URI.create(str)).build().toUri(); return execution.execute(new UriModifyHttpRequestWrapper(request, newUri), body); } private static class UriModifyHttpRequestWrapper extends HttpRequestWrapper { private final URI uri; public UriModifyHttpRequestWrapper(HttpRequest request, URI uri) { super(request); this.uri = uri; } @Override public URI getURI() { return uri; } } }
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest str = exchange.getRequest(); //新url String newPath ="/system/loanOrg/list"; ServerHttpRequest newRequest = str.mutate().path(newPath).build(); exchange.getAttributes().put("path", newRequest.getURI()); return chain.filter(exchange.mutate() .request(newRequest).build()); }
1.定義攔截器
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; @Component public class GlobalInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpServletResponseWrapper httpResponse = new HttpServletResponseWrapper((HttpServletResponse) response); System.out.println(request.getRequestURI()); String path=request.getRequestURI(); if(path.indexOf("/idea")>-1){ path = path.replaceAll("/idea",""); request.getRequestDispatcher(path).forward(request,response); } return true; } }
2.定義WebMvcConfig
import com.GlobalInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired GlobalInterceptor globalInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(globalInterceptor).addPathPatterns("/idea/**"); } }
要求:
程式碼中設定的url路徑為http://127.0.0.1/api/asso
現在要求http://127.0.0.1/asso 也可以同樣存取同一個conroller下面的method,並且要求引數全部跟隨
程式碼:
package com.framework.filter; import java.io.IOException; 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.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; /** * 修改請求路由,當進入url為/a/b時,將其url修改為/api/a/b * **/ public class UrlFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest)request; HttpServletResponseWrapper httpResponse = new HttpServletResponseWrapper((HttpServletResponse) response); System.out.println(httpRequest.getRequestURI()); String path=httpRequest.getRequestURI(); if(path.indexOf("/api/")<0){ path="/api"+path; System.out.println(path); httpRequest.getRequestDispatcher(path).forward(request,response); } else { chain.doFilter(request,response); } return; } }
這個類必須繼承Filter類,這個是Servlet的規範。有了過濾器類以後,以前的web專案可以在web.xml中進行設定,但是spring boot專案並沒有web.xml這個檔案,那怎麼設定?在Spring boot中,我們需要FilterRegistrationBean來完成設定。
其實現過程如下:
package com.shitou.huishi.framework.filter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by qhong on 2018/5/16 15:28 **/ @Configuration public class FilterConfig { @Bean public FilterRegistrationBean registFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new UrlFilter()); registration.addUrlPatterns("/*"); registration.setName("UrlFilter"); registration.setOrder(1); return registration; } }
攔截所有請求
@Configuration public class CustMvcConfigurerAdapter extends WebMvcConfigurerAdapter { @Autowired private CustInterceptor custInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(custInterceptor).addPathPatterns("/**"); } }
排除指定路徑 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(custInterceptor).addPathPatterns("/**").excludePathPatterns("/select/**"); }
攔截指定路徑
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(custInterceptor).addPathPatterns("/user/**"); }
CustInterceptor具體攔截類
@Component public class CustInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean needLogin = needLogin(request); if (!needLogin) { return true; } boolean isLogin = checkLogin(request, response); return isLogin; } }
到此這篇關於spring boot使用攔截器修改請求URL域名 換 IP 存取的文章就介紹到這了,更多相關spring boot攔截器修改請求URL域名內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45