【问题标题】:Send JSON and Image with single request. Angular + Spring Boot使用单个请求发送 JSON 和图像。角+弹簧靴
【发布时间】:2018-05-25 03:50:32
【问题描述】:

弹簧休息控制器

@PostMapping(
    value = "/post",
    produces = MediaType.APPLICATION_JSON_VALUE,
    consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE}
)
public ResponseEntity<User> handleFileUpload(@RequestParam("user") User user, @RequestPart("file") MultipartFile file) {
    // do something with User and file
    return ResponseEntity.ok().build();
}

角度服务

@Injectable()
export class UploadFileService {

  constructor(private http: HttpClient) { }
  pushFileToStorage(file: File): Observable<HttpEvent<{}>> {
    let formdata: FormData = new FormData();
    formdata.append('file', file);
    formdata.append('user', JSON.stringify(new User('John', 12)))

    const req = new HttpRequest('POST', '/post', formdata, {
      reportProgress: true,
    });

    return this.http.request(req);
  }
}

当我尝试发送请求时,我收到 500 Internal Server Error.

这是一个请求标头

POST /post HTTP/1.1
Host: localhost:4200
Connection: keep-alive
Content-Length: 152881
Accept: application/json, text/plain, */*
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydaQb5yaWw2xu1V9r
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

请求负载

------WebKitFormBoundarydaQb5yaWw2xu1V9r
Content-Disposition: form-data; name="file"; filename="Screen Shot 2017-10-24 at 8.49.13 PM.png"
Content-Type: image/png


------WebKitFormBoundarydaQb5yaWw2xu1V9r
Content-Disposition: form-data; name="user"

{"name":"John","age":12}
------WebKitFormBoundarydaQb5yaWw2xu1V9r--

注意:如果在 Spring rest 控制器中我将参数类型 User 更改为 String ,它可以工作。

问题:如何从 Angular 发送请求,以便在 Spring 上我可以获取 User 和 MultipartFile,而不是 String。

【问题讨论】:

  • 我正在使用 Angular 4 和 Spring Boot 1.5.7
  • 您找到解决此错误的任何方法了吗?我也一样,请多多支持。

标签: spring angular typescript spring-boot


【解决方案1】:

变化

public ResponseEntity<User> handleFileUpload(@RequestParam("user") User user, @RequestPart("file") MultipartFile file)

public ResponseEntity<User> handleFileUpload(@RequestPart("user") User user, @RequestPart("file") MultipartFile file)

并将请求更改为这样的内容将起作用:

curl -i -X POST -H "Content-Type: multipart/form-data" \
-F 'user={"name":"John","age":12};type=application/json' \
-F "file=@myfile.txt" http://localhost:8080/post

对于consumes,仅需要MediaType.MULTIPART_FORM_DATA_VALUE

要以角度提出上述类型的请求,可以这样做:

const userBlob = new Blob(JSON.stringify(new User('John', 12)),{ type: "application/json"});
formdata.append('user', userBlob);

【讨论】:

  • 我尝试了同样的方法,但我得到了,无法转换请求元素:org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException:无法转换类型'org.springframework.web的值。 multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' 到所需类型'com.PersonDTO';嵌套异常是 java.lang.IllegalStateException:无法将类型“org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile”的值转换为所需类型“com.PersonDTO”:找不到匹配的编辑器或转换策略
  • @dinesh 你能在一个单独的问题中发布你的代码吗?
  • 我试过你的提议,你需要把[]加到JSON.stringify(new User('John', 12):const myObjStr = JSON.stringify(new User('John', 12); const userBlob = new Blob([myObjStr],{ type: "application/json"});
  • 这取决于您希望 JSON 的方式以及后端使用的数据模型。有或没有[] 都是有效的 JSON,如果我们有正确的数据模型来处理它,应该可以正常工作。
猜你喜欢
  • 2018-10-31
  • 2021-12-22
  • 2023-03-29
  • 1970-01-01
  • 2018-08-09
  • 2019-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多