Angular调用Spring Boot PUT接口报415错误,如何设置MediaType?
我正在开发基于Angular与Spring Boot的Web项目,作为新手,尝试通过PUT请求修改后端已有Category对象名称时,始终收到415错误。曾尝试在组件类中设置Content-Type为application/json但无效,Postman发送相同请求却正常。
核心问题排查
1. Angular HttpClientService的PUT方法实现错误
HttpClientService的PUT方法错误地将路径字符串作为请求体发送,而非传入的Category对象,导致后端无法解析JSON格式数据,直接触发415错误。
// 错误代码 public put<T>(path: string, param?: HttpParameters): Observable<T> { return this.http.put<T>(`${this.apiUrl}/${path}`, path); }
2. CategoryService的update方法路径不匹配
后端Spring Boot的PUT接口是@PutMapping("{id}"),要求路径中携带Category的ID(如categories/1),但前端仅传递了基础路径categories,既不匹配接口路由,也无法正确定位要修改的资源。
// 错误代码 public update(category: Category): Observable<Category> { return this.httpClientService.put<Category>(`${this.categoryUrl}`, category); }
3. 组件中Headers设置错误且未生效
组件内定义的Headers将Content-Type写成了application-json(正确应为application/json),且该Headers未在请求中实际使用。不过Angular HttpClient默认会为JSON请求自动设置正确的Content-Type,此问题并非核心原因。
// 错误代码 public headers = new HttpHeaders({'Content-Type': 'application-json'});
4. CategoryService的findById方法路径错误
该方法需根据ID查询单个Category,但当前代码未拼接ID到路径,会调用查询所有Category的接口,无法获取目标资源。
// 错误代码 public findById(id: string): Observable<Category> { return this.httpClientService.get<Category>(this.categoryUrl); }
修复步骤
1. 修正HttpClientService的PUT方法
将请求体改为传入的业务对象,同时支持可选的请求配置:
public put<T>(path: string, body: T, options?: any): Observable<T> { return this.http.put<T>(`${this.apiUrl}/${path}`, body, options); }
2. 修正CategoryService的update方法
拼接Category的ID到路径,匹配后端接口路由:
public update(category: Category): Observable<Category> { return this.httpClientService.put<Category>(`${this.categoryUrl}/${category.id}`, category); }
3. 修正CategoryService的findById方法
拼接ID到路径,正确查询单个Category:
public findById(id: string): Observable<Category> { return this.httpClientService.get<Category>(`${this.categoryUrl}/${id}`); }
4. 组件onSubmit方法优化
确保从路由参数获取Category ID,先查询现有数据再执行更新:
public onSubmit(): void { if (this.createForm && this.createForm.valid) { const {name, description} = this.createForm.getRawValue(); this.route.paramMap.pipe(takeUntil(this.onDestroy$)).subscribe(params => { const categoryId = params.get('id'); if (categoryId) { this.categoryService.findById(categoryId).pipe(takeUntil(this.onDestroy$)).subscribe(existingCategory => { const updatedCategory = { ...existingCategory, name, description }; this.categoryService.update(updatedCategory).pipe(takeUntil(this.onDestroy$)).subscribe(category => { this.onCreateSuccess(category); }); }); } }); } }
后端代码确认
后端Spring Boot的接口与CORS配置均正常:
@PutMapping("{id}")正确接收@RequestBody Category参数- CORS配置已允许PUT方法与前端域名跨域请求
内容的提问来源于stack exchange,提问作者magnet_code007

