1.框架搭建方面
和搭建ssh等开发环境步骤基本一致,无需额外注意什么,struts2是通过filter的方式拦截所有客户端的请求,spring mvc是通过一个自动装载的servlet来拦截,一定要说注意的点的话就是struts2是拦截所有的请求,写法如下:
<filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
spring mvc的配置为拦截/的请求,如下:
<servlet-mapping> <servlet-name>spring3</servlet-name> <!-- 这里可以用 / 但不能用 /* ,拦截了所有请求会导致静态资源无法访问,所以要在spring3-servlet.xml中配置mvc:resources --> <url-pattern>/</url-pattern> </servlet-mapping>
2.如何接收前台提交的数据?
spring mvc与struts2的最大区别就在这里,struts2的action方法都是无参数的,接收客户端提交的数据一般都是在action类定义实体类实例的方式来实现的,spring mvc则主要是通过定义action 方法参数来接收,这个搞struts2开发的程序员还真是需要适应一下,记住,取客户端提交的东西通过定义方法参数来获取!
具体怎么接收呢?假设有以下实体类
package com.shinowit.web; import java.io.Serializable; import java.util.Date; public class UserInfo implements Serializable{ private static final long serialVersionUID = 1L; private String userName; private String userPass; private int age; private Date birthday; private float price; private byte status; private boolean valid; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPass() { return userPass; } public void setUserPass(String userPass) { this.userPass = userPass; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public byte getStatus() { return status; } public void setStatus(byte status) { this.status = status; } public boolean isValid() { return valid; } public void setValid(boolean valid) { this.valid = valid; } }
前台的输入录入界面hello.jsp关键代码为:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <form:form action="./test/hello1.do" method="post" modelAttribute="user"> username:<form:input path="userName"/><form:errors path="userName" /> password:<form:password path="userPass"/> age:<form:input path="age"/><form:errors path="age"></form:errors> birthday:<form:input path="birthday"/><form:errors path="birthday"></form:errors> <input type="submit" value="login"> </form:form>
spring mvc中接收的代码则为:
@RequestMapping(value="hello1",method=RequestMethod.POST) public ModelAndView saveHello(@ModelAttribute("user") UserInfo user,BindingResult bindingResult){ ModelAndView result=new ModelAndView("hello"); if (bindingResult.hasErrors()==false){ if (user.getAge()<10){ bindingResult.rejectValue("age", "","年龄不能小于十岁!"); } } return result; }
上面的代码少TMD的一个字都会有问题啊,里面的几个重点:
1.BindingResult 参数前面必须要有用@ModelAttribute修饰的参数,一般就是实体类了,另外,必须必须的要起个名字,这个名字一定要和前台的
<form:form action="./test/hello1.do" method="post" modelAttribute="user">这里面的modelAttribute名称一样。
2.前台的
<form:errors path="age"></form:errors>如果有类型转换错误时,比如int类型的age用户错误的输入了字符串时,需要定义全局的国际化资源文件来搞定,如下:
spring的配置参数文件中定义加载国际化资源文件
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="messages"/> </bean>
然后编写messages.properties文件,内容如下:
typeMismatch.java.util.Date={0} \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u65E5\u671F. typeMismatch.int={0} \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u6570\u5B57.
然后在界面上使用<form:errors path="xxx">输出spring mvc的类型转换错误消息时才会好看,要不然就是一大堆E文提示,这玩意折腾了两天的时间才知道如何搞定。
另外就是需要写一写类型转换器,比如针对Date类型的,代码如下:
package com.shinowit.util; import java.beans.PropertyEditorSupport; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.springframework.util.StringUtils; public class DateConvertEditor extends PropertyEditorSupport { private SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.hasText(text)) { try { if (text.indexOf(":") == -1 && text.length() == 10) { setValue(this.dateFormat.parse(text)); } else if (text.indexOf(":") > 0 && text.length() == 19) { setValue(this.datetimeFormat.parse(text)); }else{ throw new IllegalArgumentException("Could not parse date, date format is error "); } } catch (ParseException ex) { IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage()); iae.initCause(ex); throw iae; } } else { setValue(null); } } public String getAsText() { if (getValue() instanceof java.util.Date) { try{ Calendar cal=Calendar.getInstance(); Date dateValue=(Date)getValue(); cal.setTimeInMillis(dateValue.getTime()); if ((0==cal.get(Calendar.HOUR_OF_DAY)) && (0==cal.get(Calendar.MINUTE)) && (0==cal.get(Calendar.SECOND))){ return dateFormat.format(dateValue); }else{ return datetimeFormat.format(dateValue); } }catch(Exception e){ e.printStackTrace(); } } return ""; } }
针对int类型的
package com.shinowit.util; import java.beans.PropertyEditorSupport; import org.springframework.util.StringUtils; public class IntConvertEditor extends PropertyEditorSupport { public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.hasText(text)) { try { setValue(Integer.parseInt(text)); } catch (Exception ex) { IllegalArgumentException iae = new IllegalArgumentException("Could not parse int data,message: " + ex.getMessage()); iae.initCause(ex); throw iae; } } else { setValue(0); //setValue(null); } } public String getAsText(){ if (getValue() instanceof java.lang.Integer) { Integer value=(Integer)getValue(); return value.toString(); } return ""; } }
总体感觉Spring MVC还是挺简单的,上手比较快,就是没有什么人讨论一些低级点问题,遇到问题不好查找怎么解决。