springmvc rest框架搭建中遇到的问题(二)

接上篇,又遇到了新的问题

3.bean to xml显示的xml不是我往ModelAndView中塞的bean

怎么说呢,

Task task = taskManager.getTaskById(id);

ModelAndView result = new ModelAndView();

result.addObject("task",task);

结果应该是这样的。。。

<task>
<taskname>任务查询</taskname>
<priority>1</priority>
<startdate>2010-10-13 08:30:43</startdate>
</task>

但实际上,却是

<bean-property-binding-result field-error-count="0" global-error-count="0" error-count="0">

...

而demo里是好的啊,我怎么就出问题了呢。。。

调试了spring源代码,在model的map中发现,spring转的bean不是我塞进去的Task对象,而是BindingResult.task,如下:

{org.springframework.validation.BindingResult.task=org.springframework.validation.BeanPropertyBindingResult: 0 errors, task=com.css.pms.demo.entity.Task@1b1dfe5}

 

我要调试了下rapdi的demo,发现它的model里面的map和我一样啊,为啥它取出来的却是正确的呢?

rapid代码

ModelAndView result = new ModelAndView();

result.addObject("userinfo",userinfo);

{userInfo=com.company.project.model.UserInfo@7da18e[UserId=1,Username=badqiu,Password=123,BirthDate=<null>,Sex=1,Age=2], org.springframework.validation.BindingResult.userInfo=org.springframework.validation.BeanPropertyBindingResult: 0 errors}

 

在spring源代码处终于发现了问题所在

 在AnnotationMethodHandlerAdapter类的getModelAndView方法中 

    ModelAndView mav = (ModelAndView) returnValue;//这里的mav中的ModelMap是个LinkedHashMap
    mav.getModelMap().mergeAttributes(implicitModel);

 

   但是随后的,AbstractView的public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)方法

 Map<String, Object> mergedModel =
    new HashMap<String, Object>(this.staticAttributes.size() + (model != null ? model.size() : 0));
  mergedModel.putAll(this.staticAttributes);
  if (model != null) {
   mergedModel.putAll(model);
  }

这里又变成了普通的HashMap

 

 在MarshallingView中的locateToBeMarshalled方法中中,是遍历获取第一个对象的

 for (Object o : model.values()) {

    ...

 }

  但由于此时的model已经不是LinkedHashMap,只是普通的HashMap,导致里面的BindingResult对象和Bean对象的顺序有可能变掉了(hashmap按照字母排?),

  至于我的程序取出来的bean是错误的,而rapid的demo里面取出来的是正确的,只是demo的狗屎运,没碰上这个问题。

  为了验证,我把我的程序里的result.addObject("task",task);改成result.addObject("userinfo",task);

而demo里的改成相反的,结果,我的xml内容对了,demo的xml内容错了。

解决办法一:在网上找到了老外的解决办法:

原先的result.addObject("task",task);

得变成result.addObject(BindingResult.MODEL_KEY_PREFIX + "task", task);  太丑陋了,不喜欢,同时,加了这个前缀,转成json又出现问题了

解决办法二:老样子,重写spring中配置的org.springframework.web.servlet.view.xml.MarshallingView

改写这个locateToBeMarshalled方法

粗暴的将遇到的BindingResult对象跳过

if(o instanceof BindingResult){
    continue;
   }

算是暂时解决了。

总结:这次框架的搭建,让我感受到真不容易啊,网上的代码示例比比皆是,但挪到自己身上才发现问题一大堆

BindingResult问题,spring的bug

cglib代理类的问题,凡是beantoxml的工具,都有遇到,xstream,jaxb2,castor,目前只有castor1.2版本解决了这个问题,而最新的1.3.1版本,反而没有去重测这个功能,导致错误。

 

转载于:https://www.cnblogs.com/monolithic/archive/2010/11/20/1882811.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值