最近做项目时,页面传递给后台的特殊字符很烦人,想写一个公共方法来给需要使用的地方调用,但是后来发现,要调用的地方实在太多,万一有什么变动的话,改起来烦死人。后来发现使用过滤器可以完成这个功能。
过滤器中的主要代码如下:
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
chain.doFilter(new HTMLCharacterRequest(req), resp);
}
其中 HTMLCharacterRequest 是继承与 HttpServletRequest包装类的:
public class HTMLCharacterRequest extends HttpServletRequestWrapper {
public HTMLCharacterRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name){
return filter(super.getParameter(name));
}
/**
* 过滤请求参数值
* @param parameter
* @return
*/
private String filter(String parameter) {
if(StringHelper.isNullOrEmpty(parameter)){
return null;
}
return StringEscapeUtils.escapeSql(StringHelper.unescape(parameter));
}
}
StringHelper.unescape()方法内容如下:
public static String unescape(String src) {
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length());
int lastPos = 0, pos = 0;
char ch;
while (lastPos < src.length()) {
pos = src.indexOf("%", lastPos);
if (pos == lastPos) {
if (src.charAt(pos + 1) == 'u') {
ch = (char) Integer.parseInt(
src.substring(pos + 2, pos + 6), 16);
tmp.append(ch);
lastPos = pos + 6;
} else {
ch = (char) Integer.parseInt(
src.substring(pos + 1, pos + 3), 16);
tmp.append(ch);
lastPos = pos + 3;
}
} else {
if (pos == -1) {
tmp.append(src.substring(lastPos));
lastPos = src.length();
} else {
tmp.append(src.substring(lastPos, pos));
lastPos = pos;
}
}
}
return tmp.toString();
}
这样做完之后,前端传递过来的escape("xxx") 就可以在Controller中可以使用request.getParameter("xxx")的形式获取到解码之后并且对数据库操作无影响的字符串了。
截图如下:
可以看到request的真正类型是
HTMLCharacterRequest ,并且 通过 request.getParameter("provinceName") 获取到的值 也是 解码并且对数据库无影响的值。
但是,这个时候就有个问题了,如下:
方法参数列表中 使用 @RequestParam 获取到的参数 却是未解码的。
为什么呢???
后来跟踪Annotation源码发现了如下的一段代码:
(详见:org.springframework.web.bind.annotation.support.HandlerMethodInvoker 的 resolveRequestParam方法)
if (paramValue == null) {
String[] paramValues = webRequest.getParameterValues(paramName);
if (paramValues != null) {
paramValue = (paramValues.length == 1 ? paramValues[0] : paramValues);
}
}
if (paramValue == null) {
if (defaultValue != null) {
paramValue = resolveDefaultValue(defaultValue);
}
else if (required) {
raiseMissingParameterException(paramName, paramType);
}
paramValue = checkValue(paramName, paramValue, paramType);
}
由此发现,在源码中是使用 getParameterValues 方法来获取参数值的,而不是 getParameter方法
所以需要在 HTMLCharacterRequest 中再 @override 一下 getParameterValues 的方法:
@Override
public String[] getParameterValues(String name) {
return filter(super.getParameterValues(name));
}
/**
* 过滤请求参数值
* @param parameters
* @return
*/
private String[] filter(String[] parameters) {
if(parameters.length == 0){
return null;
}
for (int i=0; i<parameters.length; i++) {
parameters[i] = StringEscapeUtils.escapeSql(StringHelper.unescape(parameters[i]));
}
return parameters;
}
这个时候再来看 @RequestParam 注解的参数值 就是 解码之后的了:
- 大小: 12.8 KB
- 大小: 10.3 KB
- 大小: 18.2 KB
- 大小: 20.3 KB
分享到:
相关推荐
- **提高灵活性**:开发者可以在不修改web.xml文件的情况下,通过修改注解参数灵活地调整过滤器的行为。 - **增强可读性**:注解通常会直接写在过滤器类上,这样可以更容易地看出过滤器的作用范围。 #### 四、`@Web...
5. **使用注解配置过滤器**: 在Java EE 6及以上版本,还可以使用`@WebFilter`注解来代替`web.xml`配置: ```java @WebFilter(filterName = "myFilter", urlPatterns = "/*") public class MyFilter implements ...
过滤器的执行顺序可以通过`<filter-mapping>`的`filter-name`和`url-pattern`来控制,也可以使用注解式配置(如Spring的`@WebFilter`)。 总的来说,"java请求参数过滤拦截"是保证Web应用安全的关键措施之一,它...
- 使用注解`@WebFilter`在Java类上直接配置过滤器,更符合现代开发习惯。 3. **过滤器方法** - **init()**:在过滤器实例化后调用,用于初始化过滤器。 - **doFilter()**:核心方法,处理请求和响应。它接收`...
自Java EE 6开始,除了传统的XML配置,还可以使用Servlet 3.0的注解来配置过滤器,如`@WebFilter`,这样可以简化配置过程。 7. **Filter接口的其他方法**: 过滤器接口还提供了其他方法,如`init(FilterConfig ...
在现代的Java Web应用中,可以通过Java配置或者使用Spring Boot的`@WebFilter`注解来定义过滤器。 8. **过滤器和拦截器的区别**:虽然过滤器和拦截器都能实现类似的逻辑,但过滤器是Servlet规范的一部分,而拦截器...
此外,为了提高性能,敏感词过滤逻辑可以进行优化,比如使用布隆过滤器(Bloom Filter)来快速判断一个词是否可能是敏感词,从而减少不必要的精确匹配操作。 总之,通过AOP进行参数预处理的敏感词过滤是一种强大的...
在实际应用中,你需要将这些过滤器配置到`web.xml`或使用Spring Boot的`@WebFilter`注解,以便在应用程序启动时自动注册它们。此外,还可以使用过滤器链,将多个过滤器串联起来,按顺序执行,以满足更复杂的业务需求...
在Java Web开发中,拦截器(Interceptor)和过滤器(Filter)是两种常见...总结来说,拦截器、过滤器和参数读取是Java Web开发中的基础工具,理解它们的工作原理和使用技巧,能帮助我们更好地构建高效、稳定的Web应用。
例如,通过`@WebFilter`注解来声明一个过滤器,并使用`@Override`注解覆盖`doFilter`方法。此外,Spring MVC还提供了`HandlerInterceptor`接口,它也是一种拦截请求的方式,但更偏向于业务逻辑处理。 在实际项目中...
5. **配置过滤器**:在`web.xml`部署描述符或使用Servlet 3.0以上的注解`@WebFilter`,我们可以指定过滤器的URL模式,决定哪些请求需要通过这个过滤器。例如,将过滤器应用于所有`.jsp`页面或特定的Servlet。 6. **...
在Java开发中,JSON对象(JSONObject)常用于数据交换,特别是在前后端交互中。当我们序列化或反序列化Java...通过结合使用自定义注解、序列化器和反序列化器,我们可以实现更为复杂的过滤策略,满足特定的业务需求。
创建过滤器后,需要在web.xml文件中进行配置,或者使用Servlet 3.0的注解来简化配置过程。例如,使用@WebFilter注解可以直接在类上方声明过滤器的映射。 文章还介绍了过滤器在Java Web开发中的典型应用场景,包括:...
在.NET框架下,注解属性(Attribute)是过滤器的一种实现方式。注解属性派生自System.Attribute类,它是特殊的.NET类,用于提供元数据,即附加在代码元素上的信息。这些信息可以被编译器读取,并在运行时被框架或程序...
过滤器的配置通常在`WebSecurityConfig`类中完成,通过`@EnableWebSecurity`注解启用Spring Security。 2. **SQL注入防护**:项目可能使用了Spring Data JPA、JdbcTemplate或MyBatis等持久层技术,这些库提供了防止...
3. 在`web.xml`或使用注解(如`@WebFilter`)配置过滤器,指定URL模式和过滤顺序。 作业报告通常包括以下几个方面: 1. 过滤器设计的目标和应用场景。 2. 过滤器的配置详细说明,包括URL映射和过滤顺序。 3. 实际...
例如,我们可以在一个AOP(面向切面编程)拦截器或者一个过滤器中获取并处理这些信息: ```java public class ApiInterceptor { public void intercept(Method method) { ApiCallLog log = method.getAnnotation...
例如使用 Servlet Filter API 或者使用 Spring 的 HandlerInterceptor机制,但是 SpringBoot 2.x 版本中引入了新的 @WebFilter 注解,提供了更加简洁和灵活的方式来实现过滤器。 @WebFilter 注解是 SpringBoot 框架...
过滤器(Filter)是Java Servlet API的一部分,允许我们在请求到达目标Servlet或JSP之前对其进行拦截和处理。在这个场景下,我们需要创建一个专门的过滤器来解决GET请求的编码问题。 首先,我们需要了解HTTP协议的...
总结来说,Java过滤器提供了一种灵活的方式,可以在请求到达Servlet之前和响应离开Servlet之后对它们进行拦截和修改,从而增强了Web应用程序的功能和安全性。通过合理利用过滤器,开发者可以实现诸如身份验证、权限...