【问题标题】:How to filter a request that has an invalid parameter in JAX-RS?如何过滤 JAX-RS 中具有无效参数的请求?
【发布时间】:2014-08-13 14:59:02
【问题描述】:

“无效”是指不期望的参数。

例如:

@Path("/")
public interface ExampleInterface {
    @GET
    @Path("/example")
    public Response test(
        @QueryParam("param1") String param1,
        @QueryParam("param2") String param2
    );
}

然后我打电话给".../example?param3=foo"

【问题讨论】:

  • 对于您的处理程序来说,这看起来像是一个无效的 URL。不是吗?
  • 您可以使用 Per Resource Method 过滤器和拦截器...
  • 如果参数不是预期的,可以忽略。
  • 你的问题到底是什么,或者你想达到什么目的?
  • 如果发送了意外参数,我想将用户重定向到“400 Bad Request”页面,而不使用 RESTEasy,仅使用 JAX-RS 规范。 @LutzHorn,我知道它可以忽略,但它是项目必需的。

标签: java filter jax-rs resteasy query-parameters


【解决方案1】:

您可以检查使用ContainerRequestFilter 并将传递的参数与定义的参数进行比较:

@Provider
public class RequestParamFilter implements ContainerRequestFilter {

    @Context
    private ResourceInfo resourceInfo;

    @Context
    private HttpServletRequest servletRequest;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        Set<String> validParams = new HashSet<String>();
        Method method = resourceInfo.getResourceMethod();
        for (Annotation[] annos : method.getParameterAnnotations()) {
            for (Annotation anno : annos) {
                if (anno instanceof QueryParam) {
                    validParams.add(((QueryParam) anno).value());
                }
            }
        }
        for (String param : servletRequest.getParameterMap().keySet()) {
            if (!validParams.contains(param)) {
                requestContext.abortWith(Response.status(Status.BAD_REQUEST).build());
            }
        }
    }

}

不要忘记ServletRequest#getParameterMap 返回一个包含查询字符串参数和在请求正文中传递的参数的映射。所以也许你需要自己解析查询字符串。

注意:这不会加速您的应用程序。

【讨论】:

    【解决方案2】:

    感谢您接受的答案。它非常有帮助,我也使用它。我提供的是修改后的版本,有以下更改:

    • 删除了通过上下文注释进入的 servletRequest。这不是必需的,因为请求是过滤器方法本身的参数。
    • 添加了导入,因为对于同名的不同类(Method、Annotation、ContainerRequestContext、...)可能存在很多问题
    • 还在错误消息中添加了缺失参数的名称

    -

    import java.io.IOException;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.ws.rs.QueryParam;
    import javax.ws.rs.container.ContainerRequestContext;
    import javax.ws.rs.container.ContainerRequestFilter;
    import javax.ws.rs.container.ResourceInfo;
    import javax.ws.rs.core.Context;
    import javax.ws.rs.core.MultivaluedMap;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.Response.Status;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    public class UnexpectedParameterFilter implements ContainerRequestFilter {
    
        @Context
        private ResourceInfo resourceInfo;
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            Set<String> validParams = new HashSet<String>();
            Method method = resourceInfo.getResourceMethod();
            for (Annotation[] annos : method.getParameterAnnotations()) {
                for (Annotation anno : annos) {
                    if (anno instanceof QueryParam) {
                        validParams.add(((QueryParam) anno).value());
                    }
                }
            }
    
            MultivaluedMap<String, String> queryParameters = requestContext.getUriInfo().getQueryParameters();
            for (String param : queryParameters.keySet()) {
                if (!validParams.contains(param)) {
                    requestContext.abortWith(Response.status(Status.BAD_REQUEST).entity("unexpected paramter: "+param).build());
                }
            }
        }
    
    }
    

    【讨论】:

    • requestContext.getUriInfo().getQueryParameters()servletRequest.getParameterMap() 之间有一个区别。后者还将包含已发布表单数据的参数。我同意在这个例子中前者更有意义。谢谢!
    猜你喜欢
    • 2015-04-26
    • 1970-01-01
    • 2023-04-04
    • 2021-06-09
    • 2013-07-06
    • 1970-01-01
    • 2016-01-19
    • 2016-08-14
    • 2012-12-29
    相关资源
    最近更新 更多