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 56

    ##其他布局 * LinearLayout * RelativeLayout * FrameLayout * AbsoluteLayout (绝对布局, 文档说过时,应用场景机顶盒开发,定制的平板) ...

  2. PCAP研究

    一.  pcap简介 封装了OS提供的底层抓包技术,对外提供一些统一的抓包(及发送)接口.实现这些功能的其他技术包括:BPF(Berkeley Packet Filter),DLPI(Data Lin ...

  3. MapReduce明星搜索指数统计,找出人气王

    我们继续通过项目强化掌握Combiner和Partitioner优化Hadoop性能 1.项目介绍 本项目我们使用明星搜索指数数据,分别统计出搜索指数最高的男明星和女明星. 2.数据集 3.分析 基于 ...

  4. MyBatis Tutorial – CRUD Operations and Mapping Relationships – Part 1---- reference

    http://www.javacodegeeks.com/2012/11/mybatis-tutorial-crud-operations-and-mapping-relationships-part ...

  5. 编写android的widget

    以前对这个东西很感兴趣,因为确实方便,如今有时间了来做一个例子 首先要定义一个layout(widgetview.xml)和一个配置文件(widgetconfig.xml) <?xml vers ...

  6. css考核点整理(八)-在什么情况下通过img引入图片,什么情况用背景图引入?背景属性有哪些

    在什么情况下通过img引入图片,什么情况用背景图引入?背景属性有哪些

  7. oracle实现自动记录存储过程、自定义函数执行错误

    CREATE OR REPLACE Package Pkg_Stm_Prgerrlog As --Purpose: 实现记录系统错误异常信息,便于问题跟踪 Procedure Sp_Stm_Prger ...

  8. 阿里大于验证码发送 (ThinkPhp框架)

    1.登录平台 阿里大于2.登陆之后我们可以看到资费,使用场景等,在进入正题之前我们需要一些准备工作,首先我们先了解下短信的请求参数,在这里我们需要注意的是sms_param这个参数,在接下来我们申请短 ...

  9. Matlab使用xlsread, xlswrite函数导致excel进程无法终止的问题

    系统版本:Win7 64位 Matlab版本:R2015b 问题描述:使用excel的操作函数,比如xlsread,xlswrite,导致excel进程无法终止,任务管理器中仍残留excel进程,打开 ...

  10. order by 自定义排序

    使用order by排序,有时候不是根据字符或数字顺序,而是根据实际要求排序. 例如有客户A,B,C,我希望排序结果是B,C,A,那么就要通过自定义的规则排序. 第一种方法,可以构造一张映射表,将客户 ...