【问题标题】:Spring MVC rollback with custom message带有自定义消息的 Spring MVC 回滚
【发布时间】:2016-03-21 14:49:53
【问题描述】:

我有一个 Spring MVC 服务方法来执行 save() 和 update() - 两个操作。

save()执行成功后,如果发现要更新的用户不存在,我会手动抛出一个新的RuntimeExceotion()来回滚保存操作。在这种情况下,如何将错误消息(“找不到用户”)返回到浏览器端?

@Transactional(rollbackFor = { Exception.class })
public Map<String,Object> service(){
    Map<String,Object> map = new HashMap<String,Object>();
    //1. save user
    User user = getUser();
    this.save(user);

    //2. try to update another
    String anotherUserId = "anUserId";
    User anUser = this.getById(anotherUserId);
    if(anUser != null){
        anUser.setName("newName");
        this.update(anUser);
        map.put("status",true);
    }else{
        //logical error
        map.put("status",false);
        map.put("err_msg","cant find the user for update");        

        //triger rollback(rollback save user)
        throw new RuntimeException("update user error");
    }
    return map;
}

【问题讨论】:

    标签: spring-mvc spring-transactions


    【解决方案1】:

    为什么不将错误包装在一个对象中,并在抛出它时将其传递给异常。

    稍后在控制器/请求-响应处理程序层,从异常中获取错误对象并将其传递给 UI 层。

    Class CustomException extends Exception {
    
        Map<String,Object> errorMap;
    
        public CustomException(String errorMsg, Map errorMap)
        {
            super(errorMsg);
            this.errorMap = errorMap;
        }
        public CustomException(Throwable cause){
            super(cause);
        }
    
        public CustomException(String message ,Throwable cause){
            super(message,cause);
        }
    }
    

    在抛出异常时:

    throw new CustomException("Can not find the user", map);
    

    在 Controller 端,捕获这个异常并提取包含您的数据的 ErrorMap。 包装/转换此对象并将其传递给 UI/浏览器。

    【讨论】:

    • 真的很感激!它工作得很好,我没有想过在向 SpringTransactional 抛出异常后做些什么。
    【解决方案2】:

    您可以添加一个包含错误消息的CustomException 类。

    您可以将错误消息发送回您的客户。为此,您可以使您的服务返回类型为 Object,这就是它可以发送 MapErrorMessage 的原因。

    CustomException 类看起来像这样:

    public class CustomException extends Exception implements Serializable {
    
        public CustomException(String errorMsg)
        {
            super(errorMsg);
        }
        public CustomException(Throwable cause){
            super(cause);
        }
    
        public CustomException(String message ,Throwable cause){
            super(message,cause);
        }
    }
    

    您可以通过以下方式使用它:

    throw new CustomException("Can not find the user");
    

    【讨论】:

    • 谢谢你的帮助,可能我表达的不好。当我抛出异常(RuntimeException 或像您所说的 CustomException)时,Spring MVC 将接管它,并执行回滚操作,并且我的“返回 obj;”不会被执行。如果我抛出异常,浏览器端(ajax 调用),如何获取 Object?
    • 您可以使您的对象可序列化以通过网络发送。 public class CustomException extends Exception implements Serializable{}
    • 我按照@Bandi Kishore 的建议解决了这个问题,在控制器方法中,try{service();}catch(CustomException e){map = e.getErrorMap();}。通过 try-catch 块,在 SpringTransactional 回滚完成后,会将这个异常抛出到我的控制器方法中。然后我可以继续错误消息句柄。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 2011-08-20
    • 2019-04-21
    • 2021-03-25
    • 2015-04-10
    • 2015-03-01
    • 2014-02-04
    相关资源
    最近更新 更多