字符编码拦截器/过滤器无效的原因

本文探讨了在使用拦截器或过滤器设置字符集为UTF-8的情况下,表单提交仍然出现乱码的原因及解决方案。指出这些工具仅对POST请求有效,并建议使用POST方式提交数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时候配置了拦截器或者过滤器,来将字符设置为UTF-8,但是有时候我们表单提交,发现提交到数据库的时候还是乱码,这是为毛?

<wbr></wbr>

拦截器或者过滤器对表单只是对表单的post方式有效!

<wbr></wbr>

如果表单是get方式的话,需要在tomcat里面加东西才能起作用。

<wbr></wbr>

所以尽量用post方式吧。

<think>我们被要求回答关于Java中常用的过滤器拦截器示例的问题。根据用户提供的引用内容,我们已经知道过滤器拦截器的区别以及一些基本概念。现在,我们需要列举一些常用的过滤器拦截器,并给出示例。 首先,回顾一下引用中的关键点: - 过滤器(Filter)是基于函数回调的,而拦截器(Interceptor)是基于Java反射机制的。 - 过滤器在Servlet容器级别工作,而拦截器在Spring容器中工作,因此拦截器可以获取Spring容器中的bean。 - 过滤器主要用于对请求进行预处理,如编码转换、安全校验等;拦截器则更灵活,可以在方法执行前后进行拦截,处理更细粒度的业务逻辑。 下面,我们将分别列举常用的过滤器拦截器示例。 ### 一、常用过滤器示例 1. **字符编码过滤器** - 作用:解决请求和响应的乱码问题。 - 示例:使用Spring提供的`CharacterEncodingFilter`。 2. **登录认证过滤器** - 作用:检查用户是否登录,未登录则跳转到登录页面。 - 示例:自定义过滤器。 3. **敏感词过滤过滤器** - 作用:过滤请求参数中的敏感词。 - 示例:自定义过滤器。 4. **跨域资源共享(CORS)过滤器** - 作用:处理跨域请求。 - 示例:使用Spring的`CorsFilter`。 下面是一个自定义登录过滤器的示例代码: ```java // 自定义登录过滤器 public class LoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 检查是否登录,这里假设session中有"user"属性表示已登录 if (httpRequest.getSession().getAttribute("user") == null) { // 未登录,重定向到登录页面 httpResponse.sendRedirect(httpRequest.getContextPath() + "/login"); return; } // 已登录,继续执行 chain.doFilter(request, response); } @Override public void destroy() { // 销毁 } } ``` 在web.xml中配置: ```xml <filter> <filter-name>loginFilter</filter-name> <filter-class>com.example.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` ### 二、常用拦截器示例 在Spring MVC中,拦截器需要实现`HandlerInterceptor`接口,并重写三个方法:`preHandle`、`postHandle`和`afterCompletion`。 1. **日志记录拦截器** - 作用:记录请求的日志信息,如请求URL、IP、执行时间等。 2. **权限验证拦截器** - 作用:验证用户是否有权限访问某个资源。 3. **性能监控拦截器** - 作用:监控方法执行时间。 4. **异常处理拦截器** - 作用:统一处理异常。 下面是一个日志记录拦截器的示例: ```java public class LogInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); logger.info("Request URL: {}", request.getRequestURL()); return true; // 继续执行 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在处理方法之后,渲染视图之前执行 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { long startTime = (Long) request.getAttribute("startTime"); long endTime = System.currentTimeMillis(); long executeTime = endTime - startTime; logger.info("Request [{}] executed in {} ms", request.getRequestURL(), executeTime); } } ``` 在Spring配置中注册拦截器(使用Java配置): ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/static/**"); // 排除静态资源 } } ``` ### 三、过滤器拦截器的选择建议 - 如果功能与Servlet容器相关(如请求编码、安全过滤等),使用过滤器。 - 如果功能与Spring容器相关(如需要调用Spring的bean,或者需要与控制器方法交互),使用拦截器。 - 对于细粒度的业务逻辑处理(如权限验证、日志记录),通常使用拦截器更灵活。 ### 总结 过滤器拦截器Java Web开发中扮演着重要角色,它们分别适用于不同的场景。通过上述示例,我们可以看到如何实现常见的过滤器拦截器,并在项目中应用它们。 §§相关问题§§ 1. 如何配置过滤器使其在拦截器之前执行? 2. 在拦截器中如何获取Spring容器中的Bean? 3. 过滤器拦截器的执行顺序是怎样的? 4. 如何实现一个全局异常处理的拦截器?</think>### Java 常用过滤器拦截器详解 在 Java Web 开发中,过滤器拦截器是两种重要的请求处理机制,以下是常用类型及示例: --- #### 一、常用过滤器 (Filter) 基于函数回调,作用于 Servlet 容器层面。 1. **字符编码过滤器** 解决请求/响应乱码问题: ```java public class CharsetFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("UTF-8"); res.setCharacterEncoding("UTF-8"); chain.doFilter(req, res); // 继续执行后续过滤器 } } ``` 2. **认证过滤器** 实现登录校验: ```java public class AuthFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; if (request.getSession().getAttribute("user") == null) { ((HttpServletResponse) res).sendRedirect("/login"); } else { chain.doFilter(req, res); } } } ``` 3. **XSS 防护过滤器** 过滤危险脚本: ```java public class XssFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { chain.doFilter(new XssRequestWrapper((HttpServletRequest) req), res); } } // 包装类实现参数清洗 class XssRequestWrapper extends HttpServletRequestWrapper { public XssRequestWrapper(HttpServletRequest request) { super(request); } @Override public String getParameter(String name) { return cleanXSS(super.getParameter(name)); } private String cleanXSS(String value) { return value.replaceAll("<", "<").replaceAll(">", ">"); } } ``` --- #### 二、常用拦截器 (Interceptor) 基于反射机制,作用于 Spring 容器层面。 1. **日志拦截器** 记录请求耗时: ```java public class LogInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { request.setAttribute("startTime", System.currentTimeMillis()); return true; // 继续执行后续拦截器 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { long duration = System.currentTimeMillis() - (long) request.getAttribute("startTime"); System.out.println("请求 " + request.getRequestURI() + " 耗时: " + duration + "ms"); } } ``` 2. **权限拦截器** 校验接口访问权限: ```java public class AuthInterceptor implements HandlerInterceptor { @Autowired private UserService userService; // 可注入Spring Bean @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (!userService.validateToken(token)) { throw new UnauthorizedException("无效凭证"); } return true; } } ``` 3. **限流拦截器** 控制接口访问频率: ```java public class RateLimitInterceptor implements HandlerInterceptor { private final Map<String, AtomicInteger> counters = new ConcurrentHashMap<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String ip = request.getRemoteAddr(); AtomicInteger count = counters.computeIfAbsent(ip, k -> new AtomicInteger(0)); if (count.incrementAndGet() > 100) { // 每秒限流100次 throw new RateLimitException("访问过于频繁"); } return true; } } ``` --- #### 三、配置方式对比 | **组件** | **配置方式** | **示例** | |----------|---------------------------------------|--------------------------------------------------------------------------| | 过滤器 | web.xml 或 `@WebFilter` 注解 | `<filter><filter-name>charsetFilter</filter-name><filter-class>...` | | 拦截器 | Spring MVC 配置类 | ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/static/**"); } }``` | --- #### 四、核心区别总结 | **特性** | 过滤器 (Filter) | 拦截器 (Interceptor) | |------------------|-------------------------------------|----------------------------------------| | **作用层面** | Servlet 容器 | Spring 容器 | | **依赖注入** | 不支持 Spring Bean 注入[^4] | 支持 Spring Bean 注入[^4] | | **执行顺序** | 最先执行 (FilterChain 开头) | 在 DispatcherServlet 之后执行 | | **实现原理** | 基于函数回调[^3] | 基于 Java 反射机制[^3] | | **URL 忽略配置** | 需在 doFilter 中手动实现 | 支持 `excludePathPatterns()` 方法[^4] | | **适用场景** | 全局编码转换、基础安全过滤 | 业务权限校验、日志记录、接口限流 | > **最佳实践建议**: > - 基础请求处理(如编码/安全)使用过滤器 > - 业务相关处理(如权限/日志)使用拦截器 > - 需要 Spring 容器管理的功能必须用拦截器[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值