一、Maven构建项目
该示例采用Maven构建一个Web项目,项目结构如图所示:
其中,pom.xml文件中依赖如下所示,自动添加相应依赖包,包括Spring MVC、Hibernate、MySQL JDBC等:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>sdd</groupId> <artifactId>sdd</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name /> <description /> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.glassfish</groupId> <artifactId>bean-validator</artifactId> <version>3.0-JBoss-4.0.2</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.annotation</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.ejb</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.enterprise.deploy</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.jms</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.management.j2ee</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.resource</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.security.auth.message</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.security.jacc</artifactId> <version>3.0.1</version> <exclusions> <exclusion> <artifactId>javax.servlet</artifactId> <groupId>org.glassfish</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.servlet.jsp.jstl</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.transaction</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api-osgi</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> <exclusions> <exclusion> <artifactId>servlet-api</artifactId> <groupId>javax.servlet</groupId> </exclusion> <exclusion> <artifactId>jsp-api</artifactId> <groupId>javax.servlet.jsp</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.3</version> </dependency> <dependency> <groupId>javax.xml</groupId> <artifactId>webservices-api-osgi</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.jboss.weld</groupId> <artifactId>weld-osgi-bundle</artifactId> <version>1.0.1-SP3</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.11.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>xerces</groupId> <artifactId>xerces</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.6</version> </dependency> </dependencies> <build> <sourceDirectory>${basedir}/src</sourceDirectory> <outputDirectory>${basedir}/WebRoot/WEB-INF/classes</outputDirectory> <resources> <resource> <directory>${basedir}/src</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> </resources> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <webappDirectory>${basedir}/WebRoot</webappDirectory> <warSourceDirectory>${basedir}/WebRoot</warSourceDirectory> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project>
二、配置Web.xml
web.xml配置是整个框架整合的关键,需要配置对Spring的支持、SpringMVC的支持,同时需要解决浏览器对于rest PUT和DELETE请求的支持。
三、配置spring-servlet.xml<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" 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"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 添加对spring的支持 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 --> <listener> <listener-class> org.springframework.web.util.IntrospectorCleanupListener </listener-class> </listener> <!-- Spring MVC配置 --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <!-- 不能是/*,否则会报404 --> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 浏览器不支持put,delete等method,由该filter将/user?_method=delete转换为标准的http delete方法 --> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <!-- spring 名称一定要和servlet-mapping中servlet name一致 --> <servlet-name>spring</servlet-name> </filter-mapping> <!-- 指定Spring配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app>
一般以servlet-name来命名,你也可以取其他名字。该文件主要配置Spring MVC,同时需要解决Spring MVC对静态文件的解析过滤,通常放在WEB-INF路径下,具体内容如下:
四、创建并配置jdbc.properties<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- Spring MVC扫描Control --> <context:component-scan base-package="com.springmvc.control" /> <!-- 使用如下两个class激活@RequestMapping annotation --> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <!-- 通过mvc:resources设置静态资源,这样servlet就会处理这些静态资源,而不通过控制器 --> <!-- 设置不过滤内容,比如:css,jquery,img 等资源文件 --> <mvc:resources location="/*.html" mapping="/**.html" /> <mvc:resources location="/css/*" mapping="/css/**" /> <mvc:resources location="/js/*" mapping="/js/**" /> <mvc:resources location="/images/*" mapping="/images/**" /> <!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 避免IE执行AJAX时,返回JSON出现下载文件 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 --> </list> </property> </bean> </beans>
五、创建并配置applicationContext.xml文件jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=root
该文件通常放在src目录下
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 注解支持 --> <context:annotation-config /> <!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描 --> <context:component-scan base-package="com.springmvc.dao,com.springmvc.service"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- JDBC属性文件位置 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- MySQL数据库连接 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <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> <!-- 创建sessionFactory工具类 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="mappingResources"> <list> <value>com/springmvc/model/User.hbm.xml</value> </list> </property> </bean> <!-- Spring接管Hibernate CRUD操作 --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- Spring声明式事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置事务特性,配置add,delete,update开始的方法,事务传播特性为required --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- REQUIRED 表示 如果存在一个事务,则支持当前事务。如果没有事务则开启 --> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="*" read-only="true" /> </tx:attributes> </tx:advice> <!-- 配置那些类的方法进行事务管理,当前com.ssh2.basedao.impl包中的子包, 类中所有方法需要,还需要参考tx:advice的设置 --> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution(* com.springmvc.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" /> </aop:config> <!-- 导入SpringMVC Servlet配置文件 --> <import resource="classpath*:spring-servlet.xml" /> </beans>
六、编写控制类
Controller控制类是Spring MVC的核心,类似于Struts2框架中的Action,通过@Controller注解实现Spring的注入,并通过@RequestMapping接收前端映射请求。加入返回值@ResponseBoady注解后,要把对象转换成json格式,缺少转换依赖的jar包,会出现以下异常的情况,需要添加依赖的jar,jackson-core-asl-1.9.12.jar,jackson-mapper-asl-1.9.12.jar问题解决。
Response Status: 406 (Not Acceptable)
package com.springmvc.control; import javax.annotation.Resource; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.springmvc.model.User; import com.springmvc.service.UserService; /** * Scope:表示实例是原型,这样会对每一个请求实例化,保证线程安全 Spring中使用 Controller注解表示该类是控制器 * Repository注解Dao访问类 Service注解业务逻辑处理类 Resource注解表示使用某个bean资源 * RequestMapping:表示对该类所有方法的请求URL,前面必须接上/user,如/user/login 表示对login方法的请求访问 * * @author Administrator * */ @Scope("prototype") @Controller @RequestMapping("/user") public class UserControl { @Resource(name = "userService") private UserService userService; private String message; /** * * Spring MVC中使用RequestMapping处理URL请求, * GET:表示查询;POST:表示添加操作 * PUT:表示修改操作;DELETE:表示删除操作 * ResponseBody:表示返回对象或者值; * consumes: 表示前端传过来的数据格式; * produces:表示返回数据格式 */ @RequestMapping(value = "/login", method = RequestMethod.GET, consumes = "application/json", produces = "application/json") @ResponseBody public User login(User user, Model model) { // System.out.println(user.getUsername()); User u = userService.findUserByNameAndPassword(user); return u; } @RequestMapping(value = "/addUser", method = RequestMethod.POST, produces = "application/json") @ResponseBody public String addUser(User user) { boolean flag = userService.addUser(user); if (flag) { message = "success"; } else { message = "error"; } return message; } /** * PathVariable:注解方法参数,表示该参数变量值是通过URL传递的 * URL中必须包含该参数变量名,变量名需要相同才能完成变量传递注入 */ @RequestMapping(value = "/deleteUser/{id}", method = RequestMethod.DELETE, produces = "application/json") @ResponseBody public String deleteUser(@PathVariable Integer id) { boolean flag = userService.deleteUser(id); if (flag) { message = "success"; } else { message = "error"; } return message; } public void setUserService(UserService userService) { this.userService = userService; } public UserService getUserService() { return userService; } }
七、编写业务逻辑类
八、编写Dao操作类package com.springmvc.service; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.springmvc.dao.UserDao; import com.springmvc.model.User; @Service(value="userService") public class UserService { @Resource(name="userDao") private UserDao userDao; public User findUserByNameAndPassword (User user) { List<User> listUsers = userDao.findByNameAndPassword(user); if(listUsers.size() > 0) { return listUsers.get(0); } return null; } public User findUserByName (String name) { List<User> listUsers = userDao.findUserByName(name); if(listUsers.size() > 0) { return listUsers.get(0); } return null; } public boolean deleteUser(Integer id) { return userDao.deleteUser(id); } public boolean addUser(User user) { return userDao.addUser(user); } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
九、本示例中的Model类package com.springmvc.dao; import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; import org.springframework.orm.hibernate4.HibernateTemplate; import org.springframework.stereotype.Repository; import com.springmvc.model.User; @Repository(value="userDao") public class UserDao { //hibernateTemplate是Spring提供的Hibernate Dao操作类,在applicationContext中已经完成bean注入,所以此处直接 //可以拿过来使用 @Resource(name="hibernateTemplate") private HibernateTemplate hibernateTemplate; //根据用户名和密码查询 public List<User> findByNameAndPassword (User user) { String queryString = "from User where username = :username and password = :password"; String paramNames[] = {"username" , "password"}; String paramValues[] = {user.getUsername(),user.getPassword()}; //findByNamedParam方法提供hql方法参数查询,避免Sql注入漏洞 @SuppressWarnings("unchecked") List<User> listUsers = (List<User>) hibernateTemplate.findByNamedParam(queryString, paramNames, paramValues); return listUsers; } @SuppressWarnings("unchecked") public List<User> findUserByName(String name) { List<User> userList = new ArrayList<User>(); String queryString = "from User where username like:name"; userList = (List<User>) hibernateTemplate.findByNamedParam(queryString,"name",name); return userList; } public boolean addUser(User user) { try { hibernateTemplate.save(user); } catch (Exception e) { return false; } return true; } public boolean deleteUser(Integer id) { try { User user = hibernateTemplate.get(User.class, id); hibernateTemplate.delete(user); } catch (Exception e) { return false; } return true; } public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } }
十、前端JSP页面Ajax请求package com.springmvc.model; public class User { private Integer id; private String username; private String password; private String address; private String tel; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <!-- action uri 前面不能加/ 否则路径变成从根开始 --> <!-- <script type="text/javascript" src="js/jquery-easyui-1.4.4/jquery.min.js"></script> --> <script type="text/javascript" src="js/jquery-easyui-1.4.4//jquery.min.js"></script> <script type="text/javascript"> $(document).ready( function() { $("#btnQuery").click( function() { var username = $("#username").val(); var password = $("#password").val(); var data = { "username" : username, "password" : password }; // alert(JSON.stringify(data)); $.ajax({ type : "GET", url : "user/login", dataType : "json", //后台返回值类型 data : data, beforeSubmit : function() { }, success : function(data) { alert(data.username + " " + data.password + " " + data.address + " " + data.tel); }, error : function(data) { alert("error"); } }); }); $("#btnAdd").click( function() { var username = $("#username").val(); var password = $("#password").val(); var address = $("#address").val(); var tel = $("#tel").val(); var data = { "username" : username, "password" : password, "address" : address, "tel" : tel }; $.ajax({ type : "POST", url : "user/addUser", dataType : "json", //后台返回值类型 data : data, beforeSubmit : function() { }, success : function(data) { if(data == 'success') { alert("添加成功"); }else { alert("添加失败"); } }, error : function(data) { alert("error"); } }); }); $("#btnDel").click( function() { var id = $("#id").val(); $.ajax({ type : "DELETE", url : "user/deleteUser/"+id, dataType : "json", //后台返回值类型 beforeSubmit : function() { }, success : function(data) { if(data == 'success') { alert("删除成功"); }else { alert("删除失败"); } }, error : function(data) { alert("error"); } }); }); }); </script> </head> <body> <!-- 查询 --> 用户名: <input type="text" id="username" value="xx"> <br> 密码: <input type="password" id="password" value="1233"> <br> <a href="javascript:void(0)" id="btnQuery">查询</a> <br> <!-- 添加 --> 用户名: <input type="text" id="username" value="张三图"> <br> 密码: <input type="password" id="password" value="1233"> <br> 地址: <input type="text" id="address" value="安徽天长"> <br> 联系方式: <input type="password" id="tel" value="1232333"> <br> <input type="button" id="btnAdd" value="提交"> <br> <!-- 删除 --> <input type="text" id="id" value="51"> <input type="button" id="btnDel" value="删除"> <%-- <form:form action="user/login" method="post"> 用户名:<input type="text" name="username" value="xx"><br> 密码: <input type="password" name="password" value="1233"><br> 用户名:<input type="text" name="address" value="ss"><br> 密码: <input type="password" name="tel" value="1232333"><br> <input type="submit" value="提交"> </form:form> --%> <%--<form:form action="user/deleteUser/50" method="delete"> <input type="submit" value="提交"> </form:form> --%> </body> </html>HTTP请求中本身是不支持PUT和DELETE method方法请求的,本文在web.xml中添加了过滤器处理该部分请求,并且通过Ajax发送请求。但是Spring MVC本身也提供了<form:form>标签,通过表单提交的方式发送Restful请求,如上面代码中注释内容所示。只需要在页面前面导入标签库即可。
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>