SpringMvc配置 导致实事务失效

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}")
时间: 2024-10-01 05:16:02

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

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

一.知识点及问题 后端框架: Spring .Spring mvc .mybatis 业务需求: client先从服务端获取用户大量信息到client,编辑完毕之后统一Post至服务端,对于数据的改动要么全成功,要么全失败,所以须要使用事务支持. 问题: 配置Spring声明式事务,运行中出现异常未回滚.从网上查询得到一開始是自己的配置出了问题,因为配置文件的载入顺序决定了容器的载入顺序导致Spring事务没有起作用. 详情例如以下: 因为採用的是SpringMVC. MyBatis,故统一採用

Flink生产数据到Kafka频繁出现事务失效导致任务重启

在生产中需要将一些数据发到kafka,而且需要做到EXACTLY_ONCE,kafka使用的版本为1.1.0,flink的版本为1.8.0,但是会很经常因为提交事务引起错误,甚至导致任务重启 kafka producer的配置如下 def getKafkaProducer(kafkaAddr: String, targetTopicName: String, kafkaProducersPoolSize: Int): FlinkKafkaProducer[String] = { val prop

spring事务失效情况分析

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt113 <!--[if !supportLists]-->一.<!--[endif]-->声明式事务和注解事务并存的情况下,事务失效. 该情况常见配置如下: <!--事务声明--> <bean name="transactionManager" class="org.springframework.jdbc.dat

spring声明式事务 同一类内方法调用事务失效

只要避开Spring目前的AOP实现上的限制,要么都声明要事务,要么分开成两个类,要么直接在方法里使用编程式事务 [问题] Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring AOP啊,事务管理真轻松啊,真轻松:事务管理代码没有了,脑不酸了,手不痛了,一口气全配上了事务:轻量级,测试起来也简单,嘿!”.不管从哪个角度看,轻量级声明式事务都是一件解放生产力的大好事.所以,我们“一直用它”. 不过,最近的一个项目里,却碰到了一个事务管理上的问题:有一个服务类,其一个声明了事

Spring3.x事务失效的原因以及解决办法

项目中如果使用spring来管理事务,可能会出现事务失效的情况,我认为主要的原因是cglib无法获取到代代理的实例.. 如果带上事务,那么用annotation方式的事务注解和bean配置,事务会失效,要将service的bean配置到xml文件中才行,这样springmvc就不会扫描到@Service的类了 这个问题有另一种解决办法: 首先在主容器中(applicationContext.xml),将Controller的注解排除掉 <context:component-scan base-p

Spring事务失效的原因

Spring事务失效的原因 5种大的原因 如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB 假如有兴趣了解 mysql中 " engine=innodb " 以及 " engine=innodb 和engine=myisam的区别 ",可以读读这篇文章:http://blog.sina.com.cn/s/blog_6ac4c6cb01018pb1.html 可使用下述语句之一检查表的标类型: SHOW TAB

Spring 事务失效

隔离级别 在 TransactionDefinition.java 接口中,定义了“四种”的隔离级别枚举: /** * [Spring 独有]使用后端数据库默认的隔离级别 * * MySQL 默认采用的 REPEATABLE_READ隔离级别 * Oracle 默认采用的 READ_COMMITTED隔离级别 */ int ISOLATION_DEFAULT = -1; /** * 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读.幻读或不可重复读 */ int ISOLATION_R

BootStrap Validator 版本差异问题导致的submitHandler失效问题的解决方法

最近一直在做互金平台,做到后台提交表单的时候出现验证提交数据一直没有提交的问题.于是百度了一下.果然是版本问题造成的.幸好找到了问题所在.我一直仿照的是东钿原微信平台的做法,但是使用byond的后台框架,可能版本不一样,所以造成 submitHandler: function(validator, form, submitButton) { // 版本号0.4.5支持 // 版本号v0.5.2-dev不再支持submitHandler配置 } 这个方法一直是无效的无法执行.百度搜到就是以下解决办

Spring component-scan 的逻辑 、单例模式下多实例问题、事务失效

原创内容,转发请保留:http://www.cnblogs.com/iceJava/p/6930118.html,谢谢 之前遇到该问题,今天查看了下 spring 4.x 的代码 一,先理解下 context:component-scan 处理过程: 1 <!-- scan the package and the sub package --> 2 <!-- 3 [重要]:容易产生事务失效的地方,见:http://jinnianshilongnian.iteye.com/blog/176