java - 如何使用HEAD检查文件是否存在

标签 java angular spring spring-boot angular8

我想使用这个 Spring Endpoint 上传文件。

@PostMapping(value = "/upload", produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<StringResponseDTO> uploadFile(@RequestParam("file") MultipartFile file,
            RedirectAttributes redirectAttributes, @RequestParam("id") Integer merchantId) throws Exception {
        ..............
        return ResponseEntity.ok(new StringResponseDTO("test"));
    }

Angular 代码:

imports(file: any, id: number) {
    const formData = new FormData();
    formData.append('file', file, file.name);
    return this.http.post(environment.api.urls.merchants.uploadLogo, formData, {
      params: { id: id.toString() }
    }).pipe(
      catchError(this.handleError)
    );
  }

就我而言,如果文件存在,我想显示 Angular 的下载链接。如何使用 HEAD 发出请求并检查文件是否存在? 我不想下载该文件来验证该文件是否可供下载。

最佳答案

HTTP 请求方法

在直接解决您的问题之前,我想先介绍一下 HTTP 请求方法的一般概念。 HTTP 请求方法用于指示对所识别的资源执行所需的操作。以下方法在一定程度上进行了标准化

  • 获取
  • 发布
  • 选项
  • 放置
  • 删除
  • 补丁
  • 连接

资源代表什么以及如何实际实现服务和调用服务(请求)完全取决于您。

With that being said, it would be accurate to say that a GET request that is used explicitly to update an existing value is implemented incorrectly.

Additionally, what method you choose will be limit your functionality if you are using any type of client-side or server-side platform or library. For example, Angular won't provide a means of sending a request body with a GET, even though you technically could craft an HTTP GET call that contains a request body.

Spring 启动

查看您的代码,您使用以下代码明确将您的服务设置为 POST 服务

@PostMapping(value = "/upload", produces = { MediaType.APPLICATION_JSON_VALUE })

您可以通过将该行替换为以下内容来显式指定您的服务作为 HEAD 服务

@RequestMapping( value = "/upload", method = RequestMethod.HEAD, produces = { MediaType.APPLICATION_JSON_VALUE } )

但是,请记住 HEAD 方法基本上应该是 GET 方法,但应该只返回 header 。在提供的示例中,我无法说出您的 DTO 具体做了什么,但它似乎正在返回一个主体。相反,您可以使用类似的内容仅返回 header

String fileId = ....
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("fileId", fileId);

return ResponseEntity.ok().headers(responseHeaders);

您使用的命名约定不是 RESTful。首先,/upload 端点不是面向资源的,因为您的路径中没有指定资源。

此外,上传可能不是正确使用的动词,因为您实际上所做的是检查验证。我可能会将端点交换为类似的东西

 @RequestMapping( value = "/resourceName/validate", method = RequestMethod.HEAD, produces = { MediaType.APPLICATION_JSON_VALUE } )

resourceName替换为您的资源名称。

Angular

同样,在 Angular 调用中,您的调用是显式 POST

return this.http.post( ... )

类似地,Angular 有一个 $http.head 方法

return this.http.head( ... )

与 Spring Boot 不同,您可能无法简单地逐行交换。您需要确保 head 中的参数与 post 中的参数匹配,如果不匹配,则需要进行相应调整。

摘要

我的回答可以总结如下

  • 您可能需要重新考虑 HEAD 的总体使用(这里适用吗?)
  • 您可能希望将端点重命名为面向资源的
  • 如果您确实想使用 head,则需要更改 Spring Boot 注释
  • 如果您确实想使用 head,则需要将 Spring Boot 响应更改为仅包含 header
  • 如果您确实想使用 had,您需要更改 Angular 请求以使用 head 方法

关于java - 如何使用HEAD检查文件是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57747117/

相关文章:

java - 将 Double 数组转换为 BigDecimals 数组

java - 如何为 Spring Roo 项目创建 Maven 模块?

javascript - 在 Ionic 2 中通过 id 检索 DOM 元素

java - cxf 升级抛出 NoSuchFieldError : REFLECTION

java - 使许多 bean 依赖于一个 bean 的简单方法

java - RestTemplate - RestClientException - 无法提取响应

java - 匿名可运行实现并将其发布到处理程序

javascript - MultipartFile 数组未发送到 spring Controller

javascript - @Input() 问题

angular - 重新初始化一个已经加载的 Angular 组件