代码样例参考了Spring包中docs下 MVC-step-by-step教程
配置
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
contextConfigLocation参数设定Bean定义文件的位置与名称
此处不配置则DispatcherServlet默认会使用Servlet的名称为前置读取
"servletName-servlet.xml"作为Bean的定义文件->springapp-servlet.xml
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<jsp-config>
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/tld/spring-form.tld</taglib-location>
</taglib>
</jsp-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
springapp-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
the application context definition for the springappDispatcherServlet
-->
<!--
定义信息资源
<fmt:message key="title"/>
......
-->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"></property>
</bean>
<bean name="/hello.htm" class="com.archie.web.HelloController" />
<bean name="/product.htm" class="com.archie.web.InventoryController">
<!-- productManager字段映射id为productManager的bean -->
<property name="productManager" ref="productManager"></property>
</bean>
<bean name="/priceincrease.htm" class="com.archie.web.PriceIncreaseFormController">
<property name="sessionForm" value="true" />
<property name="commandName" value="priceIncrease" />
<property name="commandClass" value="com.archie.service.PriceIncrease" />
<property name="validator">
<bean class="com.archie.service.PriceIncreaseValidator" />
</property>
<property name="formView" value="priceincrease" />
<property name="successView" value="product.htm" />
<property name="productManager" ref="productManager" />
</bean>
<!-- 视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--
the parent application context definition for the springapp
application
-->
<bean id="productManager" class="com.archie.service.SimpleProductManager">
<property name="productDao" ref="productDao" />
</bean>
<bean id="productDao" class="com.archie.dao.JdbcProductDao">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- jdbc配置文件配置 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!-- 事务配置 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<aop:config>
<aop:advisor pointcut="execution (* *..ProductManager.*(..))"
advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save*" />
<!-- true则数据只读,任何操作无法更改数据 -->
<tx:method name="*" read-only="false" />
</tx:attributes>
</tx:advice>
</beans>
库存Controller(商品列表)
package com.archie.web;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import com.archie.service.ProductManager;
/**
* 库存Controller
* @author archie2010
* since 2011-1-5上午11:08:07
*/
public class InventoryController implements Controller{
protected final Log logger=LogFactory.getLog(getClass());
private ProductManager productManager;
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String now=(new Date()).toString();
logger.info("returning hello view with"+now);
Map<String, Object> myModel=new HashMap<String, Object>();
myModel.put("now", now);
myModel.put("products", this.productManager.getProducts());
return new ModelAndView("product","model",myModel);
}
public ProductManager getProductManager() {
return productManager;
}
public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}
}
表单提交的Controller
package com.archie.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import com.archie.service.PriceIncrease;
import com.archie.service.ProductManager;
/**
* 负责提交的FormController
* @author archie2010
* since 2011-1-5上午11:04:25
*/
public class PriceIncreaseFormController extends SimpleFormController {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private ProductManager productManager;
public ModelAndView onSubmit(Object command) throws ServletException {
int increase = ((PriceIncrease) command).getPercentage();
logger.info("Increasing prices by" + increase + "%.");
productManager.increasePrice(increase);
logger.info("returning from Price Increase Form view to" + getSuccessView());
return new ModelAndView(new RedirectView(getSuccessView()));
}
protected Object formBackingObject(HttpServletRequest request)throws ServletException{
PriceIncrease priceIncrease=new PriceIncrease();
priceIncrease.setPercentage(20);
return priceIncrease;
}
public ProductManager getProductManager() {
return productManager;
}
public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}
}
表单验证
package com.archie.service;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* Form验证
* @author archie2010
* since 2011-1-5上午11:03:40
*/
public class PriceIncreaseValidator implements Validator{
private int DEFAULT_MIN_PERCENTAGE=0;
private int DEFAULT_MAX_PERCENTAGE=50;
private int minPercentage=DEFAULT_MIN_PERCENTAGE;
private int maxPercentage=DEFAULT_MAX_PERCENTAGE;
/**Logger for this class and subclasses*/
protected final Log logger=LogFactory.getLog(getClass());
@SuppressWarnings("unchecked")
public boolean supports(Class clazz) {
return PriceIncrease.class.equals(clazz);
}
public void validate(Object obj, Errors errors) {
PriceIncrease pi=(PriceIncrease) obj;
if(pi==null){
errors.rejectValue("percentage", "error.not-specified", null, "Value required");
}else{
logger.info("Validating with"+pi+":"+pi.getPercentage());
if(pi.getPercentage()>maxPercentage){
errors.rejectValue("percentage","error.too-high",
new Object[]{new Integer(maxPercentage)},"Value too high.");
}
if(pi.getPercentage()<=minPercentage){
errors.rejectValue("percentage","error.too-low",
new Object[]{new Integer(minPercentage)},"Value too low.");
}
}
}
public int getMinPercentage() {
return minPercentage;
}
public void setMinPercentage(int minPercentage) {
this.minPercentage = minPercentage;
}
public int getMaxPercentage() {
return maxPercentage;
}
public void setMaxPercentage(int maxPercentage) {
this.maxPercentage = maxPercentage;
}
}