spring boot使用 * 修改请求URL域名 换 IP 访问的方法
作者:OAK社区 发布时间:2022-08-21 20:15:53
Interceptor 介绍
* (Interceptor)同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。
你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置…
在 Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或多个)。
Spring Interceptor是一个非常类似于Servlet Filter 的概念 。
Interceptor 作用
日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等;
权限检查:如登录检测,进入处理器检测是否登录;
性能监控:通过 * 在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如 Apache 也可以自动记录)
通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用 * 实现。
自定义 Interceptor
如果你需要自定义 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 渲染了对应的视图之后执行。此方法主要用来进行资源清理。
接下来结合实际代码进行学习。
案例1 :域名换IP访问
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;
}
}
}
案例2: erverWebExchange通过 * 修改请求url
@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());
}
案例3: 将请求路径中/idea都去掉
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/**");
}
}
案例4: SpringBoot 利用过滤器Filter修改请求url地址
要求:
代码中配置的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;
}
}
案例5. * : WebMvcConfigurerAdapter *
拦截所有请求
@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;
}
}
来源:https://libin9ioak.blog.csdn.net/article/details/126891064
猜你喜欢
- 前言相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Sp
- 很多时候,我们需要使用C#中的WebClient 来收发数据,WebClient 类提供向 URI 标识的任何本地、Intranet 或 I
- 一、算法描述波雷费密码是一种对称式密码,是首种双字母取代的加密法。下面描述算法步骤:1、从1号二维码M05,提取明文信息和密文,M05格式:
- 最近碰到个需求,是希望在Unity有一个按钮,打开后直接跳转淘宝app,打开商品页面。百度了下没有相关的文章,于是我在此分享下。之前开发游戏
- 当你在开发flutter应用的时候,有时会需要调用native的api,往往遇到flutter并没有相应的package, 这时候flutt
- ArrayList中存放引用数据类型ArrayList中存放引用类型时,存放的是一个引用,因此在放入ArrayList之后再进行改动会影响到
- 一、项目结构二、pom.xml<?xml version="1.0" encoding="UTF-8&q
- SpringBoot配置文件中设置server.port不生效我的配置文件为:# application.ymlserver:
- 干java 开发这么多年, 之前一直没留意java 进程还区分守护进程和用户进程。守护进程这个概念最早还是在linux系统中接触的,直到近期
- package com.chase.test;import java.util.ArrayList;import java.util.Has
- NO.1–注释在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内容
- mybatis初始化SqlSessionFactory失败总结原因有几点1.resources中的xml配置文件放错位置或者是放的太深加载不
- 前言在使用maven配置Mybatis generator插件时报以下错误,generator插件一直无法使用,查询资料说和eclipse版
- ArrayList的构造方法(前置知识)可快速过一些基本成员变量:// 默认初始大小private static final int DEF
- 谈到多线程就不得不谈到Synchronized,重要性不言而喻,今天主要谈谈Synchronized的实现原理。Synchronizedsy
- 接收JSON浏览器传来的参数,可以是 key/value 形式的,也可以是一个 JSON 字符串。在 Jsp/Servlet 中,我们接收
- 什么是JavaMemoryModel(JMM)?JMM通过构建一个统一的内存模型来屏蔽掉不同硬件平台和不同操作系统之间的差异,让Java开发
- Java设计模式的模板方法模式定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步
- 前言在看一本关于高性能编程的时候发现 Java8 中关于接口的新特性的介绍,这个特性是真的棒,解决了一个接口中有多个方法,但并不想实现该接口
- 引用Spring官方文档的说法介绍一下@Conditional注解:Spring5.0.15版本@Conditional注解官方文档@Con