Spring WebClient POST请求在传递领域对象时似乎无法正常工作。

huangapple go评论114阅读模式
英文:

Spring WebClient POST request doesnt seem to work when passing Domain objects

问题

在传递域对象时出现了WebClient调用失败的问题,但将其作为JSON字符串传递则可以正常工作:

这个部分正常工作:

String req = "{
    \"Login\": \"1121\",
    \"Password\": \"1212=121\",
    \"Domain\": \"corpdev.net\"
}";
String respo = webClient.post()
    .uri("https://sssss.com")
    .contentType(MediaType.APPLICATION_JSON)
    .bodyValue(req)
    .retrieve()
    .bodyToMono(String.class)
    .block();

但是使用域对象时不起作用:

String resp = webClient
    .post()
    .uri("https://sssss.com")
    .contentType(MediaType.APPLICATION_JSON)
    .accept(MediaType.APPLICATION_JSON)
    .body(Mono.just(login), Login.class)
    .retrieve()
    .bodyToMono(String.class)
    .block();
public class Login {
    private String Login;
    private String Password;
    private String Domain;
}

我对Webflux有点陌生,似乎无法使其正常工作。看起来我漏掉了一些简单的东西。

英文:

Having an issue where the WebClient Call fails when passing a domain object but passing as a JSON String works :

This works :

String req="{\n" +
			"\"Login\": \"1121\",\n" +
			"\"Password\": \"1212=121\",\n" +
			"\"Domain\": \"corpdev.net\"\n" +
			"}";
String respo=webClient.post()
				.uri("https://sssss.com")
				.contentType(MediaType.APPLICATION_JSON)
				.bodyValue(req)
				.retrieve()
				.bodyToMono(String.class)
						.block();

but the same using a Domain object doesnt work :

String resp = webClient
				.post()
				.uri("https://sssss.com")
				.contentType(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON )
				.body(Mono.just(login),Login.class)
				.retrieve()
				.bodyToMono(String.class)
				.block();
public class Login {
    private String Login;
    private String Password;
    private String Domain;
}

I am a bit new to Webflux and cant seem to get this working . Seems like iam missing something simple . I was expecting the second option to work as it seems straight forward but they object value doesnt seem to be sent to the Rest call .

答案1

得分: 1

WebClient 使用 Jackson 库来编码内容负载。编码是通过 WebClient 委托给 Jackson2JsonEncoder 完成的。Jackson2JsonEncoder 使用 ObjectMapper(作为与 Jackson 库的高级 API 交互的组件)将您的类序列化为文本JSON表示。

问题在于,您的 Login 类在其当前形式下无法序列化为JSON。您可以执行以下操作之一:

  1. 在您的类上生成getter方法,例如 getLogin()getPassword() 等。
  2. 如果您在使用较新版本的Java,可以将 Loginclass 更改为 record
  3. 与生成getter方法不同,您可以使用 @JsonProperty 注解对字段进行注解。

上述三点中的任何一点都会作为提示传递给 Jackson(执行实际编码的库),指导其如何将您的类序列化为JSON。

此外,在Java中,按照惯例,类字段名称应以小写字母开头。

因此,假设您的 Login 现在是一个 record,您可以像这样在 WebClient 中使用它:

String response = webClient.post()
                .uri("https://sssss.com")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(new Login("Login", "Password", "Domain"))
                .retrieve()
                .bodyToMono(String.class)
                .block();
英文:

WebClient uses Jackson library to encode the content payload. Encoding is delegated from WebClient to Jackson via Jackson2JsonEncoder. Jackson2JsonEncoder uses ObjectMapper (a component which acts as a high level API to the Jackson library) to serialize your class to a textual JSON representation.

And the problem is, your Login class is not serializable to JSON in its current form.
You can do one of the following:

  1. generate getters on your class such as getLogin(), getPassword() etc.
  2. if you are on recent Java, you can change Login from class to record
  3. instead of generating getters, you can annotate the fields with @JsonProperty annotation

Any of the three points above acts as hint to Jackson (the library doing the actual encoding) how to serialize your class to JSON.

Also, it is a convention in Java to start class field names in lower case.

So assuming your Login is now a record, you can use it with WebClient like so

String respo = webClient.post()
                .uri("https://sssss.com")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(new Login("Login","Password","Domain")
                .retrieve()
                .bodyToMono(String.class)
                .block();

答案2

得分: 0

我刚刚与我的当前项目进行了比较,我能看到的唯一区别是你传递请求体的方式,你可以尝试将以下行替换为:

.body(Mono.just(login),Login.class)

替换为

.bodyValue(login)

祝好!

英文:

I've just compared with my current project and the only difference I can see is based on the way you passed the request body, can you try to replace the line :

.body(Mono.just(login),Login.class)

by

.bodyValue(login)

Regards,

huangapple
  • 本文由 发表于 2023年6月6日 11:21:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411254.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定