springboot过滤器中读取自定义配置+过滤器中转发请求

本文介绍了在SpringBoot过滤器中如何读取自定义配置以及在过滤器内部如何转发请求到对应的Controller。文章详细讲解了两种解决方案,包括通过重写过滤器的init方法(未采用)和定义配置信息Bean并通过SpringContextUtils读取配置。此外,还提供了在过滤器中进行请求转发的依赖和代码示例。

springboot过滤器中引入自定义配置+过滤器中转发请求

一、问题

业务要求:过滤器中需要获取请求url并判断url是否是匿名就可以访问的,而匿名可访问的url需要提前定义在配置文件中,这就要求在过滤器中可以读取自定义的配置。

问题点:项目运行过程中,springboot默认加载顺序listener --》filter–》servlet。过滤器filter的优先级要高于servlet 因此 普通的采用@Value读取自定义配置是不行的。

二、在网上搜索两张方式

1、过滤器中重写init方法

ps:(这种方法我没有用,重写init过程中,报init方法在一个上级过滤器被最终定义过了)
在filter中 需要用上下文对象来获取。应用程序启动时,服务器将创建Filter的实例对象
并调用其init方法,完成对象的初始化功能
从而为后续的用户请求作好拦截的准备工作
filter对象只会创建一次,init方法也只会执行一次

2、直接定义好配置信息bean,利用SpringContextUtils在过滤器中直接读取

1、定义读取配置信息JwtProperty 类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class JwtProperty {

    //忽略的过滤路径  在配置文件中写
    @Value("${com.winfuture.ignoreAuthUrls}")
    private  String ignoreAuthUrls;


    public String getIgnoreAuthUrls() {
        return ignoreAuthUrls;
    }


    public void setIgnoreAuthUrls(String ignoreAuthUrls) {
        this.ignoreAuthUrls = ignoreAuthUrls;
    }

    public JwtProperty() {
        this.setIgnoreAuthUrls(ignoreAuthUrls);
    }

}

2、实现ApplicationContextAware的SpringContextUtils

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtils implements ApplicationContextAware {
    /** * 上下文对象实例 */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /** * 获取applicationContext * * @return */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /** * 经过name获取 Bean. * * @param name * @return */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /** * 经过class获取Bean. * * @param clazz * @param <T> * @return */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * * 经过name,以及Clazz返回指定的Bean * * @param name * @param clazz * @param <T>
     * * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

3、在过滤器方法中直接引用定义好的JwtProperty 直接获取配置文件中的配置

# 获取bean
JwtProperty jwtProperty=SpringContextUtils.getBean(JwtProperty.class);
# 获取配置文件中忽略的url字符串
String  ignoreAuthUrls = jwtProperty.getIgnoreAuthUrls();
# 加工字符串成List

至此完成

三、另外记录一下在过滤器中判断并让请求直接转发到对应的controller

依赖

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
            <scope>provided</scope>
  </dependency>

1、过滤器方法上加 @lombok.SneakyThrows //重定向注解
2、转发代码

HttpServletRequest httpServletRequest = (HttpServletRequest) request;
request.getRequestDispatcher("/user/200").forward(request, response);

欧克

### SpringBoot 中通过过滤器修改 HTTP 请求参数 在 Spring Boot 应用程序中,可以通过自定义 `Filter` 来拦截和修改 HTTP 请求参数。由于 HTTP 请求的输入流(`InputStream`)是一次性的资源,在被读取之后无法再次访问,因此需要创建一个新的请求对象来替代原始请求,并将修改后的参数封装到新的请求对象中。 以下是具体实现方式: #### 创建自定义 Wrapper 类 为了能够多次读取请求体或者动态修改参数,可以扩展 `HttpServletRequestWrapper` 并重写其方法以支持参数的修改。 ```java import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.*; public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper { private final Map<String, String[]> modifiedParams; public CustomHttpServletRequestWrapper(HttpServletRequest request, Map<String, String[]> additionalParams) { super(request); // 合并原有参数与新增/修改的参数 modifiedParams = new HashMap<>(this.getParameterMap()); modifiedParams.putAll(additionalParams); } @Override public String getParameter(String name) { String[] values = modifiedParams.get(name); if (values == null || values.length == 0) { return null; } return values[0]; } @Override public Map<String, String[]> getParameterMap() { return Collections.unmodifiableMap(modifiedParams); } @Override public Enumeration<String> getParameterNames() { return Collections.enumeration(modifiedParams.keySet()); } @Override public String[] getParametersValues(String name) { return modifiedParams.get(name); } } ``` 此代码片段展示了如何通过继承 `HttpServletRequestWrapper` 实现对请求参数的修改[^1]。 #### 自定义过滤器 接下来,编写一个过滤器用于拦截请求并对请求参数进行修改。 ```java import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.HashMap; import java.util.Map; @WebFilter(urlPatterns = "/*") public class RequestModifierFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; // 定义要修改的参数 Map<String, String[]> additionalParams = new HashMap<>(); additionalParams.put("newParam", new String[]{"newValue"}); // 使用自定义的 Wrapper 替代原生请求 CustomHttpServletRequestWrapper customRequest = new CustomHttpServletRequestWrapper(httpRequest, additionalParams); // 继续处理链路 filterChain.doFilter(customRequest, servletResponse); } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} } ``` 在此部分中,我们实现了 `doFilter` 方法,其中利用前面提到的 `CustomHttpServletRequestWrapper` 对象替换掉原有的 `HttpServletRequest` 对象,从而允许我们在不破坏后续逻辑的情况下修改请求参数[^2]。 #### 配置过滤器生命周期 如果希望更灵活地控制过滤器的行为,比如仅针对某些 URL 或者特定条件触发,则可以在配置文件或 Java 注解中调整 `@WebFilter` 的属性设置。例如指定 `urlPatterns` 参数限定作用范围,以及通过 `init()` 和 `destroy()` 方法管理资源初始化与释放过程[^2]。 --- ### 注意事项 当尝试从 POST 请求中提取 JSON 数据时需要注意,因为默认情况下这些数据不会自动映射成查询字符串形式的键值对。此时可能还需要额外解析 JSON 文本内容再将其转换为目标格式以便于操作。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值