问题
有一条考试结果,需要更新,采用了PUT请求。
//前台
@Action()
examResult(id: string, examResult: { score: number, qualified: boolean, remarks: string, push: boolean }): Observable<void> {
examResult = examResult as Exam;
return this.httpClient.put<void>(`/exam/examResult/${id}`, {examResult});
}
//后台
@PutMapping("examResult/{id}")
public void putExamResult(@PathVariable String id, @RequestBody @Valid ExamDto.UpdateResult request) {
this.examService.updateExamResult(id , request);
}
//后台实体校验
@Data
public static class UpdateResult {
@NotNull
private Boolean qualified;
@NotNull
private Short score;
@Size(max = 50)
private String remarks = "";
@NotNull
private Boolean push;
}
上面examResult方法接收两个参数,一个字段,一个Exam对象。当发起请求的时候后台给我们传了一个错误如下:
这个错误说 score、qualified、push字段的值都是空的;后面打印到控制台的时候 又是有值的。
console.log(id, examResult);
当时就觉得很奇怪,这不是有值吗,为什么后台没有接收到值呢,然后就去网络中检查请求体:
json 对象中又包含了json对象,后台并不需要这么接收,只需要绿色框里面的json对象。
此时就想到了之前上传文件遇到的问题,也是{}
引起的,最后把{}
去掉,后台就成接收到值了
return this.httpClient.put<void>(`/exam/examResult/${id}`, examResult);
问题分析
- 使用
{}
作为参数,Spring Boot 会将请求体中的 JSON 数据解析为 Java 对象,当前后台也确实需要json对象,但不需要json对象中的json对象。 - 因为examResult()方法接收参数的时候,就是接收的一个json对象,不需要第二次包裹了。
GET请求
用于从服务器获取数据。
this.httpClient.get<T>(url: string, options?: { params?: HttpParams | { [param: string]: string | string[]; }; ... }): Observable<T>
设置参数查询
假设发起get请求,需要设置正确参数,例:预期地址如下
http://angularHttpTest.com/page?page=0&size=10&score=75
方法一:作为方法参数直接查询
pageAction(params: { page: number, size: number, score?: number }): Observable<Page<Exam>> {
return this.httpClient.get<Page<Exam>>('http://angularHttpTest.com/page', {params});
}
方法二:创建 HttpParams 对象
set()
const params = new HttpParams()
.set('page', 0)
.set('size', 10);
.set('score', 75);
this.httpClient.get<Page<Exam>>('http://angularHttpTest.com/page', {params});
需要注意的是,通过链式语法调用 set()
方法,构建 HttpParams
对象。这是因为 HttpParams 对象是不可变的,通过 set()
方法可以防止该对象被修改。
每当调用 set()
方法,将会返回包含新值
的 HttpParams
对象,因此如果使用下面的方式,将不能正确的设置参数。
const params = new HttpParams()
.set('page', 0);
params.set('size', 10);
params.set('score', 75);
// 最中结果只会是http://angularHttpTest.com/page?page=0
append()
const params = new HttpParams()
.append('page', 0)
.append('size', 10);
.append('score', 75);
this.httpClient.get<Page<Exam>>('http://angularHttpTest.com/page', {params: params});
set() 和 append()区别
set()
和append()
特性一样的,都会返回新值的HttpParams
对象set()
会覆盖现有参数的值,如果该参数已经存在。例如,先使用set('page', 0)
,然后再调用set('page', 1)
,page
参数的值将变为1
,而不是保留0
。append()
方法则不会覆盖现有参数,而是会添加一个新的参数值。如果该参数已经存在,则会将新的值追加到现有的值列表中。
使用 fromString 语法
params = new HttpParams().fromString('page=0&size=10&score=75');
this.httpClient.get<Page<Exam>>('http://angularHttpTest.com/page', {params: params});
post 请求
用于向服务器发送数据,一般用于创建数据。
this.httpClient.post<T>(url: string, body: any | null, options?: { headers?: HttpHeaders; ... }): Observable<T>
put 请求
用于更新服务器上的资源。
this.httpClient.put<T>(url: string, body: any | null, options?: { headers?: HttpHeaders; ... }): Observable<T>
post()
和put()
使用方法都一样,上面那个问题就是最好的案例了。
delete 请求
用于删除服务器上的资源。
this.httpClient.delete<T>(url: string, options?: { headers?: HttpHeaders; ... }): Observable<T>
示例:
@Action()
deleteAction(id: number): Observable<void> {
Assert.isNumber(id, 'id不能为空');
return this.httpClient.delete<void>(`/exam/examResult/${id}`);
}
总结
忘性比较大,写篇博客的目的是在巩固下,不宜忘记。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。