Spring boot @ExceptionHandler 将响应返回为 html

Posted

技术标签:

【中文标题】Spring boot @ExceptionHandler 将响应返回为 html【英文标题】:Spring boot @ExceptionHandler return the response as html 【发布时间】:2018-11-07 07:03:58 【问题描述】:

我对 Spring boot 更感兴趣当抛出异常时,我得到 html 的响应,而我需要它作为 JSON。

服务响应

HTTP/1.1 500
Content-Type: text/html;charset=UTF-8
Content-Language: en-US
Content-Length: 345
Date: Mon, 28 May 2018 16:13:06 GMT
Connection: close

<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Mon May 28 19:13:06 EEST 2018</div><div>There was an unexpected error (type=Internal Server Error, status=500).</div><div>The environment must be QAT2,PSQA or DEVSTAGE4</div></body></html>

这是异常环境必须是 QAT2、PSQA 或 DEVSTAGE4 我需要它作为 JSON 响应,而无需编写自定义异常处理程序类,如下所示:


   "timestamp" : 1413313361387,
   "exception" : "java.lang.IllegalArgumentException",
   "status" : 500,
   "error" : "internal server error",
   "path" : "/greet",
   "message" : "The environment must be QAT2,PSQA or DEVSTAGE4"

它之前按预期工作,但我对此做了一些更改 控制器

package main.controller;

@RestController
@RequestMapping("/api")
public class API 

private final APIService apiService;

@Autowired
public API(APIService offersService) this.apiService = offersService;

@ExceptionHandler(IllegalArgumentException.class)
void handleIllegalStateException(IllegalArgumentException e, HttpServletResponse response) throws IOException 
    response.sendError(HttpStatus.FORBIDDEN.value());


@PostMapping(value = "/createMember", produces = "application/json")
public ResponseEntity createMembers(@Valid @RequestBody APIModel requestBody) throws IllegalArgumentException 
    validatePrams();
    apiService.fillMembersData();
    return ResponseEntity.ok(HttpStatus.OK);


private void validatePrams() throws IllegalArgumentException 
    if (APIModel.getEnvironment() == null || (!APIModel.getEnvironment().equalsIgnoreCase("QAT2")
            && !APIModel.getEnvironment().equalsIgnoreCase("PSQA")
            && !APIModel.getEnvironment().equalsIgnoreCase("DEVSTAGE4"))) 
        throw new IllegalArgumentException("The environment must be QAT2,PSQA or DEVSTAGE4");
    


型号

package main.model;

@Entity
@Table(name = "APIModel")
public class APIModel 

    @Id
    @Column(name = "environment", nullable = false)
    @NotNull
    private static String environment;

    @Column(name = "country", nullable = false)
    @NotNull
    private static String country;

    @Column(name = "emailTo", nullable = false)
    @NotNull
    private static String emailTo;

    @Column(name = "plan", nullable = false)
    @NotNull
    private static String plan;

    @Column(name = "paymentType", nullable = false)
    @NotNull
    private static String paymentType;

    @Column(name = "numberOfUsers", nullable = false)
    @NotNull
    private static Integer numberOfUsers;

    @Column(name = "program")
    private static String program;

    public APIModel(String environment, String country, String emailTo, String plan, String paymentType, Integer numberOfUsers, String program) 
        APIModel.environment = environment;
        APIModel.country = country;
        APIModel.emailTo = emailTo;
        APIModel.plan = plan;
        APIModel.paymentType = paymentType;
        APIModel.numberOfUsers = numberOfUsers;
        APIModel.program = program;
    

    public APIModel() 

    public static String getEnvironment() return environment;

    public void setEnvironment(String environment) APIModel.environment = environment;

    public static String getCountry() return country;

    public static String getEmailTo() return emailTo;

    public static String getPlan() return plan;

    public static String getPaymentType() return paymentType;

    public static Integer getNumberOfUsers() return numberOfUsers;

    public static String getProgram() return program;

    public void setProgram(String program) APIModel.program = program;

应用程序

package main;

@SpringBootApplication
public class MainClass 

    static 
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd'/'hh_mm_ss");
        System.setProperty("current.date.time", dateFormat.format(new Date()));
        System.setProperty("usr_dir", System.getProperty("user.dir") + "\\src\\logs");
    

    public static void main(String[] args) 
        SpringApplication.run(MainClass.class, args);
    

【问题讨论】:

尝试使用此代码response.sendError(HttpStatus.BAD_REQUEST) 而不是response.sendError(HttpStatus.BAD_REQUEST.value()) @Generic 这也不起作用,我在控制台中遇到了异常,但仍然不是同样的问题。 【参考方案1】:

从上面的类范围中删除 @ResponseBody 并注意它们的 url 值应该以 '/' 开头,而不仅仅是输入 url,而不是输入

@RequestMapping(value = "createMember", method = RequestMethod.POST)

这应该是

@RequestMapping(value = "/createMember", method = RequestMethod.POST)

或者如果你像下面这样直接用帖子注释它会更好

@PostMapping(value = "/createMember")

GETPUT 等是一样的

【讨论】:

【参考方案2】:

您的处理程序仅捕获 IllegalStateException 而不是抛出的 IllegalArgumentException:

   @ExceptionHandler(IllegalStateException.class)
    void handleIllegalStateException(IllegalStateException e, HttpServletResponse response) throws IOException 
        response.sendError(HttpStatus.BAD_REQUEST.value());
    

这些都是 RuntimeExceptions。要在同一个处理程序中捕获两者,您可以尝试将其替换为:

   @ExceptionHandler(RuntimeException.class)
    void handleIllegalStateException(IllegalStateException e, HttpServletResponse response) throws IOException 
        response.sendError(HttpStatus.BAD_REQUEST.value());
    

实际上,这将捕获此控制器抛出的所有 RuntimeExceptions。

【讨论】:

还是同样的问题,控制器确实捕获了异常,但他将错误作为 HTML 返回,我可以在响应中看到异常,但我需要它作为 json 看看这是否有帮助:@RequestMapping(value = "createMember", method = RequestMethod.POST,produces = "application/json")

以上是关于Spring boot @ExceptionHandler 将响应返回为 html的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 学习例子

Spring Boot 2Spring Boot CLI

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot