5

问题

有一条考试结果,需要更新,采用了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对象。当发起请求的时候后台给我们传了一个错误如下:

image.png

这个错误说 score、qualified、push字段的值都是空的;后面打印到控制台的时候 又是有值的。

console.log(id, examResult);

image.png

当时就觉得很奇怪,这不是有值吗,为什么后台没有接收到值呢,然后就去网络中检查请求体:

image.png

json 对象中又包含了json对象,后台并不需要这么接收,只需要绿色框里面的json对象。

此时就想到了之前上传文件遇到的问题,也是{}引起的,最后把{}去掉,后台就成接收到值了

return this.httpClient.put<void>(`/exam/examResult/${id}`, examResult);

image.png

问题分析

  • 使用{}作为参数,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 对象,因此如果使用下面的方式,将不能正确的设置参数。
image.png

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});

image.png

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}`);
}

总结

忘性比较大,写篇博客的目的是在巩固下,不宜忘记。


zZ_jie
401 声望9 粉丝

虚心接受问题,砥砺前行。