springMVC和struts比起来,划分更细,各个层之间可供选择的方法更多,其实这也给大家造成了学习负担。灵活性和复杂性有时是有一定关系的。
在springMVC中,有“分发器”、“映射处理器”、“控制器”、“视图解析器”的概念。这些东西还都提供了不同的实现供选择,就是因为可以灵活选择,要是刚开始使用,倒不知道用哪个好了。
简单说一下sprngMVC的处置流程,Dispatcher Servlet接到请求后,需要将请求送给合适的“控制器”(Controller)处理,但是到底让哪个控制器处理,由HanderMapping(映射处理器)决定,控制器将处理后的业务对象打包到ModelAndView对象中,接着,Controller(控制器)将带有ModelAndView的请求送回到Dispatcher Servlet,然后交给ViewResolver(视图解析器),让他决定用那种视图来呈现结果。
基本的理论讲完了,现在还是通过例子来说明一下。通过idea建立一个web工程,这个步骤就省略了。引入的jar包如图lib所示。
项目引入的jar如图示:
1、首先对web-xml 进行配置
web.xml |
< 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_2_5.xsd" version="2.5" >
< servlet >
< servlet-name > roadrantz </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
<load-on-startup>1</load-on-startup>
</ servlet >
< servlet-mapping >
< servlet-name > roadrantz </ servlet-name >
< url-pattern > *.htm </ url-pattern >
</servlet-mapping>
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value >
/WEB-INF/roadrantz-service.xml
/WEB-INF/roadrantz-data.xml
/WEB-INF/roadrantz-security.xml
</ param-value >
</ context-param >
</ web-app >
在web-info.xml中,主要配置了“分发器(DispatcherServlet)”,但访问 *.htm 时候,就会触发此分发器。另外,还有一个监听器,但监听器启动时,会自动加载/WEB-INF/roadrantz-service.xml、roadrantz-data.xml、roadrantz-security.xml这些文件。可以将一些配置分散到不同的配置文件中,其中,在这个hello world的例子中还用不到,呵呵。
下面建立一个roadrantz-servlet.xml的文件,此文件中要配置“映射处理器(Handler Mapping)”和“视图解析器(ViewResolver)”。这个文件的名字必须要注意,是“servlet名-servlet.xml”,此处的bean指在web.xml中的“分发器(Display)”对应的servlet名。
另外,也可以自定义这个文件名,不过需要改动一下roadrantz,加<init-param>的节点,改为:
<servlet>
<servlet-name>roadrantz</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/hello-servlet.xml , /WEB-INF/helloWorld.xml </param-value>
</init-param>
</init-param>
</servlet>
其中,如果xml文件在classpath下面,param-value还可以基于classpath写,<param-value>classpath*:springmvc.xml</param-value>
roadrantz-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.xsd">
<bean id="beanNameUrlMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<bean name="/home.htm" class="com.baidu.HomePageController"></bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
对代码描述很痛苦,有时写的手疼,但是还是需要一些的。这里面配置了“映射处理器(Hander Mapping)、“控制器(Homepage
Controller)””和“视图解析器(View Resolver)”。其中,可以配置不同的“映射器”和不同的“视图解析器”。为什么不为HomePageController Bean设置id属性,而是设置name属性?奇怪的是,设定的不是一个真实的名字,而是一个URL “/home.htm”,是因为这里的name属性担任了两个责任:即定义bean的名字,还定义需要使用这个控制器处理的URL。由于URL中含有XML id属性中非法字符 -- “斜杠”,所以用name属性而没有用id。
HomePageController.java:
HomePageController.java |
importorg.springframework.web.servlet.ModelAndView;
importorg.springframework.web.servlet.mvc.Controller;
/**
* Created by IntelliJ IDEA.
* User: liuzhaoyang
* Date: 2011-2-28
* Time: 22:43:08
*/
public class HomePageController implements Controller {
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
return new ModelAndView("index","rants","hello,world");
}
只有进入DispatcherServlet的请求是以 /home.htm"结尾的,DispatcherServlet就会分发给HomePageController处理。
SpringMVC带有很多视图解析器,InternalResourceViewResolver是其中非常简单的一个。InternalResourceViewResolver在ModelAndView返回的视图前加上prefix属性配置的前缀,再在后面加上suffix属性设置的后缀,由于HomePageController返回的ModelAndView中视图名称是home,InternalResourceViewResolver将在 /home.jsp 中查找视图。
index.jsp文件
index.jsp |
<%--
Created by IntelliJ IDEA.
User: liuzhaoyang
Date: 2011-2-27
Time: 9:56:01
To change this template use File | Settings | File Templates.
--%>
<%@pagecontentType="text/html;charset=UTF-8"language="java" %>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core" %>
<%@pageisELIgnored="false" %>
<html>
<head><title>Simple jsp page</title></head>
<body>
Place your content here
<hr>
<c:outvalue="${rants}"></c:out>
</body>
</html>
---------------------------------------------------------
至此,基本写完了,这篇文章代码带多,描述有些少,要是大家谁不太明白,结合运行结果,会有更深的体会。
启动服务,运行,结果如图示:
注意,为什么在index.jsp中写了一句<%@ page isELIgnored="false" %>呢?因为我们在wen.xml中配置的servlet版本是2.5的,servlet2.4版本默认支持EL,