在JSON反序列化期间抛出自定义错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在JSON反序列化期间抛出自定义错误相关的知识,希望对你有一定的参考价值。

我有以下POJO:

@Entity // This tells Hibernate to make a table out of this class
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;


    private String name;

    private String email;

    private String username;

    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) throws DataFormatException {
        if(name.equals(""))
        {
            throw new DataFormatException("Mpla Mpla");
        }
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {

        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @JsonCreator
    public User(@JsonProperty("name") String name, @JsonProperty("email") String email,@JsonProperty("username") String username,@JsonProperty("password") String password) throws DataFormatException {
        setName(name);
        this.email = email;
        this.username = username;
        this.password = password;
}
    } 

以下控制器:

public class MainController {
    @Autowired // This means to get the bean called userRepository
    // Which is auto-generated by Spring, we will use it to handle the data
    private UserRepository userRepository;
    }
    @PostMapping(path="/add") // Map ONLY POST Requests
    public @ResponseBody String addNewUser (@RequestBody @Valid User user1) {
        // @ResponseBody means the returned String is the response, not a view name

        userRepository.save(user1);
        return "Saved";
    }

    @GetMapping(path="/all")
    public @ResponseBody Iterable<User> getAllUsers() {
        // This returns a JSON or XML with the users
        return userRepository.findAll();
    }

问题是,它不会产生错误DataFormatException,而是产生:

"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
    "message": "JSON parse error: Can not construct instance of hello.Users.User, problem: Mpla Mpla; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of hello.Users.User, problem: Mpla Mpla
 at [Source: java.io.PushbackInputStream@7604dc21; line: 6, column: 1]",

虽然从上面可以看出问题是正确的但是消息是错误的。那么,为了产生想要的错误而不是杰克逊产生的错误,可以做些什么呢?

答案

在控制器中使用以下代码。

@RequestMapping(value = "/user/register", method = RequestMethod.POST)
    public SecurityToken register(@RequestBody @Valid SecurityUser user, BindingResult result) {
        List<ObjectError> st = result.getAllErrors();
        String errorFields = "";
        for (ObjectError error : st) {
            errorFields = errorFields + error.getDefaultMessage();
        }
        if (!errorFields.equals("")) {
            throw new CustomException(errorFields);
        }
        return service.register(user);
    }

您可以将字段的注释用作:

import org.hibernate.validator.constraints.NotEmpty;

public class SecurityUser {

    @NotEmpty(message = "Email id is mandatory.")
    private String emailId;

对于异常处理,您可以在Spring控制器或ControllerAdvice中使用HandlerMethod。

@ControllerAdvice
public class SecurityControllerAdvice {

    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public CustomResponse handleSecurityException(CustomException se) {
        CustomResponse response = new CustomResponse(se.getMessage());
        return response;
    }
}

以上是关于在JSON反序列化期间抛出自定义错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ajax(Post) 请求期间抛出自定义 http 状态码

在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数

MVC抛出自定义异常,并易Json方式返回

如果受 hystrix 保护的调用超时,我可以抛出自定义错误吗?

为 Jackson 自定义反序列化程序抛出带有 HTTP 状态代码的自定义异常

如何在 JSON 反序列化期间将引用转换为实例