SpringMVC 应用开发
一、Spring MVC介绍
Spring MVC属于SpringFrameWork的后续产品,已经融合在SpringWeb Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
二、在项目中引入Spring MVC
1、Spring配置文件类别
如果你的项目是使用Spring框架进行构建开发的,并使用了Spring注解,那么我们在路径…/WEB-INF下的配置文件会包含:web.xml和applicationContext.xml,其中web.xml文件配置了Spring的字符集过滤器和默认的欢迎页面;applicationContext.xml文件里配置了需要扫描注解的包路径以及jdbcTemplate的Bean之类的内容。
2、使用SpringMVC时需新增的配置文件
如果要引入SpringMVC,我们需要在web.xml里面添加请求转发控制器DispatcherServlet,用于接收前段页面请求,将业务处理逻辑跳转到指定的对象方法。另外,还需要添加一个配置文件,默认名称是controller-servlet.xml,其中包括内部资源视图跳转的配置、待扫描注解的包路径配置、启动Spring MVC的注解功能以完成请求和注解POJO映射的配置、字符串处理配置等。
详细的配置文件以及说明会在文档最后给出。
3、web.xml重点配置内容
(1)字符串过滤器
<filter>
<description>字符集过滤器</description>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<description>字符集编码</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)DispatcherServlet配置
<!-- Controller 配置,类似于struts2中的action -->
<servlet>
<servlet-name>controller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>controller</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(3)ContextLoaderListener配置
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
4、applicationContext.xml重点配置
<!—启用注解设置 -->
<context:annotation-config/>
<!--注解对象扫描设置 -->
<context:component-scan base-package="comNaNcc.annotation"></context:component-scan>
5、controller-servlet.xml重点配置
<!—启用注解设置 -->
<context:annotation-config/>
<!--注解对象扫描设置 -->
<context:component-scan base-package="comNaNcc.annotation.action"/>
<!--action页面跳转设置,设置view(视图)文件的前缀和后缀 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/view/"p:suffix="" />
#说明:如果后缀是空,那么在跳转代码逻辑里面,需要写完整的跳转目标后缀,如return “userPage/user.jsp”或return “userPage/user.html”或return “userPage/user”
<!-- 从请求和响应处读取/编写字符串 -->
<bean id="stringHttpMessage"class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 将对象转换成json -->
<bean id="jsonConverter"class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
</bean>
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<!-- <refbean="mappingJacksonHttpMessageConverter" />json转换器 -->
<ref bean="stringHttpMessage"/>
<ref bean="jsonConverter"/>
</list>
</property>
</bean>
<!--拦截器配置-->
<mvc:interceptors>
<!-- 国际化操作拦截器如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
三、代码编写
我们设定项目默认页面是index.jsp,并在页面上调用业务逻辑处理的java类。
在index.jsp页面上添加代码:
<h3>用户信息操作:form提交add.do,传递表单参数</h3>
<form action="user/add.do"method="post">
姓名:<input type="text"name="userid"></input><br/>
号码:<input type="text"name="phone"></input><br/>
生日:<input type="text"name="birth"></input><br/>
<input type="submit"value="提交"/>
</form>
点击提交按钮后,Spring容器会去寻找user类中的add.do对应的方法。因此我们需要指定一个类的别名映射为user,并指定其中一个方法映射是add.do。
由于在controller-servlet.xml文件中配置的注解扫描路径是comNaNcc.annotation.action,我们在该路径下新增一个java文件,命名UserInfoController.java,新增方法public String add(params …){…}。
然后对这个类进行注解:
@Controller
@RequestMapping("/user")
publicclassUserInfoController {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@RequestMapping("/add.do")
public String add(User user , Map<String, Object> map){
System.out.println("add finished !");
System.out.println(user.toString());
map.put("name", user.getUserid());
map.put("phone", user.getPhone());
map.put("birth", sdf.format(user.getBirth()));
return"userinfo/user_add.jsp";
}
需要说明的是,add()方法里面有三个传入参数:User,Date,Map。为什么要传入这三个参数呢?因为SpringMVC在帮我们做跳转的时候,会将表单数据自动封装给指定的对象bean。但如果对象属性包含Date和Boolean之类的类型,就无法绑定,解决方法就是要在类中配置表单数据编辑器,比如日期编辑器CustomDateEditor等。编辑器需要用到注解@InitBinder。写法如下:
@InitBinder
publicvoidinitBinder(ServletRequestDataBinder bin){
CustomDateEditorcust = new CustomDateEditor(sdf,true);
bin.registerCustomEditor(Date.class,cust);
}
当页面提交包含表单数据的请求时,SpringMVC会帮我们把表单数据赋值给方法中的参数对象,前提是参数对象的属性名与表单中的字段名一致。如果表单数据中包含日期等类型参数,需要通过参数编辑器进行解析。
而参数Map,则用于接收对象属性值,并传递给跳转的目的页面userinfo/user_add.jsp,放到request中。页面通过jquery获取${paramName}获取数据。该页面的路径是:
project---webContent---view---userinfo---user_add.jsp
说明:页面跳转设置,设置view(视图)文件的前缀和后缀时,如果配置的是
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/view/"p:suffix="" />
那么待跳转的视图页面都是放在view下面,如果在view路径下再建立一个子类页面路径/userinfo,其中有user_add.jsp页面,那么通过return"userinfo/user_add.jsp";跳转到该页面中。
四、所有文件完整内容
1、web.xml
<?xml version="1.0"encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>springAnnotation</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<description>字符集过滤器</description>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<description>字符集编码</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Controller 配置,类似于struts2中的action -->
<servlet>
<servlet-name>controller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>controller</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>3000</session-timeout>
</session-config>
</web-app>
2、applicationContext.xml
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd ">
<!--Spring 配置 -->
<!--注解设置 -->
<context:annotation-config/>
<!--注解对象扫描设置 -->
<context:component-scan base-package="com.cmcc.annotation"></context:component-scan>
<!--properties文件扫描地址 -->
<context:property-placeholder location="classpath:conf.properties"/>
<bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource"ref="dataSource"></property>
</bean>
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"value="${jdbc.driver}" />
<property name="url"value="${jdbc.url}" />
<property name="username"value="${jdbc.username}" />
<property name="password"value="${jdbc.password}" />
</bean>
</beans>
3、controller-servlet.xml
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd ">
<!-- Spring mvc配置 -->
<!--注解对象扫描设置 -->
<context:component-scan base-package="com.cmcc.annotation.action"/>
<!--注解设置 -->
<mvc:annotation-driven />
<!--action页面跳转设置,设置view(视图)文件的前缀和后缀 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/view/" p:suffix=""/>
<!-- 从请求和响应处读取/编写字符串 -->
<bean id="stringHttpMessage"class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 将对象转换成json -->
<bean id="jsonConverter"class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
</bean>
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<!-- <refbean="mappingJacksonHttpMessageConverter" />json转换器 -->
<ref bean="stringHttpMessage"/>
<ref bean="jsonConverter"/>
</list>
</property>
</bean>
<mvc:interceptors>
<!-- 国际化操作拦截器如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<!-- 如果不定义 mvc:mapping path 将拦截所有的URL请求 -->
<!-- <beanclass="comNaNcc.ercs.eec.filter.AuthInterceptor"></bean>-->
</mvc:interceptors>
<!-- 上传文件解析器 -->
<bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize"value="100000000"/>
</bean>
</beans>
4、index.jsp
<%@ page language="java" contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE htmlPUBLIC "-//W3C//DTDHTML 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>Index</title>
<script src="<%=basePath%>js/jquery-1.7.2.min.js"></script>
</head>
<body>
<h3>用户信息操作:form提交add.do,传递表单参数</h3>
<form action="user/add.do"method="post">
姓名:<input type="text"name="userid"></input><br/>
号码:<input type="text"name="phone"></input><br/>
生日:<input type="text"name="birth"></input><br/>
<input type="submit"value="提交"/>
</form>
<br></br>
</body>
</html>
5、user_add.jsp
<%@ page language="java" contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE htmlPUBLIC "-//W3C//DTDHTML 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>
<script src="<%=basePath%>js/jquery-1.7.2.min.js"></script>
</head>
<body>
<h1>完成用户添加</h1>
${name }--${phone }--${birth}
</body>
</html>
下一篇会介绍SpringMVC跟Ajax的结合使用。