SpringMVC回归MVC本质,简简单单的Restful式函数,没有任何基类之后,应该是传统Request-Response框架中最好用的了。

Tips

1.事务失效的惨案

Spring MVC最打击新人的事情,你必须保证spring-mvc.xml的context:component-scan只扫描Controller,而 applicationContext.xml里的不包含Controller. 否则你定义在applicationContext.xml里的事务就要失效了。方法如下:

spring-mvc.xml:

<context:component-scan base-package="com.mycompany.myproject" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

applicationContext.xml:

<context:component-scan base-package="org.springside.examples.quickstart">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

另外,定义在spring-mvc.xml里的东西,在applicationContext*.xml中是不可见的,想共享的东西最好放在applicationContext.xml那边。
而applicationContext*.xml里的一些BeanPostProccesor,也不会作用到spring-mvc.xml定义/扫描到的Bean上,如果有必要就在spring-mvc.xml里重新定义一次,像Shiro的AOP校验权限。


2.Struts2式的Preparable接口--表单仅包含对象领域部分属性

Struts2有一个很实用的Preparable二次绑定功能: 表单提交时,先绑定一个ID,使用这个ID从数据库里找出对象来,再把表单中的其他属性绑定到这个对象上,对于那些表单中的输入框数量比业务对象的实际属性数少的情况很实用。

其实Spring MVC也有相同的能力, 见quickstart中的UserAdminController.

先用@ModelAttribute标注如下函数。SpringMVC会在执行任何实际处理函数之前,执行该函数并将返回值存为Model Attribute "user"

@ModelAttribute("user")
public User getUser(@RequestParam(value = "id", required = false) Long id) {
if (id != null) {
return accountService.getUser(id);
}
return null;
}

再在save函数里,以@ModelAttribute标注表单处理函数的参数。SpringMVC就会按名称"user"取出前面的对象,然后才进行真正的Binding。

@RequestMapping(value = "update/{userId}", method = RequestMethod.POST)
public String update(@Valid @ModelAttribute("user") User user) {
accountService.updateUser(user);
return "redirect:/admin/user";
}

注意1, 这里有个小坑爹的地方是,这个getUser()会在controller的所有函数前都执行,因此需要进行一下判断RequestParam中是否含id属性的判断,要不你就把update()方法独立到一个Controller中。

注意2, ModelAttribute如果已经占用了"user"这个名字,那些非update()函数的参数里就要躲开这个名字。

另外,你也可以选择不用这个功能,而是自己创建一个Form的DTO,然后用Dozer或手工把属性绑定到领域对象上。


3.Struts2式的FlashAttribute

为了防止用户刷新重复提交,save操作之后一般会redirect到另一个页面,同时带点操作成功的提示信息。因为是Redirect,Request里的attribute不会传递过去,如果放在session中,则需要在显示后及时清理,不然下面每一页都带着这个信息也不对。Spring在3.1才提供了这个能力。

public String save(@ModelAttribute("group") Group group, RedirectAttributes redirectAttributes) {
accountManager.saveGroup(group);
redirectAttributes.addFlashAttribute("message", "修改权限组成功");
return "redirect:/account/group/";
}

4.CheckBox/RadioButtons的绑定

在采用ORM的应用中,如果绑定子对象到页面上,以及在表单提交时如何把checkbox的内容重新绑回父对象是一个头痛的问题。

在showcase示例中,User-Role组合中的Role是一个对象而不是简单的枚举(对于简单的枚举,什么都不用做,直接用checkboxes的taglib就可以了。

<form:checkboxes path="permissionList" items="${allPermissions}" itemLabel="displayName" itemValue="value" />

注意,如果使用BootStrap,SpringMVC自带的checkboxes标签并不合用,详见Twitter Bootstrap章节。

而复杂对象时对象就没这么好彩了,详见showcase中的UserControler首先你需要设定不要自动绑定checkbox结果到对象中

@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("roleList");
}

然后在输入参数中多注入一个roleList, 自行处理:

@RequestMapping(value = "save/{userId}")
public String update(@Valid @ModelAttribute("user") User user,
@RequestParam(value = "roleList") List<Long> checkedRoleList) {
user.getRoleList().clear();
for (Long roleId : checkedRoleList) {
Role role = new Role(roleId);
user.getRoleList().add(role);
} accountService.saveUser(user);
return "redirect:/account/user";
}

5.输出跨域Ajax所需的JsonP

网上说什么扩展JsonView什么的太复杂了,自己拿Jackson生成一个JsonP的字符串返回就好了。 更多JSONP信息见Ajax章节.

6.Spring MVC与Hibernate Validator的结合

见Validation章节,一般情况下使用JQuery Validation Plugin的客户端认证。为了防止恶意用户的攻击,可以再加上Spring MVC与Hibernate Validator的服务端认证。因为是用来防恶意攻击的,因此直接抛出异常,而不会返回输入页面且输出出错信息(如果Controller方法中有BindingResult的参数,就交由方法内部去处理,否则直接往外抛异常)。

  1. 在spring-mvc.xml中,加入hibernate validator的定义
  2. 在User.java的相关属性加入@NotBlank定义
  3. 在UserDetailController的save方法,加入@Valid定义和BindingResult参数。

7. WARNING: "Skipping URI variable 'id' since the request contains a bind value

造成这个Warning的原因是url的path和表单中都有id 变量,这个时候,把url path改成别的名字就好了。

@RequestMapping(value = "save/{userId}")

SpringMvc配置 导致实事务失效的更多相关文章

  1. 面试突击83:什么情况会导致@Transactional事务失效?

    一个程序中不可能没有事务,而 Spring 中,事务的实现方式分为两种:编程式事务和声明式事务,又因为编程式事务实现相对麻烦,而声明式事务实现极其简单,所以在日常项目中,我们都会使用声明式事务 @Tr ...

  2. Mysql引起的spring事务失效

    老项目加新功能,导致出现service调用service的情况..一共2张表有数据的添加删除.然后测试了一下事务,表A和表B,我在表B中抛了异常,但结果发现,表B回滚正常,但是表A并没有回滚.显示事务 ...

  3. Spring,SpringMvc配置常见的坑,注解的使用注意事项,applicationContext.xml和spring.mvc.xml配置注意事项,spring中的事务失效,事务不回滚原因

    1.Spring中的applicationContext.xml配置错误导致的异常 异常信息: org.apache.ibatis.binding.BindingException: Invalid ...

  4. spring+springMVC,声明式事务失效,原因以及解决办法

    http://blog.csdn.net/z69183787/article/details/37819627#comments 一.声明式事务配置: <bean id="transa ...

  5. springmvc mybatis 声明式事务管理回滚失效,(checked回滚)捕捉异常,传输错误信息

    一.知识点及问题 后端框架: Spring .Spring mvc .mybatis 业务需求: client先从服务端获取用户大量信息到client,编辑完毕之后统一Post至服务端,对于数据的改动 ...

  6. java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现

    注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...

  7. 将struts的jar包拷贝到WEB-INF/lib导致eclipse中配置好的javadoc失效

    我通过这个步骤导入了struts的jar包并且配置好了javadoc,且亲测可用: http://www.cnblogs.com/qrlozte/p/3173805.html 但是当我把struts的 ...

  8. Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置

    用过 Spring Boot 的小伙伴都知道,我们只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好,但是,真实的项目环境比 ...

  9. Spring事务深入剖析--spring事务失效的原因

    之前我们讲的分布式事务的调用都是在一个service中的事务方法,去调用另外一个service中的业务方法, 如果在一个sevice中存在两个分布式事务方法,在一个seivice中两个事务方法相互嵌套 ...

随机推荐

  1. Android自己定义控件而且使其能够在xml中自己定义属性

    为什么要自己定义View android开发中自己定义View的优点是显而易见的.比方说以下的这个顶部导航,它被设计出如今应用的每一个界面,但每次的内容却不尽同样.我们不能在每一个layout资源中都 ...

  2. 详细分享UICollectionView的自定义布局(瀑布流, 线性, 圆形…)

    前言: 本篇文章不是分享collectionView的详细使用教程, 而是属于比较’高级’的collectionView使用技巧, 阅读之前, 我想你已经很熟悉collectionView的基本使用, ...

  3. Java基础知识强化之集合框架笔记41:Set集合之HashSet存储自定义对象并遍历练习

    1. HashSet集合存储自定义对象并遍历.如果对象的成员变量值相同即为同一个对象 注意了: 你使用的是HashSet集合,这个集合的底层是哈希表结构. 而哈希表结构底层依赖:hashCode()和 ...

  4. Java设计模式02:常用设计模式之工厂模式(创建型模式)

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的.  工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Fact ...

  5. htmlentities() 函数

    Definition and Usage定义和用法 The htmlentities() function converts characters to HTML entities.htmlentit ...

  6. Apache本地环境下出现循环重定向

    最近发现一个很奇怪的问题,用了很久的apache+php访问项目,昨天突然不行了,出现了这个 然后我一点点测试,我用的是TP框架,Indexaciton的index中调用框架里的一个redirect函 ...

  7. equals函数的作用

    1.equals函数在什么地方 在Object类中,写法与==一样,但是我们用的时候要重写这个equals方法 String类型中的equals是复写好的 2.equals函数的作用 ==号在比较两个 ...

  8. 使用Sqlite数据库存储数据

    1.Sql基本命令 1.1.创建表 表是有行和列组成的,列称为字段,行称为记录. 使用CREATE命令来创建表: 1 CREATE TABLE tab_student (studentId INTEG ...

  9. [转]mysql导入导出数据中文乱码解决方法小结

    本文章总结了mysql导入导出数据中文乱码解决方法,出现中文乱码一般情况是导入导入时编码的设置问题,我们只要把编码调整一致即可解决此方法,下面是搜索到的一些方法总结,方便需要的朋友. linux系统中 ...

  10. 【转】WF事件驱动

    转自:http://www.cnblogs.com/Mayvar/category/315963.html 这系统的教程有代码可以下载 WF事件驱动(5) 摘要: 之前,我通过4篇文章介绍了在WF4中 ...