java - 如何使用 Spring Web Flux 处理 url 编码的有效负载
问题描述
客户端正在发送编码的有效负载(编码百分比),而给定的代码适用于未编码的有效负载/XML(内容类型:应用程序/xml),但它会因 http 415 编码的有效负载/XML 文件(内容类型:应用程序/ x-www-form-urlencoded)。
我注意到 FormHttpMessageReader.java 成功解码了有效负载(在调试日志中看到),但是在我的代码无法将解码后的 XML 正确映射到 POJO 之后,在请求流的某个地方。
卷曲请求 -
curl -H 'Content-type: application/x-www-form-urlencoded' http://localhost:8081/api/v1/app/test -d @encodedpyaload.xml -i-H 'Accept: application/xml, text/xml, application/x-www-form-urlencoded, */*’
HTTP/1.1 100 Continue
HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json
Content-Length: 158
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Referrer-Policy: no-referrer
{"error":"415 UNSUPPORTED_MEDIA_TYPE \"Content type 'application/x-www-form-urlencoded' not supported for bodyType=test.package.Pojo\””}
配置类 -
@Bean
public RouterFunction<ServerResponse> testRoute() {
return route(POST(“/app/test”).and(contentType(MediaType.APPLICATION_FORM_URLENCODED)),
handler::testHandler);
}
处理程序类
public Mono<ServerResponse> testHandler(final ServerRequest request) {
return dataManager.testSave(request.bodyToMono(Pojo.class))
.flatMap(uri -> ServerResponse.ok().build())
.switchIfEmpty(ServerResponse.badRequest().build());
}
更新了 Handler 类代码
处理程序类
return dataManager.testSave(request.bodyToMono(String.class)
.flatMap(body -> Mono.just(URLDecoder.decode(body, StandardCharsets.UTF_8))
.map(s -> createBody(s))).cast(Pojo.class))
.flatMap(uri -> ServerResponse.ok().build())
.switchIfEmpty(ServerResponse.badRequest().build());
private Pojo createBody(String s) {
XmlMapper mapper = new XmlMapper();
Pojo pojo = new Pojo();
try {
pojo = mapper.readValue(s, Pojo.class);
} catch (IOException e) {
e.printStackTrace();
}
return pojo;
}
POJO类
@XmlRootElement(name = “root”)
public class Pojo {
@XmlElement(name = “id”)
public long getId() {
return id;
}
public void setId(long id) {
this.id= id;
}
}
解决方案
当我们偏离处理标准的“内容类型:应用程序/xml”时,这里添加了 3 个额外的步骤-
1)解码(百分比编码的请求正文)有效负载
2) 将解码后的字符串编码为 XML
3) 将 XML 转换为 Mono
代码更改:
处理函数:
就像托马斯建议的那样——
request.bodyToMono(String.class).flatmap(body -> Mono.just(decode(body)).map(decodedstring -> createXML(decodedstring))).cast(Pojo.class))
和
private String decode(String body){
String str1 = "";
String str2 = body;
//if percent content is re-encoded multiple times
while(!str1.equals(str2)) {
str1=str2;
str2=URLDecoder.decode(str2,StandardCharsets.UTF_8)
}
return str2;
}
和
private Pojo createXML(String decodedstring) {
InputStream is = new ByteArrayInputStream(decodedstring.getBytes(Charset.forName("UTF-8")));
Pojo pojo = JAXB.unmarshal(is, Pojo.class);
return pojo;
}
推荐阅读
- android - 安卓通知不起作用它不返回任何错误
- list - 在谷歌表格中使用 api 制作列表
- javascript - 我无法通过对象中的键获取值
- java - java - 如何在java中对ExecutorService中的类似线程求和?
- react-native - 有没有将 StrictMode 与 React-Native 一起使用的示例?
- nginx - Nginx:从反向代理的应用程序重写 url 中的端口
- html - 如何使两个部分在 SVG 中看起来像一个部分?
- python - 从 API 将数据写入数据帧时失败
- php - 将输出格式化为逗号分隔列表而不是嵌套数组
- azure - 无法连接到我的远程应用程序,只有具有相同 IP 的远程桌面