【发布时间】:2021-10-12 08:09:16
【问题描述】:
我正在做一些练习来熟悉 Spring 框架并使用 REST API。我确实通过了练习,但没有通过我最初的实现。我想知道为什么我在测试中获得 NPE 而在 Postman 中却没有。
在尝试解决此测验时,测试抛出了 NPE:
{
"title": "Math4",
"text": "Which of the following is equal to 4?",
"options": ["2*3", "5*8", "8*0", "1*5"],
"answer": null
}
当我使用 Postman 将此测验发布到 dB 并解决时,一切正常。
但是当我通过测试运行它时,我收到以下信息:
堆栈跟踪:
java.lang.NullPointerException: null
at engine.presentation.controllers.QuizController.solveQuiz(QuizController.java:44) ~[main/:na]
at jdk.internal.reflect.GeneratedMethodAccessor90.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at jdk.internal.reflect.GeneratedMethodAccessor64.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:282) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:279) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:550) ~[na:na]
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:314) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:170) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:225) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:47) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:149) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:145) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.29.jar:9.0.29]
at jdk.internal.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:282) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:279) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:550) ~[na:na]
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:314) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:253) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:191) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:47) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:149) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:145) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at jdk.internal.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:282) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:279) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:550) ~[na:na]
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:314) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:253) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:191) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:47) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:149) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:145) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at jdk.internal.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:282) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:279) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:550) ~[na:na]
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:314) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:253) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:191) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:47) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:149) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:145) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108) ~[spring-boot-actuator-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at jdk.internal.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:282) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:279) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:550) ~[na:na]
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:314) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:253) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:191) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:47) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:149) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:145) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at jdk.internal.reflect.GeneratedMethodAccessor47.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:282) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:279) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:550) ~[na:na]
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:314) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:253) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:191) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:47) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:149) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:145) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.29.jar:9.0.29]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
build.gradle
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'java'
id "io.freefair.lombok" version "6.1.0-m3"
}
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = 11
repositories {
mavenCentral()
}
sourceSets.main.resources.srcDirs = ["src/resources"]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
}
应用程序设置
server.port=8889
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
# H2 data source setup
spring.datasource.url=jdbc:h2:file:../quizdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# Automatically update tables when persistence objects have changed
spring.jpa.hibernate.ddl-auto=update
# Setup for the H2 console, used for viewing data in the database
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false
# Show SQL statements generated by Spring ORM
spring.jpa.show-sql=true
测验.java:
@Entity
@Table(name = "quizzes")
@NoArgsConstructor
@Getter
@Setter
@ToString
@JsonPropertyOrder({
"id",
"title",
"text",
"options"
})
public class Quiz {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private int id;
@NotBlank(message = "Title is required")
private String title;
@NotBlank(message = "Text is required")
private String text;
@NotEmpty(message = "There must be at least 2 options")
@Size(min = 2, message = "There must be at least 2 options")
private LinkedHashSet<String> options;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private HashSet<Integer> answer;
public void setAnswer(HashSet<Integer> answer) {
this.answer = Optional.ofNullable(answer).orElseGet(HashSet::new);
}
}
QuizController.java
@RestController
@RequestMapping("/api")
public class QuizController {
private final QuizService quizService;
@Autowired
public QuizController(QuizService quizService) {
this.quizService = quizService;
}
@GetMapping("/quizzes")
public Iterable<Quiz> getQuizzes() {
return quizService.findAll();
}
@GetMapping("/quizzes/{id}")
public Quiz getQuiz(@PathVariable @Min(0) int id) {
return quizService.findById(id);
}
@PostMapping("/quizzes")
public Quiz saveQuiz(@RequestBody @Valid Quiz quiz) {
return quizService.save(quiz);
}
@PostMapping("/quizzes/{id}/solve")
public Response solveQuiz(@RequestBody @Valid AnswerDto answer,
@PathVariable @Min(0) int id) {
return Response.builder()
.success(quizService.findById(id).getAnswer().equals(answer.getAnswer()))
.build();
}
}
QuizService.java:
@Service
public class QuizService {
private final QuizRepository repository;
@Autowired
public QuizService(QuizRepository repository) {
this.repository = repository;
}
public Iterable<Quiz> findAll() {
return repository.findAll();
}
public Quiz findById(int id) {
Optional<Quiz> quiz = repository.findById(id);
if (quiz.isEmpty()) {
throw new QuizNotFoundException(id);
}
return quiz.get();
}
public Quiz save(Quiz quiz) {
return repository.save(quiz);
}
}
我不明白的是,如果 setAnswer 方法从未将字段设置为空,那么如何使用空答案字段创建测验。根据我的理解,如果我弄错了,请纠正我。当使用@RequestBody 将JSON 反序列化为对象时,它使用默认(无参数)构造函数和定义的setter 方法来实例化对象。另外,为什么我无法在 Postman 上复制问题?
这仅用于教育目的。即使我解决了问题,我也想了解我从哪里开始出错。任何帮助都非常感谢。
编辑:为澄清起见,如果在创建 Quiz 对象时传递了一个空值作为答案,则会创建一个空的 HashSet。这应该反序列化为一个空数组,如上面的邮递员图像所示。当我发布测验的答案时,我收到了成功响应,因为答案是 [];
【问题讨论】:
-
请同时发布测试。似乎
QuizService没有自动连接到QuizController。 -
测试是从第 3 方生成的,除了在调用方法时将一些语句打印到控制台之外,我无权访问正在运行的测试。我确实编辑了我的帖子并添加了 QuizService 类。我有通过构造函数自动装配的存储库,以及通过 QuizController 类的构造函数自动装配的服务。有错吗?
-
构造函数注入非常好。我想说,与现场注入相比,它甚至是更先进的方法。从堆栈跟踪中不清楚哪个变量是
null。如果它在本地运行但不在测试中,我的第一个猜测是quizService。但也可能是第一个quizService.findById(id).getAnswer()的返回值。没有看到测试设置,很难说。 -
@hpoettker 方法返回测验或抛出异常
public Quiz findById(int id) { Optional<Quiz> quiz = repository.findById(id); if (quiz.isEmpty()) { throw new QuizNotFoundException(id); } return quiz.get(); } -
@hpoeeker 我在solveQuiz 上打印到控制台Quiz 对象。
Quiz(id=6, title=Math4, text=Which of the following is equal to 4?, options=[2*3, 5*8, 8*0, 1*5], answer=null) 2021-08-08 10:26:48.784 ERROR 4840 --- [io-8889-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
标签: spring-boot rest jpa nullpointerexception crud