当前位置: 首页 > 知识库问答 >
问题:

隧道MultipartFile

利博远
2023-03-14

我有一个Spring控制器,它在POST上接受一个名为FileUploadBean的类。控制器方法看起来像这样:

第一控制器:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<byte[]> uploadFile(final FileUploadBean fileUploadBean) throws IOException {
   // Some code that works fine here
} 

FileUploadBean属性之一的类型为MultipartFile

现在,我正在尝试添加某种包装器控制器(将在另一台服务器上运行),它也接受FileUploadBean,并将请求转发给第一个控制器:

第二(包装)控制器:

@RequestMapping(value="/upload", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<byte[]> uploadImage(final FileUploadBean fileUploadBean) throws IOException {
  ResponseEntity<byte[]> response = restTemplate.postForEntity([first controller url here], fileUploadBean, byte[].class);
  return response;
}

当我向第一个控制器发送请求时:

org.springframework.http.converter.HttpMessageNotWritableException:

无法写入JSON:找不到java类的序列化程序。伊奥。FileDescriptor,并且没有发现创建BeanSerializer的属性(为了避免html" target="_blank">异常,请禁用SerializationFeature.FAIL_ON_EMPTY_BEANS))(通过引用链:com.outbrain.images.BEANS.FileUploadBean[“file”]-

我如何使这个请求工作?

共有2个答案

壤驷睿
2023-03-14

我调试以前的答案,并发现这个解决方案没有保存文件到文件系统

    @PostMapping(value = "/upload")
public ResponseEntity<Object> upload(MultipartHttpServletRequest request) throws Exception {
    final MultiValueMap<String, Object> requestParts = new LinkedMultiValueMap<>();

    request.getParameterMap().forEach((name, value) -> requestParts.addAll(name, asList(value)));
    request.getMultiFileMap().forEach((name, value) -> {
        List<Resource> resources = value.stream().map(MultipartFile::getResource).collect(toList());
        requestParts.addAll(name, resources);
    });

    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestParts, request.getRequestHeaders());
    return restTemplate.exchange(ImageUrlUtils.getUploadUrl() + "?" + request.getQueryString(),
                                 request.getRequestMethod(), requestEntity, Object.class);

}
薛飞星
2023-03-14

经过一番努力,我终于解决了这个问题。这就是我在第二个控制器中所做的:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody
ResponseEntity<byte[]> uploadImage(final FileUploadBean fileUploadBean) throws Exception {
  File file = null;
  try {
    final MultiValueMap<String, Object> requestParts = new LinkedMultiValueMap<>();

    final String tmpImageFileName = IMAGE_TMP_DIR + fileUploadBean.getFile().getOriginalFilename();
    file = new File(tmpImageFileName);
    fileUploadBean.getFile().transferTo(file);
    requestParts.add("file", new FileSystemResource(tmpImageFileName));

    HttpHeaders headers = new HttpHeaders();
    headers.set("Content-Type", "multipart/form-data"); // Sending it like the client-form sends it

    ResponseEntity<byte[]> response = restTemplate.exchange(ImageUrlUtils.getUploadUrl(), HttpMethod.POST, new HttpEntity<>(requestParts, headers),
      byte[].class);

    return new ResponseEntity<>(response.getBody(), response.getStatusCode());
  } catch (Exception ex) {
    return new ResponseEntity<>((ex.getMessage).getBytes("UTF-8"),
      HttpStatus.INTERNAL_SERVER_ERROR);
  } finally {
    if (file != null && file.exists()) {
      file.delete();
    }
  }
}
 类似资料:
  • 并非您希望公开的所有服务都是基于HTTP或TLS的。 ngrok TCP隧道允许您公开通过TCP运行的任何联网服务。这通常用于公开SSH,游戏服务器,数据库等。启动TCP隧道很容易。 公开在端口1234上运行的基于TCP的服务 ngrok tcp 1234 例子 公开侦听默认端口的SSH服务器 ngrok tcp 22 暴露一个Postgres服务器侦听默认端口 ngrok tcp 5432 暴露

  • HTTPS隧道使用ngrok.com证书终止ngrok.com服务器上的所有TLS(SSL)流量。 对于生产级服务,您需要使用自己的TLS密钥和证书对您的隧道流量进行加密。 ngrok使这个特别容易与TLS隧道。 将TLS流量转发到端口443上的本地HTTPS服务器 ngrok tls -subdomain=encrypted 443 一旦你的隧道运行,尝试访问它与curl。 curl --ins

  • 自定义子域名称 ngrok为它为您打开的HTTP隧道分配随机十六进制名称。 这对于一次性个人用途是可以的。 但是,如果您在黑客马拉松上显示URL或与第三方Webhook集成,则如果隧道名称更改或难以阅读,可能会令人沮丧。 您可以使用-subdomain开关为隧道URL指定自定义子域。 示例:打开具有子域“inconshreveable”的隧道 ngrok http -subdomain=incon

  • 我想通过SSH隧道访问jupyter笔记本,并遵循以下方法 要总结-: 1.登录远程机器 2.在新航站楼: 3.然后转到浏览器,然后转到 现在我的问题是:我只能在两个步骤中访问远程机器 jupyter笔记本电脑只安装在我的电脑上。 当我用较长的登录过程替换第一步的第一行时,第二步应该写什么? 当我插入remote_user=username和remote_user=my_pc_name时,我从ju

  • 我不确定这是否是由端口转发使用私钥而不是密码造成的,但下面是我正在尝试做的 我需要将本地端口3308一直转发到位于3306的my SQL DB。 我可以在我的本地终端上一起运行这样的事情 我在JSch或端口转发方面做错了什么吗?

  • 通配符域 ngrok允许您将HTTP和TLS隧道绑定到通配符域。 所有通配符域(包括ngrok.io的子域)必须首先在您的信息中心为您的帐户保留。 使用-hostname or -subdomain时,指定前导星号以绑定通配符域。 绑定隧道以接收 example.com的所有子域上的流量 ngrok http --hostname *.example.com 80 通配符域规则 使用通配符域在ng