org.springframework.web.multipart.support.MissingServletRequestPartException:所需的请求部分 'file' 不存在

org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present

我正在尝试访问另一台服务器以使用 Java 上传文件。我可以连接到服务器,但无法上传文件。
服务器(Spring启动应用程序)以这种方式接受文件。

@PostMapping(value = ("multipart-store"), headers = ("content-type=multipart/*"))
CustomResponse gridFs(@RequestPart("file") MultipartFile multipartFile) throws Exception {
    return new CustomResponse(storageService.storeObject(multipartFile));
}

我尝试了几种访问服务器的方法。
我的 Java 访问服务器的代码如下。
第一种方式

try {
  final File uploadFile2 = new File("/home/thrymr/Desktop/invoicesample.pdf");

  final String requestURL = "http://localhost:8082/data/multipart-store";

  final MultipartUtility multipart = new MultipartUtility(requestURL, charset);

  multipart.addFilePart("file", uploadFile2);

  final List<String> response = multipart.finish();

  System.out.println("SERVER REPLIED:");

  for (final String line : response) {
    System.out.println(line);
  }
} catch (final IOException ex) {
  System.err.println(ex);
}

public class MultipartUtility {

  private final String boundary;
  private static final String LINE_FEED = "\r\n";
  private final HttpURLConnection httpConn;
  private final String charset;
  private final OutputStream outputStream;
  private final PrintWriter writer;

  public MultipartUtility(final String requestURL, final String charset) throws IOException {
    this.charset = charset;

    this.boundary = "" + System.currentTimeMillis() + "";

    final URL url = new URL(requestURL);
    this.httpConn = (HttpURLConnection) url.openConnection();
    this.httpConn.setUseCaches(false);
    this.httpConn.setDoOutput(true); // indicates POST method
    this.httpConn.setDoInput(true);
    this.httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + this.boundary);
    this.outputStream = this.httpConn.getOutputStream();
    this.writer = new PrintWriter(new OutputStreamWriter(this.outputStream, charset), true);
  }

  public void addFilePart(final String fieldName, final File uploadFile) throws IOException {
    final String fileName = uploadFile.getName();

    this.writer.append("file : "+uploadFile);
    this.writer.flush();

    final FileInputStream inputStream = new FileInputStream(uploadFile);
    final byte[] buffer = new byte[4096];
    int bytesRead = -1;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
      this.outputStream.write(buffer, 0, bytesRead);
    }
    this.outputStream.flush();
    inputStream.close();

    this.writer.append(LINE_FEED);
    this.writer.flush();
  }

  public List<String> finish() throws IOException {
    final List<String> response = new ArrayList<String>();

    this.writer.append(LINE_FEED).flush();
    this.writer.append("--" + this.boundary + "--").append(LINE_FEED);
    this.writer.close();

    final int status = this.httpConn.getResponseCode();
    if (status == HttpURLConnection.HTTP_OK) {
      final BufferedReader reader = new BufferedReader(new InputStreamReader(this.httpConn.getInputStream()));
      String line = null;
      while ((line = reader.readLine()) != null) {
        response.add(line);
      }
      reader.close();
      this.httpConn.disconnect();
    } else {
      throw new IOException("Server returned non-OK status: " + status);
    }

    return response;
  }
}

第二种方式

final File file = new File("/home/thrymr/Desktop/invoicesample.pdf");  
final HttpPost post = new HttpPost("http://localhost:8082/data/multipart-store");  
final FileBody fileBody = new FileBody(file, ContentType.MULTIPART_FORM_DATA);  
final MultipartEntityBuilder builder = MultipartEntityBuilder.create();  

builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);  
builder.addPart("file", fileBody);  

final HttpEntity entity = builder.build();  
post.setHeader("Content-Type", "multipart/form-data; boundary=gv");  
final CloseableHttpClient client = HttpClients.createDefault();  
post.setEntity(entity);  

final HttpResponse response = client.execute(post);  
System.out.println(response);  

在上面的 addFilePart() 方法中,通过将 this.writer.append("file : "+uploadFile); 替换为以下代码行,我能够解决问题。

this.writer.append("--" + this.boundary).append(LINE_FEED);
this.writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
this.writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
this.writer.append(LINE_FEED);