现在的位置: 首页 > 综合 > 正文

Spring mvc 五 基础学习

2018年05月09日 ⁄ 综合 ⁄ 共 10103字 ⁄ 字号 评论关闭

话说我们讲到spring mvc 四 的时候,是不是已经感觉spring mvc 已经搞的差不多了?一个类多个方法提供外面请求,看上去好像真的已经可以了,已经到了使用的跟struts 的效

果了是吧?其实不然,我们还有一个重要的需求还没有实现呢,那是什么?

答案是表单提交,对头了,这是一个非常重要的需求呢。

呵呵,当然了,如果您是提交几个简单的字段,完全使用 request.getParameter("fieldName") 就万事大吉了。不过我们回头想想,如果大批量的数据提交或者修改的时候,您都

是request.getParameter("fieldName")接收数据,您是不是感觉回到了servlet时代了(当然,其实spring父亲就是servlet)?那我们还用spring干嘛?可能有的童鞋说,我用他一

个类提供多个方法嘛。那您就错了,其实我们Spring mvc 四   里面讲解的配置是不能使用来提交表单的,因为请求是:/abc.htm?method=方法   这样的请求,这种请求应该是不能在提交数据时候用的。现在您是不是感觉到非常失望了?没有关系,接下来我们学习下,既可以提交表单,又不用request.getParameter("fieldName")。

开始吧...... 从那里开始呢..........

1、可能有了解spring mvc 的童鞋认为,这个提交表单很简单啊,用 SimpleFormController 就可以了。对了,这个是一直关注spring 3.0之前的用法,没有错,您确实没有看错,但是,当您升级到3.0之后,您会发现关于 BaseCommandController下面所有的子类都已经被Spring 声明不建议使用了
即 :@Deprecated ,好,废话少说,贴张图上来,有图有真相:



是吧,没有错吧,如果您不信,还可以查询他下面的子类的哦。当然并不是说明 声明不建议就不能用,你要是坚持用,我也咬不了您的,您爱用就用呗。

好了,废话不多说了,我们现在要说明的是SimpleFormController ,行吧,我们先看看对Spring mvc 四的 spring配置文件进行调整吧,以得到更优美的请求地址,如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
	<!-- 普通的bean实体 -->
	<bean name="sampleController" class="com.lap.taobaouse.controller.SampleController" />

	<bean name="lapController" class="com.lap.taobaouse.controller.LapController">
		<property name="methodNameResolver" ref="propertiesMethodResolver" />
	</bean>

	<!-- 实现一类对多方法的方法参数 -->
	<bean id="propertiesMethodResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
		<property name="mappings">
			<props>
				<prop key="/query_list.htm">queryList</prop>
				<prop key="/query_byId.htm">queryById</prop>
			</props>
		</property>
	</bean>

	<!-- url 管理 -->
	<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/test.htm">sampleController</prop>
				<prop key="/query_list.htm">lapController</prop>
				<prop key="/query_byId.htm">lapController</prop>
			</props>
		</property>
	</bean>

	<!-- 管理视图对象 -->
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="cache" value="true" />
		<property name="prefix" value="/static/template/" />
		<property name="suffix" value=".jsp" />
		<property name="contentType" value="text/html;charset=utf-8" />
	</bean>
</beans>

这个时候您就可以打开两个窗口对比 Spring mvc 四 里面的配置文件了,他们的差异是:

  <!-- 实现一类对多方法的方法参数 -->  
    <bean id="parameterMethodResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">  
        <property name="paramName" value="method" />  
    </bean>  

变成这样了,也就是说,我们用到了Spring mvc 四里面提到的 PropertiesMethodNameResolver配置,这个类是配置请求地址和方法对应的。

	<!-- 实现一类对多方法的方法参数 -->
	<bean id="propertiesMethodResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
		<property name="mappings">
			<props>
				<prop key="/query_list.htm">queryList</prop>
				<prop key="/query_byId.htm">queryById</prop>
			</props>
		</property>
	</bean>

好了,这个时候您要细心的看下配置文件,相信您有一定的收获的哦。

2、接下来,我们看看Java类怎么实现获取页面对象表单吧,如下代码:

/*
 * Copyright 2013 The JA-SIG Collaborative. All rights reserved.
 * distributed with this file and available online at
 * http://www.etong.com/
 */
package com.lap.taobaouse.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

/**
 * <p>
 * 表单提交对象,并实现了一类多方法功能
 * </p>
 * 
 * @author 劳水生 Exp
 * @version $FileName: LapFormController.java $Date: 2013-3-21 上午9:49:17 -0400
 *          2013
 * @since 1.0
 * 
 */
public class LapFormController extends MultiActionController {
	/**
	 * <p>
	 * 进入表单提交页面
	 * </p>
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public ModelAndView toAdd(HttpServletRequest request, HttpServletResponse response) {
		return new ModelAndView("addTest");
	}

	/**
	 * <p>
	 * 表单提交
	 * </p>
	 * 
	 * 
	 * @param request
	 * @param response
	 * @param testVO
	 * @return
	 */
	public ModelAndView saveTest(HttpServletRequest request, HttpServletResponse response, TestVO testVO) {
		System.out.println(testVO);
		return new ModelAndView();
	}
}

大家看了代码,重点是看第二个方法的方法头里面的参数,呵呵,最后一个就是我们要的对象了,不错吧,我们再去看看MultiActionController给我提供的源码方法建议,相信您可能有一定收获,如:

/**
 * {@link org.springframework.web.servlet.mvc.Controller Controller}
 * implementation that allows multiple request types to be handled by the same
 * class. Subclasses of this class can handle several different types of
 * request with methods of the form
 *
 * <pre class="code">public (ModelAndView | Map | String | void) actionName(HttpServletRequest request, HttpServletResponse response, [,HttpSession] [,AnyObject]);</pre>
 *
 * A Map return value indicates a model that is supposed to be passed to a default view
 * (determined through a {@link org.springframework.web.servlet.RequestToViewNameTranslator}).
 * A String return value indicates the name of a view to be rendered without a specific model.
 *
 * <p>May take a third parameter (of type {@link HttpSession}) in which an
 * existing session will be required, or a third parameter of an arbitrary
 * class that gets treated as the command (that is, an instance of the class
 * gets created, and request parameters get bound to it)
 *
 * <p>These methods can throw any kind of exception, but should only let
 * propagate those that they consider fatal, or which their class or superclass
 * is prepared to catch by implementing an exception handler.
 *
 * <p>When returning just a {@link Map} instance view name translation will be
 * used to generate the view name. The configured
 * {@link org.springframework.web.servlet.RequestToViewNameTranslator} will be
 * used to determine the view name.
 *
 * <p>When returning {@code void} a return value of {@code null} is
 * assumed meaning that the handler method is responsible for writing the
 * response directly to the supplied {@link HttpServletResponse}.
 *
 * <p>This model allows for rapid coding, but loses the advantage of
 * compile-time checking. It is similar to a Struts {@code DispatchAction},
 * but more sophisticated. Also supports delegation to another object.
 *
 * <p>An implementation of the {@link MethodNameResolver} interface defined in
 * this package should return a method name for a given request, based on any
 * aspect of the request, such as its URL or an "action" parameter. The actual
 * strategy can be configured via the "methodNameResolver" bean property, for
 * each {@code MultiActionController}.
 *
 * <p>The default {@code MethodNameResolver} is
 * {@link InternalPathMethodNameResolver}; further included strategies are
 * {@link PropertiesMethodNameResolver} and {@link ParameterMethodNameResolver}.
 *
 * <p>Subclasses can implement custom exception handler methods with names such
 * as:
 *
 * <pre class="code">public ModelAndView anyMeaningfulName(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception);</pre>
 *
 * The third parameter can be any subclass or {@link Exception} or
 * {@link RuntimeException}.
 *
 * <p>There can also be an optional {@code xxxLastModified} method for
 * handlers, of signature:
 *
 * <pre class="code">public long anyMeaningfulNameLastModified(HttpServletRequest request)</pre>
 *
 * If such a method is present, it will be invoked. Default return from
 * {@code getLastModified} is -1, meaning that the content must always be
 * regenerated.
 *
 * <p><b>Note that all handler methods need to be public and that
 * method overloading is <i>not</i> allowed.</b>
 *
 * <p>See also the description of the workflow performed by
 * {@link AbstractController the superclass} (in that section of the class
 * level Javadoc entitled 'workflow').
 *
 * <p><b>Note:</b> For maximum data binding flexibility, consider direct usage of a
 * {@link ServletRequestDataBinder} in your controller method, instead of relying
 * on a declared command argument. This allows for full control over the entire
 * binder setup and usage, including the invocation of {@link Validator Validators}
 * and the subsequent evaluation of binding/validation errors.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Colin Sampaleanu
 * @author Rob Harrop
 * @author Sam Brannen
 * @see MethodNameResolver
 * @see InternalPathMethodNameResolver
 * @see PropertiesMethodNameResolver
 * @see ParameterMethodNameResolver
 * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
 * @see org.springframework.web.bind.ServletRequestDataBinder
 */
public class MultiActionController extends AbstractController implements LastModified {

....

里面的信息我们就不贴出来了,我们是看注释里面给我们说明继承他后的方法,行吧,这里我就不多说了,把 TestVO 对象代码也贴下吧,免得有人问     TestVO 是什么呢,如下:

/*
 * Copyright 2013 The JA-SIG Collaborative. All rights reserved.
 * distributed with this file and available online at
 * http://www.etong.com/
 */
package com.lap.taobaouse.controller;

import java.io.Serializable;

/**
 * 
 * @author 劳水生 Exp
 * @version $FileName: TestVO.java $Date: 2013-3-21 上午9:50:36 -0400 2013
 * @since 1.0
 * 
 */
public class TestVO implements Serializable {
	private static final long serialVersionUID = 7868977600979801437L;
	/**
	 * id
	 */
	private int id;
	/**
	 * 用户姓名
	 */
	private String name;
	/**
	 * 性别
	 */
	private int sex;
	/**
	 * 动物猫数据对象
	 */
	private CatVO catVO;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getSex() {
		return sex;
	}

	public void setSex(int sex) {
		this.sex = sex;
	}

	public CatVO getCatVO() {
		return catVO;
	}

	public void setCatVO(CatVO catVO) {
		this.catVO = catVO;
	}

}

为了证明类内聚合对象也能提交,我在TestVO 里面还搞了一个 CatVO,这里也贴出来吧,如下:

/*
 * Copyright 2013 The JA-SIG Collaborative. All rights reserved.
 * distributed with this file and available online at
 * http://www.etong.com/
 */
package com.lap.taobaouse.controller;

import java.io.Serializable;

/**
 * 
 * @author 劳水生 Exp
 * @version $FileName: CatVO.java $Date: 2013-3-21 下午2:00:54 -0400 2013
 * @since 1.0
 * 
 */
public class CatVO implements Serializable {
	private static final long serialVersionUID = 2015266440849396264L;
	/**
	 * 动物名称
	 */
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

两个数据对象都非常简单吧,这里就不说明了,呵呵。

3、我们看下页面的代码吧,页面代码还是有比较值的 注意 的细节,特别是对用惯了struts 2的童鞋,相信会写错哦,代码如:

addTest.jsp页面了,提交数据成功后我没有做页面,呵呵

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>信息添加页面</title>
</head>
<body>
	<form action="save_test.htm">
		姓名<input type="text" name="name" /><br> 
		男<input type="radio" name="sex" value="1"/> 
		女<input type="radio" name="sex" value="2"/> <br> 
		宠物猫名称<input type="text" name="catVO.name" /><br> 
		<input type="submit" value="保存" />
	</form>
</body>
</html>

页面里面我们重点注意的就是html控件里面的 <input type="xx" name="name"/> name,我们发现他并不是我们使用struts2里面的那样,不能写成 <input type="xx" name="testVO.name"/> ,注意哦。

4、可以测试了,按照我们这里写的,请求应该是 :http://localhost:8080/spring-example/add_test.htm.界面大概如下:

有图有真相。做到这里视乎应该完成了吧,但是我一直没有搞清楚一个问题,就是spring 3.0之后的 mvc 都已经声明 SimpleFormController了,那spring 的标签还能用吗?能用是不是只是对

SimpleFormController使用,如果是这样,那 MultiActionController 怎么结合 Spring 页面标签使用呢?下一节我希望我能掘开这个问题,如果有了解的童鞋也可以联系我,跟我讲解下,谢谢了。

好了,如果对本页有疑问可以联系我的哦,记得转载要保留出处哦。盗用别人的劳动不说明出处是不健康的呢。

抱歉!评论已关闭.