java - 在 Spring REST 服务中优雅地处理无效文件上传

标签 java spring rest jersey multipartform-data

我在尝试验证对 REST 端点的请求以上传文件时遇到了障碍。只要请求正确,上传就可以正常工作,现在我想检查必填字段是否存在以及它们包含的数据是否是我所期望的。

我正在使用 Spring Boot 1.2.5 和 jersey-media-multipart 2.1.4。

这是服务:

@Service
@Path("/attachments")
public class AttachmentsController {

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response upload(@FormDataParam("attachment") InputStream attachmentInputStream,
                           @FormDataParam("attachment") FormDataContentDisposition attachmentFileDetail) {

        if (null == attachmentInputStream
                || null == attachmentFileDetail
                || null == attachmentFileDetail.getFileName()) {
            return Response.status(Response.Status.BAD_REQUEST).build();
        }

        // receiving, storing file, returning 201 Created responses etc.
    }

}

现在,当我测试不同的场景时:

  1. 使用 multipart/form-data 调用端点(在 attachment 字段中包含文件)可以正常工作。
  2. 在没有 multipart/form-data 的情况下调用,attachment 字段包含一些文本或不包含文本,正确输入 if() 检查对于 null 值,但 HTTP 响应变为 404 Not Found,而不是我编码的 400 Bad Request
  3. 不带任何字段的调用(空请求),无论是否为 multipart/form-data,都会触发下面粘贴的 NullPointerException,并返回 404未找到响应。

这是NullPointerException:

Servlet.service() for servlet [jerseyServlet] in context with path [] threw exception [java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider$FormDataParamValueFactory.provide(FormDataParamValueFactoryProvider.java:205)
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
    ...

任何想法如何:

  1. 在情况 (2) 中返回正确的响应 400,并且
  2. 优雅地处理情况 (3),避免异常并返回代码 400?

最佳答案

最终我们找到了场景 2 的解决方案和场景 3 的解决方法。

场景 2

我们收到的 404 Not Found 响应是由于 Jersey 尝试显示错误页面,而该页面在服务中不存在。通过提供以下配置,可以关闭该默认行为,以便简单地返回所需的错误代码和编码响应:

@Component
public class WebServiceConfig extends ResourceConfig {

    public WebServiceConfig() {
        property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true");
    }
}

场景 3

我们通过为 POST 请求添加第二个服务方法(下面名为 uploadBodyMissing)来解决这个问题,不需要任何参数。因此,当传入无参数 POST 时,将调用此函数并返回 400 Bad Request 响应:

@Service
@Path("/attachments")
public class AttachmentsController {

    @POST
    @Consumes(MediaType.TEXT_PLAIN)
    public Response uploadBodyMissing() {
        return Response.status(Response.Status.BAD_REQUEST).build();
    }

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response upload(@FormDataParam("attachment") InputStream attachmentInputStream,
                           @FormDataParam("attachment") FormDataContentDisposition attachmentFileDetail) {

        if (null == attachmentInputStream
                || null == attachmentFileDetail
                || null == attachmentFileDetail.getFileName()) {
            return Response.status(Response.Status.BAD_REQUEST).build();
        }

        // receiving, storing file, returning 201 Created responses etc.
    }

}

关于java - 在 Spring REST 服务中优雅地处理无效文件上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31850060/

相关文章:

java - 如何将二进制与枚举一起使用?

java安装tomcat作为服务

java - 使用 Jython 在 Java 和 Python 之间进行通信

java - Spring @Component 类必须是公开的吗?

java - 使用 Java restful HTTP 连接到 OrientDB 服务器

java - 拉力赛:Java Rest Api:返回结果的限制?

java - 为什么 false && (false)?false :true return true

java - 如何在Spring + tomcat 7 + MySQL中使用数据源配置p6spy

spring - 两个EntityManagerFactories,TransactionRequiredException:没有事务在进行中

Ajax 身份验证不让浏览器弹出登录对话框