工程结构:
Spring MVC是一个包含了Dispatcher servlet的MVC框架。它调用控制器方法并转发到视图。这是使用Spring MVC的一个好处:不需要编写Dispatcher servlet。
要使用这个servlet,需要把它配置在部署描述符(web.xml文件),应用servlet和servlet-mapping。DispatchcerServlet类在spring-webmvc-x.y.z.jar文件中。
web.xml:
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
/WEB-INF/config/springmvc-config.xml
1
springmvc
*.action
注:Dispatcher servlet将使用Spring MVC诸多默认组件。此外,初始化时,它会寻找一个在应用程序的WEB-INF目录下的配置文件,该配置文件的命名规则是:
servletName-servlet.xml,其中servletName是在部署描述符中的Dispachter servlet的名称。所以本例中如果要去掉
servlet元素内的on-startup元素是可选的。如果它存在,则它将在应用程序启动时装载servlet并调用它的init方法。若它不存在,则在该servlet的第一个请求时加载。
开发一个控制器可实现org.springframework.web.servlet.mvc.Controller接口,这个接口公开了一个handleRequest方法,下面是该方法的签名:
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response),其实现类可以访问对应请求的HttpServletRequest和HttpServletResponse,还必须返回一个包含视图路径或视图路径和模的ModelAndView对象。
注:Controller接口的实现类只能处理一个单一动作(Action),而一个基于注解的控制器可以同时支持多个请求处理,并且无须实现任何接口。
springmvc-config.xml:
Spring MVC中的视图解析器负责解析视图。可以通过在配置文件中定义一个ViewResolver来配置。如上视图解析器配置有前缀和后缀两个属性。这样一来,view路径将缩短。例如,仅需提供"myPage",而不必再设置视图路径为/WEB-INF/jsp/myPage.jsp,视图解析器将会自动增加前缀和后缀。
InputProductController.java:package app03b.controller;
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;
public class InputProductController implements Controller {
private static final Log logger = LogFactory.getLog(InputProductController.class);
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.info("InputProductController called");
return new ModelAndView("ProductForm");
}
}
其中,“ProductForm”由于视图解析器的存在,自动加了前后缀,它相当于“/WEB-INF/jsp/ProduceForm.jsp”。
Spring自带的DispatcherServlet会通过springmvc-config.xml配置文件去实例化controller,而controller以
jsp页面提交表单-->product_input.action-->springmvc-config.xml匹配
由于controller以
package app03b.controller;
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 app03b.domain.Product;
import app03b.form.ProductForm;
public class SaveProductController implements Controller {
private static final Log logger = LogFactory.getLog(SaveProductController.class);
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.info("SaveProductController called");
ProductForm productForm = new ProductForm();
// populate action properties
productForm.setName(
request.getParameter("name"));
productForm.setDescription(
request.getParameter("description"));
productForm.setPrice(request.getParameter("price"));
// create model
Product product = new Product();
product.setName(productForm.getName());
product.setDescription(productForm.getDescription());
try {
product.setPrice(Float.parseFloat(
productForm.getPrice()));
} catch (NumberFormatException e) {
}
// insert code to save Product
return new ModelAndView("ProductDetails", "product", product);
}
}
ProductDetails.jsp页面通过模型属性名“product"来访问由SaveProductController传入的Product对象。
测试:浏览器输入http://localhost:8080/SpringMVCTest/product_input.action,效果及缺少的其他源码,见博客“初始MVC”。