使用java客户端通过rest api上传文件时出现400错误请求

时间:2016-06-22 09:12:05

标签: java rest

我有一个要求,我需要编写一个rest API以允许上传文件以及基于Java的客户端来调用带有文件信息的API。

以下是我目前编写的代码 -

@POST
    @Path("/uploadFile")
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {
        String name = file.getOriginalFilename();
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(
                        new FileOutputStream(new File(uploadLocation + name)));
                stream.write(bytes);
                stream.close();
                return "You successfully uploaded " + name + " into " + uploadLocation + name;
            } catch (Exception e) {
                return "You failed to upload " + name + " => " + e.getMessage();
            }
        } else {
            return "You failed to upload " + name + " because the file was empty.";
        }
    }

以下是我写的java客户端 -

public class TestFileUpload {

    public static void main(String args[]) throws Exception
    {
        HttpClient httpclient = new DefaultHttpClient();

        HttpPost httppost = new HttpPost("http://localhost:8080/upload/uploadFile");
        httppost.setHeader("content-type", "false");
        File file = new File("C:\\dummyUpload.txt");

        MultipartEntity mpEntity = new MultipartEntity();
        ContentBody cbFile = new FileBody(file, "multipart/form-data");
        mpEntity.addPart("file", cbFile);


        httppost.setEntity(mpEntity);
        System.out.println("executing request " + httppost.getRequestLine());
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity resEntity = response.getEntity();

        System.out.println(response.getStatusLine());
        if (resEntity != null) {
          System.out.println(EntityUtils.toString(resEntity));
        }
        if (resEntity != null) {
          resEntity.consumeContent();
        }

        httpclient.getConnectionManager().shutdown();
    }
}

然而,当我启动服务器时,我可以看到API正在运行,当我运行客户端代码时,我收到400个错误请求。

任何线索,可能是什么问题。

BR,

AJ

3 个答案:

答案 0 :(得分:0)

您通常会构建一个类似的文件上传请求(从HttpClient example复制):

var base64Data = data.replace(/^data:image\/png;base64,/, "");
    require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
      console.log(err);
    });

问题是您将/* * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.http.examples.entity.mime; import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * Example how to use multipart/form encoded POST request. */ public class ClientMultipartFormPost { public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("File path not given"); System.exit(1); } CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost("http://localhost:8080" + "/servlets-examples/servlet/RequestInfoExample"); FileBody bin = new FileBody(new File(args[0])); StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN); HttpEntity reqEntity = MultipartEntityBuilder.create() .addPart("bin", bin) .addPart("comment", comment) .build(); httppost.setEntity(reqEntity); System.out.println("executing request " + httppost.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httppost); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); HttpEntity resEntity = response.getEntity(); if (resEntity != null) { System.out.println("Response content length: " + resEntity.getContentLength()); } EntityUtils.consume(resEntity); } finally { response.close(); } } finally { httpclient.close(); } } } 设置为Content-Type 是有效的内容类型。它似乎不应该在使用HttpClient库时设置,并且false的内容类型必须与您尝试上传的文件的内容类型相匹配 - 在这种情况下,它是&#39 ; sa文本文件,因此ContentBody是合适的。

您也不能将text/plain设置为Content-Type - 您还必须在其上设置multipart/form-data属性,例如:boundary,用于分隔文件。

编辑:可以处理它的控制器看起来像:

Content-Type: multipart/form-data; boundary=1234567890ABCDEF

答案 1 :(得分:0)

&#39;内容类型&#39;标题值&#39; false&#39;是无效的。它应该反映您数据的内容类型。

例如,如果您的内容正文是JSON,那么Content-Type标题应设置为&#39; application / json &#39;,XML应设置为&#39; 应用/ XML &#39;等。如果您的内容是纯文本,您只需设置&#39; text / plain &#39;。

您可以阅读可用内容类型here

答案 2 :(得分:0)

如果已为表单数据添加任何内容,则删除标题ContentType