http://stackoverflow.com/questions/4917329/return-json-or-view-from-spring-mvc-controller
http://stackoverflow.com/questions/6173093/spring-return-json-from-controller-as-modelandview?lq=1
项目碰到这种场景,方法正常执行时,返回一个view;当执行出错,返回JSON,然后弹框提示。
开始找到了这个方法,但是感觉有点不太好..
然后参考了这里,但是执行过程中总是报错,异常类似如下:
org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.bean.I18nObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.HashMap["i18n"])
at org.codehaus.jackson.map.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:52)
at org.codehaus.jackson.map.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:25)
at org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:262)
at org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:186)
at org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:23)
at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613)
at org.springframework.web.servlet.view.json.MappingJacksonJsonView.writeContent(MappingJacksonJsonView.java:302)
at org.springframework.web.servlet.view.json.MappingJacksonJsonView.renderMergedOutputModel(MappingJacksonJsonView.java:257)
最后,DEBUG发现,项目中添加了拦截器,如果返回view,就向model中添加两个对象,一个是当前用户,一个国际化的对象,而这两个对象,Jackson不知道怎么去转成JSON,所以总是失败。
最后修改拦截器,如果view是MappingJacksonJsonView
,就不向model中添加这两个对象,搞定!
最后的代码如下:
Controller:
@RequestMapping("/ajaxPaymentBatchApproveProcess")
public ModelAndView ajaxPaymentBatchApproveProcess(String packageIds) {
try {
// ....
PaymentApproveResultVo paymentApproveResult = new PaymentApproveResultVo();
ModelAndView mav = new ModelAndView("payment_package_approve_result");
mav.addObject("tagMode", "accountUnitGatherList");
mav.addObject("par", paymentApproveResult);
return mav;
} catch (Exception e) {
log.error("ajaxPaymentBatchApproveProcess method failed, Exception:", e);
ModelAndView mav = new ModelAndView(new MappingJacksonJsonView());
mav.addObject("result", "failed");
return mav;
}
}
JS:
$.ajax({
url: '${ctx}/ajaxPaymentBatchApproveProcess',
type: "post",
data: {packageIds: pids},
success: function (data) {
if(typeof data == 'object' && data.result == 'failed') {
// json
jAlert('error', '出错啦!', '提示');
} else {
// view
$('#paymentBatchApproveResultPopup').html(data);
}
}
});
拦截器:
public class CommonInterceptor extends HandlerInterceptorAdapter {
/**
* 拦截共通处理
* 目前功能主要包含3部分:
* 1:使所有页面支持currentUser的el表达式调用
* 2:使所有页面支持国际化i18n的支持
* 3:清除缓存
*/
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView model)
throws Exception {
if (model != null && !(model.getView() instanceof MappingJacksonJsonView)) {
model.addObject("currentUser",
new PermissionSubject(SecurityUtils.getSubject()));
model.addObject("i18n", new I18nObject((InternationalizationGuiService) CommonHelper
.getSpringService("internationalizationGuiServiceImpl")));
}
response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
response.setHeader("Pragma", "no-cache"); // HTTP 1.0
response.setDateHeader("Expires", -1); // Proxies.
}
}