spring mvc学习中遇到的问题及解决办法

时间:2022-01-26 13:41:55

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还是挺简单的,上手比较快,就是没有什么人讨论一些低级点问题,遇到问题不好查找怎么解决。