You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:50:04