2013-07-04 57 views
1

我在使用Spring和Jackson生成正确的错误消息时遇到了问题。方案:具有自定义模型的控制器@ResponseBody(参见下文)具有两个属性的模型,可能导致解析错误。现在,如果解析这些字段失败(例如,获取Date的无效字符串),我想返回适当的错误消息。使用Spring和Jackson处理错误

如果发生解析错误,Spring将捕获它并返回一个带有HTML主体的400 Bad Request响应。尽管我能够实现我自己的HandlerExceptionResolver,但它捕获了这种异常以生成有意义的错误消息。不幸的是,我只能捕获第一个解析错误,而不是第二个解析错误。

那么,有没有一种方法来收集所有的解析/反序列化错误,并生成一个适当的错误消息与所有问题?

我使用的是Jackson 1.7.1和Spring 3.2.2。


一些示例代码:

TimeController.java

@Controller 
@RequestMapping("/time") 
public class TimeController { 
    @RequestMapping(method = RequestMethod.POST) 
    public @ResponseBody 
    TimeDocument create(@RequestBody TimeDocument entity) { 
     // magic 
     return entity; 
    } 
} 

TimeDocument.java

public class TimeDocument { 
    public String name; 
    public Date date1; 
    public Date date2; 
} 

索取1:我会得到一个200 OK

{ 
    "name": "test", 
    "date1": 123, 
    "date2": 1234 
} 

请求2:我会得到一个400 Bad Request,但我能够生成正确的错误信息,如:“日期1格式无效”。

{ 
    "name": "test", 
    "date1": "crap", 
    "date2": 1234 
} 

请求3:我会得到一个400 Bad Request,但我不能够产生像一个真正的错误信息:“日期1格式无效日期2格式无效。”。

{ 
    "name": "test", 
    "date1": "crap", 
    "date2": "crap" 
} 
+0

由于我没有找到足够的解决方案,但是,我会找到另一种方式解决我的问题。 (例如,第二个客户端验证) – svenwltr

回答

0

好吧,我想你会更好需要使用Spring MVC Form Validation或者只是在使用jquery.validate插件客户端验证input值(我只是假设你使用,因为jQuery@ResponseBody使用)。

否则,来到我的脑海另一个解决方案是实现这样的:

(首先,在你的entity添加对新field一个gettersetter称为message将存储验证结果)。

然后:现在

@Controller 
@RequestMapping("/time") 
public class TimeController { 
    @RequestMapping(method = RequestMethod.POST) 
    public @ResponseBody String create(@RequestBody TimeDocument entity) { 

     String json = null;   

     try { 

      //1. Create 'jackson' object mapper 
      ObjectMapper objectMapper = new ObjectMapper(); 

      //2. Capture data from your entity 
      String name = entity.getName(); 
      Date date1 = entity.getDate1(); 
      Date date2 = entity.getDate2(); 

      //3. Validate 'name', 'date1', 'date2' with some regex (a possibility) or any method you want. 

      //4. Suppossing that you implemented a method like this to validate your 'bean' or 'dto' that returns 'boolean' 
      if(!validate(entity)) { 

       //5. If everything is not according to your validation rules, set a message to your entity. 
       entity.setMessage("There was an error in the input values."); 
      } 

      //6. Convert your 'bean' or 'dto' as 'json' string 
      json = objectMapper.writeValueAsString(entity);    

     } catch (Exception ex) { 
      //handle the Exception 
     } 

     return json; 
    } 
} 

,在客户端(suppossing您使用jQueryajax或只是$.post)。

不要在callback如下:

(..), function(data) { 
    if(data != null) { //Callback is not null 

     //Parse the 'String' result from 'Controller' as 'JSON' from 'Jackson' 
     var obj = $.parseJSON(data); 

     if(obj.message != '') { 
     alert(obj.message) //An error ocurred in the validation. 
     } else { 
     //Show the data 
     alert('Name: ' + obj.name + ' Date1: ' + obj.date1 + ' Date2: ' + obj.date2); 
     } 
    } 
}); 

所以,如果没有message存在于entity,这意味着没有error存在。我会提出这个建议,并且考虑我在第一行写的是在clientserver方面有非常好的验证。

+0

这可能是一个想法,但它看起来像黑客攻击。虽然,我会玩这个想法。 – svenwltr

+0

@SvenWalter好吧,让我知道它是怎么回事,如果你认为这是你的答案,不要忘记检查它。 –