一、采用Spring MVC的好处
从MVC之Servlet控制器(二)中,我们知道,要实现MVC,我们要编写一个Dispatcher Servlet和Controller类,其中Dispatcher Servlet要完成下面的工作。
1. 根据uri调用相应的action .
2. 实例化正确的controller .
3. 根据请求参数来构造表单bean .
4. 调用控制器对象相应的方法。
5. 转向一个视图。
Spring MVC中就有 Dispatcher Servlet,所以我们不用再编写 DispatcherServlet,它调用controller的方法并转发视图。除这外,它还有很多其它的优点。
二、Spring MVC的Dispatcher Servlet
Dispatcher Servlet在初始化时,会自动找到WEB-INF目录下面的配置文件,这个配置文件的命名规则如下
servletName-servlet.xml
我们也可以将配置文件放在别的地方,并用 init-param元素指定目录。
三、Controller接口
在spring mvc2.5版本前,开发一个controller的唯一方法是实现 spring MVC的一个controller接口。接口中的方法如下
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
实现这个接口的类可以访问request/response。还一定要返回一个包括了视图路径,模型名称与模型的ModelAndView对象。
Controller接口的实现类只能处理一个action,而基于注解的一个controller可以实现多个请求处理动作,还不用implement任何接口。
四、第一个Spring MVC应用
工程目录
要注意DispatcherServlet文件的命名,可以将它放到config里面,但是要web.xml文件中要加入initParam配置。
- 部署描述符文件web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app 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_3_0.xsd" version="3.0" > <!-- 注意文件名一定是servletName-servlet --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- map all request to this DispatcherServlet --> <!-- 好像拦截的是*.action与/时效果不同,不知道为什么--> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
- Spring MVC配置文件
声明控制器,并进行映射。
<?xml version="1.0" encoding="UTF-8"?> <beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"> <!-- 将两个控制器映射到了product....action --> <bean class="app03a.controller.InputProductController" name="/product_input.action"/> <bean class="app03a.controller.SaveProductController" name="/product_save.action"/> </beans>
- Controller文件
InputProductController.class
public class InputProductController implements Controller{ private static final Log logger = LogFactory.getLog(InputProductController.class) ; @Override public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { logger.info("InputProductController called"); //只有视图,没有模型 return new ModelAndView("/WEB-INF/jsp/ProductForm.jsp"); } }
SaveProductController.class
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(); 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) { e.printStackTrace(); } //code here to save in DB //这里返回了视图路径,模型名和模型 return new ModelAndView("/WEB-INF/jsp/ProductDetails.jsp", "product", product) ; } }
- 视图文件
同之前的。
总体上看,和之前的比较像。
五、ViewResolver的配置
可以在要springmvc-servlet.xml中加入
<bean id ="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
这样,我们可以将上面的两个controller中的视图路径写成ProductDetails和ProductForm就可以了,视图解析器会自动加上prefix和suffix。
我们还可以将springmvc-servlet.xml(此时还可以改名字)文件移动到config中,然后改web.xml 为
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app 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_3_0.xsd" version="3.0" > <!-- 注意文件名一定是servletName-servlet --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 当springmvc的配置文件不是默认情况时,要设置contextConfigLocation --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- map all request to this DispatcherServlet --> <!-- 好像拦截的是*.action与/时效果不同,不知道为什么--> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>