将异常消息包含在JSON错误响应中。

huangapple go评论96阅读模式
英文:

Include exception message in JSON error response

问题

如果电子邮件地址已存在,则抛出异常并附带消息("消息:" + tempEmailId + "的用户已存在")。当我在Postman中进行测试时,我无法获取异常消息。你能帮我解决一下吗?问题出在哪里?

控制器类:

  1. @RestController
  2. public class RegistrationController {
  3. @Autowired
  4. private RegistrationService service;
  5. @PostMapping("/registeruser")
  6. public User registerUser(@RequestBody User user) throws Exception {
  7. String tempEmailId = user.getEmailId();
  8. if (tempEmailId != null && !"".equals(tempEmailId)) {
  9. User userObject = service.fetchUserByEmailId(tempEmailId);
  10. if (userObject != null) {
  11. throw new Exception("用户" + tempEmailId + "已存在");
  12. }
  13. }
  14. User userObject = null;
  15. userObject = service.saveUser(user);
  16. return userObject;
  17. }
  18. }

存储库:

  1. public interface RegistrationRepository extends JpaRepository<User, Integer> {
  2. public User findByEmailId(String emailId); // 在这里声明
  3. }

服务:

  1. @Service
  2. public class RegistrationService {
  3. @Autowired
  4. private RegistrationRepository repo;
  5. public User saveUser(User user) {
  6. return repo.save(user);
  7. }
  8. public User fetchUserByEmailId(String email) {
  9. return repo.findByEmailId(email);
  10. }
  11. }
英文:

If email address already exists then throw an exception with a message("message:"User with "+tempEmailId+" already exists"). I don't get my exception message when I test in postman. Can you please help me ? Where is the issue? 将异常消息包含在JSON错误响应中。

Controller class:

  1. @RestController
  2. public class RegistrationController {
  3. @Autowired
  4. private RegistrationService service;
  5. @PostMapping(&quot;/registeruser&quot;)
  6. public User registerUser(@RequestBody User user) throws Exception {
  7. String tempEmailId = user.getEmailId();
  8. if(tempEmailId !=null &amp;&amp; !&quot;&quot;.equals(tempEmailId)) {
  9. User userObject = service.fetchUserByEmailId(tempEmailId);
  10. if(userObject!=null) {
  11. throw new Exception(&quot;User with &quot;+tempEmailId+&quot; is already exist&quot;);
  12. }
  13. }
  14. User userObject = null;
  15. userObject = service.saveUser(user);
  16. return userObject;
  17. }
  18. }

Repository:

  1. public interface RegistrationRepository extends JpaRepository&lt;User, Integer&gt; {
  2. public User findByEmailId(String emailId); // Here we declare
  3. }

Service:

  1. @Service
  2. public class RegistrationService {
  3. @Autowired
  4. private RegistrationRepository repo;
  5. public User saveUser(User user) {
  6. return repo.save(user);
  7. }
  8. public User fetchUserByEmailId(String email) {
  9. return repo.findByEmailId(email);
  10. }
  11. }

答案1

得分: 6

如果您使用的是Spring Boot 2.3版本或更高版本,则必须将属性server.error.include-message设置为always

摘自Spring Boot 2.3发布说明

默认错误页面内容的更改

默认情况下,错误消息和任何绑定错误不再包含在默认错误页面中。这减少了向客户端泄露信息的风险。server.error.include-messageserver.error.include-binding-errors可用于控制是否包含消息和绑定错误。支持的值为alwayson-paramnever

英文:

If you are using Spring Boot version 2.3 or higher, the property server.error.include-message must be set to always:

Quoted from Spring Boot 2.3 Release Notes:

> Changes to the Default Error Page’s Content
>
> The error message and any binding errors are no longer included in the default error page by default. This reduces the risk of leaking information to a client. server.error.include-message and server.error.include-binding-errors can be used to control the inclusion of the message and binding errors respectively. Supported values are always, on-param, and never.

答案2

得分: 0

你可以将你的控制器响应包装为 ResponseEntity

  1. @PostMapping("/registeruser")
  2. public ResponseEntity<Object> registerUser(@RequestBody User user) throws Exception {
  3. String tempEmailId = user.getEmailId();
  4. if (tempEmailId != null && !tempEmailId.isEmpty()) {
  5. User userObject = service.fetchUserByEmailId(tempEmailId);
  6. if (userObject != null) {
  7. return new ResponseEntity<>("用户 " + tempEmailId + " 已存在", HttpStatus.BAD_REQUEST);
  8. }
  9. }
  10. return new ResponseEntity<>(service.saveUser(user), HttpStatus.OK);
  11. }

或者(更可取的方式)你可以创建一个特定的异常,比如 UserAlreadyExistException,在控制器中抛出它,并在带有 @RestControllerAdvice 注解的类中拦截它。
例如:

  1. @RestControllerAdvice
  2. public class RegistrationControllerAdvice {
  3. @ExceptionHandler({UserAlreadyExistException.class})
  4. @ResponseStatus(HttpStatus.BAD_REQUEST)
  5. public String userAlreadyExist(UserAlreadyExistException ex, WebRequest req) {
  6. return ex.getMessage();
  7. }
  8. }

你可以返回任何可序列化为 JSON 的数据结构,而不仅仅是字符串。

英文:

You can wrap your controller responses to ResponseEntity.

  1. @PostMapping(&quot;/registeruser&quot;)
  2. public ResponseEntity&lt;Object&gt; registerUser(@RequestBody User user) throws Exception {
  3. String tempEmailId = user.getEmailId();
  4. if(tempEmailId != null &amp;&amp; !tempEmailId.isEmpty()) {
  5. User userObject = service.fetchUserByEmailId(tempEmailId);
  6. if(userObject!=null) {
  7. return new ResponseEntity&lt;&gt;(&quot;User with &quot;+tempEmailId+&quot; is already exist&quot;, HttpStatus.BAD_REQUEST);
  8. }
  9. }
  10. return new ResponseEntity&lt;&gt;(service.saveUser(user), HttpStatus.OK);
  11. }

Or (preferable variant) your can create specific exception, for example UserAlreadyExistException, throw it in controller and intercept in class annotated with @RestControllerAdvice.
For example:

  1. @RestControllerAdvice
  2. public class RegistrationControllerAdvice {
  3. @ExceptionHandler({UserAlreadyExistException.class})
  4. @ResponseStatus(HttpStatus.BAD_REQUEST)
  5. public String userAlreadyExist(UserAlreadyExistException ex, WebRequest req) {
  6. return ex.getMessage();
  7. }
  8. }

Instead of String you can return any data structure serializable to JSON.

huangapple
  • 本文由 发表于 2020年9月9日 16:14:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63807464.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定