最近开始用Spring MVC做项目,而且越来越喜欢Spring MVC,特别是简易的配置,与Spring注入的完美结合,还有对JSON数据的完美转换,弄的我爱不释手!
具体的配置我就不想说了,网上资料太多,没必要细谈。
首先:注入配置。如果没用到SpringMVC的话,注入主要写很多配置,而且根据注入类型的不同,注入配置也不一样。比如set注入方式,我们首先需要在applicationContext.xml中配置这样的注入:
<bean id="userManage" name="userManage" scope="request" class="com.fly.user.beans.UserManagerBean">
<property name="userservice" ref="userservice"></property>
</bean>
<bean id="userservice" class="com.fly.user.service.impl.UserServiceImpl">
<property name="userdao" ref="userdao"/>
</bean>
<bean id="userdao" class="com.fly.user.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
而如果用到了构造函数注入方式:
<bean id="forecastBean" name="forecastcurve" scope="application" class="com.fly.user.beans.UserManagerBean">
<constructor-arg index="0" name="userservice" ref="userservice"/>
</bean>
相信大家对这个很熟悉,但是在Spring MVC下,一切配置都是浮云啊!因为只要简单的几句话就解决了,首先在applicationContext.xml下配置
<context:component-scan base-package="com.fly.user.dao,com.fly.user.service" />
当然你也可以写成如下形式,正则匹配嘛,只要整个包都可以自动扫描进去了。
<context:component-scan base-package="com.fly.*.dao,com.fly.*.service" />
然后你需要在dispatcher-servlet.xml中配置controller类的注入配置,当然是同样简单
<context:component-scan base-package="com.fly.*.controller" />
到了这步注入配置就完成了。想不到吧!然后你需要注解(@Autowired)类中的set注入方法,例如:
public class UserLoginController {
private IUserService userservice;
public IUserService getUserservice() {
return userservice;
}
@Autowired
public void setUserservice(IUserService userservice) {
this.userservice = userservice;
}
}
当然所有daoimpl与serviceimpl都要这样注解。
其次:数据的前后台交互。一般交互都是json数据转换的形式。特别是跟jquery easyui,extjs等js框架结合的时候,相当的方便。
//用户登录检查
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public Map<String,Object> loginCheck(HttpServletRequest request) {
Map<String,Object> map = new Map<String,Object>();
String username = request.getParameter("name").trim();
System.out.println(username);
String password = request.getParameter("userpasswd").trim();
User loginUser = userservice.loginCheck(username, Md5Encryption.getMd5Code(password));
if (null != loginUser) {
int logintime = loginflag.getLogintime();
loginUser.setLogintime(++logintime);
userservice.updateUser(loginUser);
map.put("user",loginUser);
map.put("success",true);
map.put("msg","登陆成功!");
} else {
map.put("success",false);
map.put("msg","登陆失败!");
}
return map;
}
其中
@RequestMapping(value = "/login", method = RequestMethod.POST)
表明了页面传入的路径,例如(/login.do),提交方式post,整个主要是在form中或者ajax提交中定义的。
@ResponseBody
表明整个方法输出的内容是会传入到页面的。如果去掉这句话,页面需要返回一个String或者Model类型进行页面之间的跳转。比如返回的是一个String类型"/user/index",页面就会根据dispatcher-servlet.xml中配置的ViewResolver:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
来进行页面的跳转,跳转到user/index.jsp页面。
针对@ResponserBody,对于controller返回的类型没有具体要求,因为强大的spring MVC内部的MappingJacksonHttpMessageConverter方法很好的把数据转换成json数据,然后可以直接在页面直接调用。
而JSON转换配置在dispatcher-servlet.xml中,需要在注册的AnnotationMethodHandlerAdapter中添加:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<!-- 配置一下对json数据的转换 -->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
如果想对页面编码进行转换,也可以在MappingJacksonHttpMessageConverter中配置编码
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<!-- 配置一下对json数据的转换 -->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
除了上面针对性的配置以外,我们再说一下<mvc:annotation-driven />。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。如果配置了<mvc:annotation-driven />,就不需要在配置json的数据转换了。<mvc:annotation-driven />并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
这里谈一下,我在项目中遇到一个超无语的事情。开始我是用<mvc:annotation-driven />注册注解的。在后台传值的问题上没有错误,可是后来我要增加拦截器,是手动配置AnnotationMethodHandlerAdapter的,这个时候前台却不能正常显示数据了,可是我能打印出前台的数据内容。后来我才发现,前台ajax接收数据的时候,一定要指定为dataType:"json"。而用默认的<mvc:annotation-driven />却不需要。蛋疼吧!
Spring3 MVC的数据转换做的那是相当牛,举个例子
如果前台ajax传入的数据是$.ajax({url:"xxx.do",data:{page:1,rows:2}})
后台方法的参数只要写成(int page, int rows)。如下:
@RequestMapping(value = "/XXX", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> getSdayForm(int page, int rows) {
...
}
或者写成(Data d),如下:
@RequestMapping(value = "/XXX", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> getSdayForm(Data d) {
...
}
Data类只要封装成如下格式:
class Data{
int page;
int rows;
...
}
根本不需要写成int page = Integer.parseInt(request.getParameter("page"));这真的太强大!