Spring MVC入門基礎項目環境搭建
本文章知道簡單的能夠搭建Sping MVC環境進行代碼基礎開發。
根據Spring的體系結構圖畫出Spring開發過程中涉及的文件和交流細節:

Spring MVC流程說明:
-
用戶請求http://127.0.0.1:8080/user/login
-
根據org.springframework.web.servlet.DispatcherServlet配置的xml文件找到相應處理器
-
根據映射到Contorller處理器的用戶請求訪問業務Service和數據訪問DAO層處理得出返回結果到前端JSP頁面
-
用戶通過返回結果得到相應的信息

在開發工具中新增Java Web項目,項目結構分布說明圖如下:

lib列表說明如下圖:

項目核心文件列表說明如下:
(1)jdbc-context.xml spring的jdbc配置
(2)springmvc-servlet.xml sping mvc相關的配置文件
(3)web.xml 配置spring過濾器和編碼
(4)LoginController.java 登錄功能的控制器
(5)LoginService.java 登錄功能業務接口
(6)LoginServiceImpl.java 登錄功能業務實現層
(7)BaseDao.java 登錄功能的數據訪問接口
(8)BaseDaoImpl.java 登錄功能的數據訪問層
(9)DBUtil.java 數據操作公共類
(10)login.jsp 登錄頁面
(11)database.properties 數據庫訪問配置
(12)User.java 實體
源碼訪問如下:
(1)jdbc-context.xml spring的jdbc配置
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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/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" default-autowire="byName">
<context:property-placeholder location="classpath:database.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${mysql.driverclass}"></property>
<property name="jdbcUrl" value="${mysql.jdbcurl}"></property>
<property name="user" value="${mysql.user}"></property>
<property name="password" value="${mysql.password}"></property>
<property name="acquireIncrement" value="5"></property> <!-- 當連接池中的連接用完時,C3P0一次性創建新連接的數目2 -->
<property name="initialPoolSize" value="10"></property> <!-- 初始化時創建的連接數,必須在minPoolSize和maxPoolSize之間 -->
<property name="minPoolSize" value="5"></property>
<property name="maxPoolSize" value="20"></property>
<!-- 最大空閑時間,超過空閑時間的連接將被丟棄
[需要注意:mysql默認的連接時長為8小時(28800)【可在my.ini中添加 wait_timeout=30(單位秒)設置連接超時】,這里設置c3p0的超時必須<28800]
-->
<property name="maxIdleTime" value="300"></property>
<property name="idleConnectionTestPeriod" value="60"></property> <!-- 每60秒檢查連接池中的空閑連接 -->
<property name="maxStatements" value="20"></property> <!-- jdbc的標準參數 用以控制數據源內加載的PreparedStatement數量,但由于預緩存的Statement屬 于單個Connection而不是整個連接 -->
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 聲明式事務管理 -->
<aop:config>
<aop:advisor pointcut="execution(* com.springTest.service.impl.*ServiceImpl.*(..))" advice-ref="myAdvice"/>
</aop:config>
<tx:advice id="myAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true" rollback-for="com.springTest.util.DaoException"/>
</tx:attributes>
</tx:advice>
<!-- 自動掃描組件,需要把controller去掉,否則影響事務管理 -->
<context:component-scan base-package="com.springTest">
<context:exclude-filter type="regex" expression="com.springTest.web.*"/>
</context:component-scan>
</beans> (2)springmvc-servlet.xml sping mvc相關的配置文件
<?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:p="http://www.springframework.org/schema/p" 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-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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 啟動掃描所有的controller --> <context:component-scan base-package="com.springTest.web"/> <!-- 主要作用于@Controller,激活該模式 下面是一種簡寫形式,完全可以手動配置替代這種簡寫形式; 它會自動注冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean, 是spring MVC為@Controllers分發請求所必須的 --> <mvc:annotation-driven/> <!-- 這里攔截器還有一種配置方法【針對路徑進行配置】 推薦使用這個,方便直觀--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/user/MyHome"/> <mvc:mapping path="/usermanager/*"/> <bean class="com.springTest.web.interceptor.MyInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> <!-- 全局配置 <mvc:interceptors> <bean class="com.springTest.web.interceptor.MyInterceptor"></bean> </mvc:interceptors> --> <!-- 配置js,css等靜態文件直接映射到對應的文件夾,不被DispatcherServlet處理 --> <mvc:resources location="/WEB-INF/resources/**" mapping="/resources"/> <!-- jsp頁面解析器,當Controller返回XXX字符串時,先通過攔截器,然后該類就會在/WEB-INF/views/目錄下,查找XXX.jsp文件--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
(3)web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/META-INF/jdbc-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置spring處理器 --> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/META-INF/springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
(4)LoginController.java 登錄功能的控制器
/**
*
*/
package com.springTest.web.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.springTest.po.User;
import com.springTest.service.LoginService;
import com.springTest.web.BaseController;
/**
* 登陸方法
* @author tushen
* @date Nov 4, 2011
*/
@Controller
public class LoginController extends BaseController{
@Autowired
private LoginService loginService;
@RequestMapping(value="/user/login",method=RequestMethod.GET)
public String login(){
return "login";
}
@RequestMapping(value="/user/login",method=RequestMethod.POST)
public String logon(String userName,String passWord){
User user = null;
try {
user = loginService.getUser(userName, passWord);
} catch (RuntimeException e) {
}
if(user!=null){
return "MyHome";
}else{
return "login";
}
}
@RequestMapping(value="/user/register",method=RequestMethod.POST)
public String register(User user){
loginService.addUser(user);
return "login";
}
@RequestMapping(value="/user/toRegister",method=RequestMethod.GET)
public String toRegister(){
return "register";
}
} (5)LoginService.java 登錄功能業務接口
/**
*
*/
package com.springTest.service;
import com.springTest.po.User;
/**
* @author tushen
* @date Nov 4, 2011
*/
public interface LoginService {
public User getUser(String userName,String password);
public void addUser(User user);
} (6)LoginServiceImpl.java 登錄功能業務實現層
/**
*
*/
package com.springTest.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.springTest.dao.BaseDao;
import com.springTest.po.User;
import com.springTest.service.LoginService;
/**
* @author tushen
* @date Nov 4, 2011
*/
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
private BaseDao baseDao;
static String addUser = "insert into user(username,password,first_name,last_name,birthday,age) values(:userName,:passWord,:firstName,:lastName,:birthday,:age);";
static String getUser = "select * from user where username = ? and password = ?";
@Override
public User getUser(String userName, String password) {
User user = baseDao.getObject(getUser, User.class, new Object[]{userName,password});
return user;
}
@Override
public void addUser(User user) {
baseDao.saveOrUpdateObject(addUser, user);
}
} (7)BaseDao.java 登錄功能的數據訪問接口
/**
*
*/
package com.springTest.dao;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @author tushen
* @date Nov 5, 2011
*/
public interface BaseDao {
/**
* 保存或者更新實體
* @param sql
* @param entry
*/
<T extends Serializable> void saveOrUpdateObject(String sql,T entry);
/**
* 查詢實體列表
* @param sql
* @param className
* @param obj
* @return
*/
<T extends Serializable> List<T> getObjList(String sql,Class<T> className,Object[] objs);
/**
* 查詢實體
* @param <T>
* @param sql
* @param objs
* @return
*/
<T extends Serializable> T getObject(String sql,Class<T> clazz,Object[] objs);
/**
* 查詢一個Map集合
* @param sql
* @param objs
* @return
*/
Map<String,?> find(String sql,Object[] objs);
/**
* 批量操作
* @param sql
* @param objLs
*/
void batchOperate(String sql,List<?> objLs);
/**
* 判斷實體是否存在
* @param sql
* @param obj
* @return
*/
int isExist(String sql,Object[] obj);
/**
* 編輯操作
* @param sql
* @param obj
* @return
*/
int editObject(String sql,Object[] obj);
} (8)BaseDaoImpl.java 登錄功能的數據訪問層
/**
*
*/
package com.springTest.dao.impl;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.springTest.dao.BaseDao;
import com.springTest.util.DBUtil;
/**
* @author tushen
* @date Nov 5, 2011
*/
@Repository
public class BaseDaoImpl implements BaseDao {
@Autowired
private DBUtil util;
@Override
public void batchOperate(String sql, List<?> objs) {
util.batchOperate(sql, objs);
}
@Override
public int editObject(String sql, Object[] obj) {
return util.editObject(sql, obj);
}
@Override
public Map<String, ?> find(String sql, Object[] objs) {
return util.getMap(sql, objs);
}
@Override
public <T extends Serializable> List<T> getObjList(String sql,
Class<T> className, Object[] objs) {
return (List<T>)util.getObjList(sql, className, objs);
}
@Override
public int isExist(String sql, Object[] obj) {
return util.isExist(sql, obj);
}
@Override
public <T extends Serializable> void saveOrUpdateObject(String sql, T entry) {
util.addOrUpdate(sql, entry);
}
@Override
public <T extends Serializable> T getObject(String sql,Class<T> clazz,Object[] objs) {
return (T)util.getObject(sql, clazz, objs);
}
} (9)DBUtil.java 數據操作公共類
/**
*
*/
package com.springTest.util;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.stereotype.Repository;
/**
* @author tushen
* @date Nov 5, 2011
*/
@Repository(value="util")
public class DBUtil{
private Log log = LogFactory.getLog(DBUtil.class);
private SimpleJdbcTemplate simpleJdbcTemplate;
/**
* 添加或者更新數據
* @param sql
* @param obj
* @return
*/
public Integer addOrUpdate(String sql,Object obj){
Integer id = 0;
try {
id = simpleJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(obj));
} catch (Exception e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return id;
}
/**
* 獲取List集合
* @param sql
* @param className
* @param obj
* @return
*/
@SuppressWarnings("unchecked")
public List<?> getObjList(String sql,Class<?> className,Object[] obj){
List<?> array = null;
try {
array = simpleJdbcTemplate.queryForList(sql,
ParameterizedBeanPropertyRowMapper.newInstance(className),
obj);
} catch (Exception e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return array;
}
/**
* 獲取Map集合值
* @param sql
* @param obj
* @return
*/
public Map<String,?> getMap(String sql,Object[] obj){
Map<String, ?> map = null;
try {
map = simpleJdbcTemplate.queryForMap(sql, obj);
} catch (Exception e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return map;
}
/**
* 獲取相應的Object
* @param sql
* @param className
* @param obj
* @return
*/
public Object getObject(String sql,Class<? extends Serializable> className,Object[] obj){
Object object = null;
try {
object = simpleJdbcTemplate.queryForObject(sql, BeanPropertyRowMapper.newInstance(className), obj);
} catch (DataAccessException e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return object;
}
/**
* 批量操作
* @param sql
* @param obj
* @return
*/
public int[] batchOperate(String sql,List<?> obj){
int[] a = null;
try {
a = simpleJdbcTemplate.batchUpdate(sql,
SqlParameterSourceUtils.createBatch(obj.toArray()));
} catch (Exception e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return a;
}
/**
* 檢查是否有值
* @param sql
* @param obj
* @return
*/
public int isExist(String sql,Object[] obj){
int index = 0;
try {
index = simpleJdbcTemplate.queryForInt(sql, obj);
} catch (Exception e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return index;
}
/**
* 編輯操作(增刪改查都可以)
* @param sql
* @param obj
* @return
*/
public int editObject(String sql,Object[] obj){
int index = 0;
try {
index = simpleJdbcTemplate.update(sql, obj);
} catch (DataAccessException e) {
log.info(e);
throw new DaoException("數據庫操作失敗!",e);
}
return index;
}
/**
* @param simpleJdbcTemplate the simpleJdbcTemplate to set
*/
@Resource(name="dataSource")
public void setSimpleJdbcTemplate(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
} (10)login.jsp 登錄頁面
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登陸</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">
-->
</head>
<body>
<form action="${ctx}/user/login" method="post">
userName:<input type="text" name="userName"><br/>
passWord:<input type="text" name="passWord"><br/>
<input type="submit" value="登陸">
</form>
</body>
</html> (11)database.properties 數據庫訪問配置
mysql.driverclass=com.mysql.jdbc.Driver mysql.jdbcurl=jdbc:mysql://127.0.0.1:3306/test mysql.user=root mysql.password=admin
(12)User.java 實體
/**
*
*/
package com.springTest.po;
import java.io.Serializable;
/**
* @author tushen
* @date Nov 4, 2011
*/
public class User implements Serializable{
private Integer id;
private String userName; //用戶名
private String passWord; //密碼
private String firstName;
private String lastName;
private String birthday; //生日
private Integer age;
/**
* @return the id
*/
public Integer getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* @return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* @param firstName the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* @param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* @return the age
*/
public Integer getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(Integer age) {
this.age = age;
}
/**
* @return the userName
*/
public String getUserName() {
return userName;
}
/**
* @param userName the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* @return the passWord
*/
public String getPassWord() {
return passWord;
}
/**
* @param passWord the passWord to set
*/
public void setPassWord(String passWord) {
this.passWord = passWord;
}
/**
* @return the birthday
*/
public String getBirthday() {
return birthday;
}
/**
* @param birthday the birthday to set
*/
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}
附錄數據庫腳步如下:
/*
SQLyog v10.2
MySQL - 5.0.87-community-nt : Database - test
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`test` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `test`;
/*Table structure for table `user` */
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`username` varchar(64) default NULL,
`password` varchar(32) default NULL,
`first_name` varchar(32) default NULL,
`last_name` varchar(32) default NULL,
`birthday` date default NULL,
`age` int(11) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `user` */
LOCK TABLES `user` WRITE;
insert into `user`(`username`,`password`,`first_name`,`last_name`,`birthday`,`age`)
values ('admin','123456',NULL,NULL,NULL,NULL),('liaoxj','123456','liao','xiongjian','1988-06-21',25),('changjiang','123456','zhang','liang','2013-01-01',25);
UNLOCK TABLES;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;