简体   繁体   English

Java 和 Spring 启动:抛出异常,返回特定的 HTTP 代码给客户端

[英]Java with Spring Boot: Throw an exception that returns a specific HTTP code to the client

I am developing a web application using Java and Spring Boot.我正在使用 Java 和 Spring 引导开发 web 应用程序。 Specifically, I am reviewing some code written by other developers.具体来说,我正在审查其他开发人员编写的一些代码。 I use Postman to make HTTP calls to my application.我使用Postman对我的应用程序进行 HTTP 调用。 There are cases where my application needs to inform the caller of certain situations.在某些情况下,我的应用程序需要通知调用者某些情况。 In this example, the developer of the application threw a JwtTokenException to the caller in case of IOException .在此示例中,应用程序的开发人员在IOException的情况下向调用者抛出了JwtTokenException

try {
    myToken = methodThatObtainsAToken(tokenInput);
}catch(IOException ex) {
    throw new JwtTokenException("Error 401", JwtStatusResponse.JWT_NOT_VALID); // TODO: cambiare
}

When something goes wrong here is what happens on POSTMAN:当出现问题时,POSTMAN 上会发生什么: 在此处输入图像描述

I have so many other very similar situations in this code and I have to do the following thing: I have to replace the code throw new JwtTokenException so that it throws exceptions that make the caller understand (so I can see them with Postman) that an HTTP error has occurred (with some code).我在这段代码中有很多其他非常相似的情况,我必须做以下事情:我必须替换代码throw new JwtTokenException以便它抛出使调用者理解的异常(所以我可以Postman 看到它们)发生 HTTP 错误(带有一些代码)。 In the example I wrote I wrote "Error 401" only as a string.在我编写的示例中,我仅将“Error 401”写为字符串。 There are other places in the code where I use "Error 500", "Error 302" and so on.. But these are just information strings, and do not correspond to the real error thrown to the client.代码中还有其他地方我使用了“Error 500”、“Error 302”等。但这些只是信息字符串,与抛出给客户端的真正错误并不对应。 How do I throw correct exceptions that raise "HTTP errors"?如何抛出引发“HTTP 错误”的正确异常?

One usually returns response entity with body object and status set to provide interesting information:一个通常返回带有正文 object 和状态集的响应实体以提供有趣的信息:

        return ResponseEntity.ok()
        .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, trackDTO.getId().toString()))
        .body(result);

Response Entity is org.springframework.http.ResponseEntotuy which provides a lot of convenience methods to setup all the headers and whatever is necessary.响应实体是 org.springframework.http.ResponseEntotuy,它提供了许多方便的方法来设置所有标题和任何必要的东西。

If most of the exceptions are handled like in code you have posted and you don't want to change return types of methods, just replace them with如果大多数异常都像您发布的代码一样处理并且您不想更改方法的返回类型,只需将它们替换为

catch(Exception e){   
    throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}

which will give the following output这将给出以下 output

{
    "timestamp": "2021-03-10T09:25:04.823+0000",
    "status": 404,
    "error": "Not Found",
    "message": "Not Found",
    "path": "/account"
}

if you'd like to get exception info just add如果您想获取异常信息,只需添加

catch(Exception e){   
    throw new ResponseStatusException(HttpStatus.NOT_FOUND,null, e);
}

response:回复:

{
    ...
    "message": "404 NOT_FOUND; nested exception is java.lang.ArithmeticException",
    ...
}

note that it will be logged if you didn't declare your own exception resolver请注意,如果您没有声明自己的异常解析器,它将被记录

 2021-03-10 15:28:20.043  WARN 11392 --- [nio-8090-exec-2] .w.s.m.a.ResponseStatusExceptionResolver : Resolved [org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND "Not Found"; nested exception is java.lang.ArithmeticException]

Instead of null you could pass a string describing exception, which will replace "message" in json response.您可以传递一个描述异常的字符串,而不是 null,它将替换 json 响应中的“消息”。

From your attached screenshot.从您附加的屏幕截图中。 Your application returned 401 Unauthorized.您的应用程序返回 401 Unauthorized。 I think you no longer need to pass the error code since you get it from the response itself.我认为您不再需要传递错误代码,因为您是从响应本身获取的。 Exceptions do not return Http Status Code and you as a developer is responsible to telling your app which error code to return.异常不会返回 Http 状态代码,您作为开发人员有责任告诉您的应用程序返回哪个错误代码。 For example in your RestController例如在你的 RestController

@GetMapping(path = "{id}")
public ResponseEntity<ResponseModel> getEmployee(@PathVariable("id") String id) {
    ResponseModel result = employeeService.findById(id);
    return new ResponseEntity<>(result, HttpStatus.OK); // <--- THIS
}

And in your custom exception handler, you can do it like this.在您的自定义异常处理程序中,您可以这样做。

NOTE: This triggers when you call from your Jwt Verifier Filter注意:当您从 Jwt 验证程序过滤器调用时会触发此事件

@ExceptionHandler(value = ExpiredJwtException.class)
public ResponseEntity<Object> handleExpiredJwt(ExpiredJwtException e) {
    ApiException apiException = new ApiException(e.getLocalizedMessage(), HttpStatus.UNAUTHORIZED);
    return new ResponseEntity<>(apiException, UNAUTHORIZED);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Web 客户端中,返回包含 Body 和 Http 状态码的 ResponseEntity(成功和失败) JAVA spring boot - In Web Client, returning ResponseEntity containing both Body and Http Status Code(both success and failure) JAVA spring boot Spring 启动:返回 HTTP 响应代码 400,嵌套异常为 java.ZF98ED07A4D5F50F4F770Exception - Spring Boot: returned HTTP response code 400, nested exception is java.io.IOException 我的Spring Boot服务器返回406 Http错误代码 - My Spring Boot server returns 406 Http error code Spring 引导 - 抛出异常或指示未找到项目 - Spring Boot - throw exception or indicate item is not found 如何在 Spring Boot 的 JSON 中抛出异常 - How to throw an exception back in JSON in Spring Boot Spring Boot 应用程序中的自定义异常抛出 - Custom Exception throw in Spring Boot Application Spring Boot自定义HTTP EXCEPTION - Spring Boot Custom HTTP EXCEPTION 具有隔离的客户端特定隔离的Spring Boot多租户代码 - Spring boot multi tenant Code with isolated client specific isolation 如果返回 http 客户端/服务器错误,我们应该记录还是抛出异常? - Java, SpringBoot - If http client/server error is returned should we log or throw exception? - Java, SpringBoot 在 Java Spring Boot 中创建并返回自定义 Http 响应代码 - Create and Return a custom Http response code in Java Spring Boot
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM