gpt4 book ai didi

java - 为什么@RequestBody不需要arg构造函数?

转载 作者:行者123 更新时间:2023-11-30 03:14:24 25 4
gpt4 key购买 nike

我只是在玩 spring-boot,只是想用 method = RequestMethod.POST 创建一个 Controller

我的 Controller :

@RequestMapping(value = "/user/signup",
method = RequestMethod.POST)
private String signUpNewUser(@Valid @RequestBody SignInUserForm userForm){
// validation + logic
}

SignUpUserForm 类:

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SignInUserForm {
@NotEmpty
@Email
private String email;

@NotEmpty
@Size(min = 8, max = 24)
private String password;

@NotEmpty
@Size(min = 8, max = 24)
private String repeatedPassword;
}

最后是我的测试:

@Test
public void shouldCallPostMethod() throws Exception {

SignInUserForm signInUserForm = new SignInUserForm("test@mail.com", "aaaaaaaa", "aaaaaaaa");

String json = new Gson().toJson(signInUserForm);

mockMvc.perform(
MockMvcRequestBuilders.post("/user/signup")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(json))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated());
}

就 SignUpControllerForm 包含无参数构造函数而言,一切正常,但是一旦缺少,这就是我从 MockMvcResultHandlers.print() 收到的内容:

MockHttpServletRequest:
HTTP Method = POST
Request URI = /user/signup
Parameters = {}
Headers = {Content-Type=[application/json]}

Handler:
Type = org.bitbucket.akfaz.gui.controller.SignUpController
Method = private java.lang.String org.bitbucket.akfaz.gui.controller.SignUpController.signUpNewUser(org.bitbucket.akfaz.gui.model.SignInUserForm)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
View name = null
View = null
Model = null

FlashMap:

MockHttpServletResponse:
Status = 400
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []

我想表达的是,异常HttpMessageNotReadableException描述性不够。 @RequestBody 不应该有任何异常吗?这会节省很多时间。

Spring 究竟是如何使用无参数构造函数将 JSON 转换为 java 对象(正如我检查的那样,它不使用 getters)?

最佳答案

正如@Sotitios所说,您可以启用调试日志,您可以通过将logback.xml(它也可以是groovy)添加到资源文件夹来实现此目的。这是我的

<configuration>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>logFile.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>logFile.%d{yyyy-MM-dd}.log</FileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>

<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} -
%msg%n</Pattern>
</layout>
</appender>

<root level="DEBUG">
<appender-ref ref="FILE" />
</root>

</configuration>

关于无参数构造函数的问题,您可以创建自己的构造函数并强制 jackson 使用它,我相信这是一个很好的做法,因为您可以更好地控制可变性

@JsonCreator
public UserDto(
@JsonProperty("id") Long id,
@JsonProperty("firstName") String firstName,
@JsonProperty("lastName") String lastName,
@JsonProperty("emailAddress") String emailAddress,
@JsonProperty("active") boolean active,
@JsonProperty("position") String position,
@JsonProperty("pendingDays") Integer pendingDays,
@JsonProperty("taxUid") String taxUid,
@JsonProperty("userName") String userName,
@JsonProperty("approver") boolean approver,
@JsonProperty("startWorkingDate") Date startWorkingDate,
@JsonProperty("birthDate") Date birthDate){

this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.taxUid = taxUid;
this.userName = userName;
this.emailAddress = emailAddress;
this.pendingDays = pendingDays;
this.position = position;
this.active = active;
//this.resourceUrl = resourceUrl;
this.isApprover = approver;
this.birthDate = birthDate;
this.startWorkingDate = startWorkingDate;

}

希望这有帮助

关于java - 为什么@RequestBody不需要arg构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32975715/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com