Spring Boot异常返回HTML而非JSON问题求助(无需自定义处理器)
解决Spring Boot异常返回白标HTML而非JSON的问题
首先咱们直接定位核心问题,再一步步给出解决方案:
1. 问题根源分析
- 异常处理器写法错误:你当前Controller里的
@ExceptionHandler用了response.sendError(),这会触发Spring Boot内置的/error端点默认逻辑,直接返回白标错误页,而且你设置的403状态码也和目标的500响应不匹配。 - Model类存在致命隐患:你的
APIModel所有字段都用了static修饰,这完全违背JPA实体的设计原则——static字段属于类而非实例,会导致多请求共享同一字段值,在Web多线程环境下必然出现数据混乱,这很可能是你“此前正常、改代码后出问题”的核心原因。
解决方案(无需额外编写全局异常处理器类)
第一步:修复APIModel的static字段问题
把所有字段的static修饰符去掉,getter/setter改为实例方法,构造函数使用实例变量,同时补上之前缺失的setter(否则Spring无法绑定请求体):
package main.model; import javax.persistence.*; import javax.validation.constraints.NotNull; @Entity @Table(name = "APIModel") public class APIModel { @Id @Column(name = "environment", nullable = false) @NotNull private String environment; @Column(name = "country", nullable = false) @NotNull private String country; @Column(name = "emailTo", nullable = false) @NotNull private String emailTo; @Column(name = "plan", nullable = false) @NotNull private String plan; @Column(name = "paymentType", nullable = false) @NotNull private String paymentType; @Column(name = "numberOfUsers", nullable = false) @NotNull private Integer numberOfUsers; @Column(name = "program") private String program; public APIModel(String environment, String country, String emailTo, String plan, String paymentType, Integer numberOfUsers, String program) { this.environment = environment; this.country = country; this.emailTo = emailTo; this.plan = plan; this.paymentType = paymentType; this.numberOfUsers = numberOfUsers; this.program = program; } public APIModel() {} public String getEnvironment() {return environment;} public void setEnvironment(String environment) {this.environment = environment;} public String getCountry() {return country;} public void setCountry(String country) {this.country = country;} public String getEmailTo() {return emailTo;} public void setEmailTo(String emailTo) {this.emailTo = emailTo;} public String getPlan() {return plan;} public void setPlan(String plan) {this.plan = plan;} public String getPaymentType() {return paymentType;} public void setPaymentType(String paymentType) {this.paymentType = paymentType;} public Integer getNumberOfUsers() {return numberOfUsers;} public void setNumberOfUsers(Integer numberOfUsers) {this.numberOfUsers = numberOfUsers;} public String getProgram() {return program;} public void setProgram(String program) {this.program = program;} }
第二步:修改Controller的异常处理器与验证逻辑
把原来的void返回改为直接返回JSON结构的ResponseEntity,同时调整验证方法(现在字段是实例变量,需要传入请求体实例):
package main.controller; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/api") public class API { private final APIService apiService; @Autowired public API(APIService offersService) { this.apiService = offersService; } // 修改后的异常处理器,直接返回目标JSON格式 @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity<Map<String, Object>> handleIllegalArgumentException(IllegalArgumentException e, HttpServletRequest request) { Map<String, Object> errorResponse = new HashMap<>(); errorResponse.put("timestamp", System.currentTimeMillis()); errorResponse.put("exception", e.getClass().getName()); errorResponse.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value()); errorResponse.put("error", "internal server error"); errorResponse.put("path", request.getRequestURI()); errorResponse.put("message", e.getMessage()); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } @PostMapping(value = "/createMember", produces = "application/json") public ResponseEntity createMembers(@Valid @RequestBody APIModel requestBody) throws IllegalArgumentException { validateParams(requestBody); apiService.fillMembersData(); return ResponseEntity.ok(HttpStatus.OK); } // 调整验证方法,传入APIModel实例获取环境值 private void validateParams(APIModel requestBody) throws IllegalArgumentException { String env = requestBody.getEnvironment(); if (env == null || (!env.equalsIgnoreCase("QAT2") && !env.equalsIgnoreCase("PSQA") && !env.equalsIgnoreCase("DEVSTAGE4"))) { throw new IllegalArgumentException("The environment must be QAT2,PSQA or DEVSTAGE4"); } } }
验证效果
修改完成后,触发IllegalArgumentException时,接口会返回你期望的JSON响应:
{ "timestamp" : 1413313361387, "exception" : "java.lang.IllegalArgumentException", "status" : 500, "error" : "internal server error", "path" : "/api/createMember", "message" : "The environment must be QAT2,PSQA or DEVSTAGE4" }
内容的提问来源于stack exchange,提问作者Mohamed-Sabbagh
相关产品推荐
相关产品推荐

