构造REST API的MulipartFormDataInput请求?

时间:2017-09-03 15:59:45

标签: spring rest http multipartform-data resteasy

我有一个带有以下签名的REST API:

public class Activity3 extends AppCompatActivity {

    private String idEmpresa = null;
    private TextView resultado;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_3);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        /*  Recebe id de outra tela*/
        idEmpresa = getIntent().getExtras().getString("id_empresa");

        resultado = (TextView) findViewById(R.id.tvAct3);
        resultado.setText(idEmpresa);


    }

    @Override
    public void finish()
    {
        Intent data = new Intent();
        data.putExtra("id_empresa", "12345");
        setResult(Activity.RESULT_OK, data);
        super.finish();
    }

}

在我的API中我将输入的数据提取为:

@POST
@Path("/bulkControlsMapping")
@Consumes({ MediaType.MULTIPART_FORM_DATA })
Response saveControlsMapping(@NonNull MultipartFormDataInput input);

我从Spring MVC Web服务调用此REST API,我正在构建我的请求:

Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
// For text
InputPart inputPart = uploadForm.get(TEXT_KEY).get(0);

// For file
InputPart inputPart = uploadForm.get(CONTROLS_FILE_KEY).get(0);

但是由于部件中没有找到Content-Disposition标头,我在这里得到400个错误的Request Exception。构建此请求的正确方法是什么?

Client client = ClientBuilder.newClient().register(MultipartWriter.class);
String endPoint = "https://localhost:8080/";
WebTarget webTarget = client.target(endPoint).path("bulkControlsMapping");


MultipartFormDataOutput multipartFormDataOutput = new MultipartFormDataOutput();
multipartFormDataOutput.addFormData(CONTROLS_FILE_KEY,
                file, MediaType.APPLICATION_OCTET_STREAM_TYPE);
multipartFormDataOutput.addFormData(TEXT_KEY, countryCode, MediaType.TEXT_PLAIN_TYPE);


Response response = webTarget.request()
                .post(Entity.entity(multipartFormDataOutput, MediaType.MULTIPART_FORM_DATA));

当我使用Postman Client测试我的API时,我可以看到正确的头结构应该是这样的,但我无法手动构建它:

     [java] 03 Sep 2017 21:16:56,300 [WARN]  (http-bio-0.0.0.0-8080-exec-12) org.jboss.resteasy.core.ExceptionHandler: Failed executing POST /bulkControlsMapping
     [java] org.jboss.resteasy.spi.ReaderException: java.lang.RuntimeException: Could find no Content-Disposition header within part
     [java]     at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:183) ~[resteasy-jaxrs-3.0.10.Final.jar:?]
     [java]     at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:89) ~[resteasy-jaxrs-3.0.10.Final.jar:?]
     [java]     at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:112) ~[resteasy-jaxrs-3.0.10.Final.jar:?]
     [java]     at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296) ~[resteasy-jaxrs-3.0.10.Final.jar:?]
     [java]     at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250) ~[resteasy-jaxrs-3.0.10.Final.jar:?]

更新:

我使用MultiPartFeature

让它工作
POST /bulkControlsMapping HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache
Postman-Token: 0af37ee0-9623-43b6-f5f3-bd2c01bdd84c
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="bulkMappingFile"; filename="Beta-Test-2.csv"
Content-Type: text/csv


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="countryCode"

MX
------WebKitFormBoundary7MA4YWxkTrZu0gW--

使用FormDataMultiPart和FormDataContentDisposition生成请求的不同方法。

Client client = ClientBuilder.newClient().register(MultiPartFeature.class, JacksonFeature.class);

我的API使用MediaType.MULTIPART_FORM_DATA并生成MediaType.APPLICATION_JSON。现在当我单独使用MultiPartFeature时,我能够发送请求但无法解析响应。我正在

    FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
    FormDataContentDisposition.FormDataContentDispositionBuilder builder = FormDataContentDisposition
            .name("controlsBulkMappingFile");
    log.error("FILENAME: " + file.getName());
    builder.fileName(file.getName());
    FormDataContentDisposition formDataContentDisposition = builder.build();

    FileInputStream fileInputStream = null;
    try {

        fileInputStream = new FileInputStream(file);
        formDataMultiPart.bodyPart(
                new FormDataBodyPart((file.getName()), fileInputStream,
                        MediaType.APPLICATION_OCTET_STREAM_TYPE)
                        .contentDisposition(formDataContentDisposition));
    } catch (FileNotFoundException ex) {
        System.out.println("&&&&&&: " + ex.getLocalizedMessage());
    }


    // COUNTRY CODE
    FormDataContentDisposition.FormDataContentDispositionBuilder builder2 = FormDataContentDisposition
            .name("countryCode");
    FormDataContentDisposition formDataContentDisposition2 = builder2.build();
    formDataMultiPart.bodyPart(new FormDataBodyPart("countryCode", countryCode,
            MediaType.TEXT_PLAIN_TYPE)).contentDisposition(formDataContentDisposition2);

    log.error("MULTIPART: " + formDataMultiPart.getBodyParts().toString());

    Entity<FormDataMultiPart> entity = Entity
            .entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA_TYPE);

    Response response = webTarget.request().accept(MediaType.APPLICATION_JSON)
            .post(entity);

    log.error("BULK MAPPING: Response 1: {}", response);

    BulkControlsMappingResponse mappingResponse = response
            .readEntity(BulkControlsMappingResponse.class);

1 个答案:

答案 0 :(得分:0)

我通过在发送请求时使用不同的功能来实现此功能,并且响应的不同如下:

Client client = ClientBuilder.newClient().register(MultiPartFeature.class);
WebTarget webTarget = client.target(endPoint).path("bulkControlsMapping")
                .register(JacksonFeature.class);