处理泽西岛

时间:2018-04-01 13:43:40

标签: java jersey jax-rs

我不断收到表单错误:

java.lang.IllegalStateException: The @FormParam is utilized when the content type of the request entity is not application/x-www-form-urlencoded

所以我试图防范这个错误,如下所示:

@Path("auth")
@Produces(MediaType.APPLICATION_JSON)
public class Auth {

@POST
@Path("login")
@Consumes(MediaType.WILDCARD)
public Response create()
{
    return Response.status(Status.UNSUPPORTED_MEDIA_TYPE).build();
}

@POST
@Path("login")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response create(@Valid @NotNull @FormParam("username") final String username,
        @Valid @NotNull @FormParam("password") final String password)
{

但是,这并不能解决问题。生成的FINE日志消息非常垃圾。

我有两个问题:

  1. 当Content-Type为空时,为什么不调用更通用的方法?
  2. 当它与@Consumes不匹配时,如何防止调用实际方法以避免日志垃圾邮件?
  3. 环境正在运行Grizzly 2.3.28,Jersey 2.25.1,MOXy 2.7.1

1 个答案:

答案 0 :(得分:2)

如果您制作自定义注释以验证内容类型并且只接受MediaType.APPLICATION_FORM_URLENCODED

,我认为您可以使用它

如果ContainerRequestFilter内容类型不存在,您可以使用会读取标题的MediaType.APPLICATION_FORM_URLENCODED并返回400错误请求。

声明注释界面

@NameBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface ContentTypeFilterAnnotation {}

将其实施为ContainerRequestFilter

@Provider
@ContentTypeFilterAnnotation
public class ContentTypeFilter implements ContainerRequestFilter {

  @Override
  public void filter(ContainerRequestContext requestContext) throws IOException {
    MultivaluedMap<String,String> headers = requestContext.getHeaders();
    List<String> contentType = headers.get(HttpHeaders.CONTENT_TYPE);
    // if MediaType.APPLICATION_FORM_URLENCODED is not present in the content type header, return a 400
    if(contentType == null || !contentType.contains(MediaType.APPLICATION_FORM_URLENCODED)) {
      // build your error as you want it
      Response.ResponseBuilder responseBuilder = Response.serverError();
      Response response = responseBuilder.status(Response.Status.BAD_REQUEST).build();
      requestContext.abortWith(response);
    }
  }
}

然后将其应用到您的终端

@POST
@Path("login")
@ContentTypeFilterAnnotation
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response create(@Valid @NotNull @FormParam("username") final String username,
                       @Valid @NotNull @FormParam("password") final String password) {
    ...
}

如果内容类型不是MediaType.APPLICATION_FORM_URLENCODED,这应该可以防止Jersey尝试获取表单参数。