为什么 request.ts 中的 serializeBody 方法不转换 JSON.stringify(this.body) 为大小写字符串?
Why serializeBody method in request.ts does not convert JSON.stringify(this.body) in case string?
当我将 string
值传递给 post 方法时,该值未被转换 JSON
。
所以我们无法在 Controller 中获取此值。
我检查了以下代码并找到了值未转换的原因。
但我无法理解这种行为是正确的。
apply(id: string): Observable<boolean> {
return this.http.post<boolean>(
REQUEST_URL + '/applicationrequest',
id,
HEADERS
);
}
@ResponseBody
@RequestMapping(value = "/applicationrequest", method = RequestMethod.POST)
public boolean apply(@RequestBody UUID id) {
return usecase.apply(id);
}
我想知道 string
不能自动转换 JSON
的原因。
如果使用 httpClient
的方法,我想知道正确的使用方法。
谢谢。
Angular版本为8.1.0。
Java 是 Java 8。
Spring 是 5.1 / Spring 启动 2.1
仅仅是因为它们是两个完全不同的东西。 Angular(或 httpclient)无法通过魔法知道端点究竟需要或期望什么作为输入。
作为开发人员,生成与服务器接口匹配的 http 请求完全取决于您。
我的团队中有人也发现了这个问题,我们需要为所有仅在正文中接受字符串的 HTTP PUT/POST 方法添加 JSON.stringify(...)
。我们生成的代理(我们使用 Swagger)没有为我们添加这个。
实际问题出在Angular code:
/**
* Transform the free-form body into a serialized format suitable for
* transmission to the server.
*/
serializeBody(): ArrayBuffer | Blob | FormData | string | null {
// If no body is present, no need to serialize it.
if (this.body === null) {
return null;
}
// Check whether the body is already in a serialized form. If so,
// it can just be returned directly.
if (isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) ||
typeof this.body === 'string') {
return this.body;
}
// Check whether the body is an instance of HttpUrlEncodedParams.
if (this.body instanceof HttpParams) {
return this.body.toString();
}
// Check whether the body is an object or array, and serialize with JSON if so.
if (typeof this.body === 'object' || typeof this.body === 'boolean' ||
Array.isArray(this.body)) {
return JSON.stringify(this.body);
}
// Fall back on toString() for everything else.
return (this.body as any).toString();
}
普通字符串将使用最后一个选项并将呈现为纯字符串,而不是通过 JSON.stringify
。
我创建了一个 HTTP interceptor 检查内容类型,如果它设置为 application/json
或 text/json
并且正文是一个纯字符串,那么拦截器调用 JSON.stringify
以确保它是一个有效的 JSON 字符串。这个拦截器看起来像这样:
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class StringInterceptor implements HttpInterceptor{
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (typeof request.body === 'string') {
const contentType = request.headers.get('Content-Type')
if (contentType == 'application/json' || contentType == 'text/json') {
request = request.clone({
body: JSON.stringify(request.body)
});
}
}
return next.handle(request)
}
}
您还需要通过在 app.module.ts
中添加以下代码来注册拦截器(确保您导入拦截器)到提供者注册中:
{
provide: HTTP_INTERCEPTORS,
useClass: StringInterceptor,
multi: true
},
还要确保删除自己的 JSON.stringify(...)
调用,以避免所有字符串都有过多的引号。
当我将 string
值传递给 post 方法时,该值未被转换 JSON
。
所以我们无法在 Controller 中获取此值。
我检查了以下代码并找到了值未转换的原因。
但我无法理解这种行为是正确的。
apply(id: string): Observable<boolean> {
return this.http.post<boolean>(
REQUEST_URL + '/applicationrequest',
id,
HEADERS
);
}
@ResponseBody
@RequestMapping(value = "/applicationrequest", method = RequestMethod.POST)
public boolean apply(@RequestBody UUID id) {
return usecase.apply(id);
}
我想知道 string
不能自动转换 JSON
的原因。
如果使用 httpClient
的方法,我想知道正确的使用方法。
谢谢。
Angular版本为8.1.0。 Java 是 Java 8。 Spring 是 5.1 / Spring 启动 2.1
仅仅是因为它们是两个完全不同的东西。 Angular(或 httpclient)无法通过魔法知道端点究竟需要或期望什么作为输入。
作为开发人员,生成与服务器接口匹配的 http 请求完全取决于您。
我的团队中有人也发现了这个问题,我们需要为所有仅在正文中接受字符串的 HTTP PUT/POST 方法添加 JSON.stringify(...)
。我们生成的代理(我们使用 Swagger)没有为我们添加这个。
实际问题出在Angular code:
/**
* Transform the free-form body into a serialized format suitable for
* transmission to the server.
*/
serializeBody(): ArrayBuffer | Blob | FormData | string | null {
// If no body is present, no need to serialize it.
if (this.body === null) {
return null;
}
// Check whether the body is already in a serialized form. If so,
// it can just be returned directly.
if (isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) ||
typeof this.body === 'string') {
return this.body;
}
// Check whether the body is an instance of HttpUrlEncodedParams.
if (this.body instanceof HttpParams) {
return this.body.toString();
}
// Check whether the body is an object or array, and serialize with JSON if so.
if (typeof this.body === 'object' || typeof this.body === 'boolean' ||
Array.isArray(this.body)) {
return JSON.stringify(this.body);
}
// Fall back on toString() for everything else.
return (this.body as any).toString();
}
普通字符串将使用最后一个选项并将呈现为纯字符串,而不是通过 JSON.stringify
。
我创建了一个 HTTP interceptor 检查内容类型,如果它设置为 application/json
或 text/json
并且正文是一个纯字符串,那么拦截器调用 JSON.stringify
以确保它是一个有效的 JSON 字符串。这个拦截器看起来像这样:
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class StringInterceptor implements HttpInterceptor{
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (typeof request.body === 'string') {
const contentType = request.headers.get('Content-Type')
if (contentType == 'application/json' || contentType == 'text/json') {
request = request.clone({
body: JSON.stringify(request.body)
});
}
}
return next.handle(request)
}
}
您还需要通过在 app.module.ts
中添加以下代码来注册拦截器(确保您导入拦截器)到提供者注册中:
{
provide: HTTP_INTERCEPTORS,
useClass: StringInterceptor,
multi: true
},
还要确保删除自己的 JSON.stringify(...)
调用,以避免所有字符串都有过多的引号。