1. 程式人生 > >spring入門例項詳解

spring入門例項詳解

spring框架在我們的開發中用到的很多,前面幾篇部落格也理解了一下spring的基本概念,現在準備寫一個spring框架的入門例項,以一個登陸認證簽到模組為例子;

例項說明:

登陸簽到模組其實很簡單,首先使用者輸入網址,然後系統進入歡迎頁面,在歡迎頁面填寫賬號和密碼的表單,點選提交到服務端,檢查使用者名稱密碼,是否匹配,如果匹配就記錄登陸日誌,顯示登陸成功,在登陸成功頁面有一個點選簽到功能,點選簽到會送5個積分,一天只能簽到一次,這裡要進行驗證一下。如果登陸不成功就返回到登陸頁面,並給出提示;

整體流程:

1.使用者登陸網址,web服務會進入預設頁面,login.jsp;

2.login.jsp是一個帶有賬號密碼的表單,使用者要輸入賬號密碼點選提交;

3.提交到web伺服器裡,web伺服器會找到我們的spring配置,並根據配置找到我們的controller;

4.在controller裡面,呼叫service方法,根據使用者名稱和密碼查詢是否存在匹配的使用者;

5.service去呼叫我們的dao方法,dao方法與資料庫進行互動查詢並得到最終結果;

6.如果沒有找到與之匹配的使用者,那麼就返回登陸頁面,並給出錯誤提示;

7.如果找到與之匹配的使用者,進入歡迎頁面列印使用者資訊。

8.點選簽到,判斷該使用者是今天第一次登陸則可以點選簽到,如果不是則不能點選。

9.點選簽到後,會找到其對應的controller,然後去呼叫service和dao方法,給該使用者增加5積分;

準備工作:

資料庫:

在進行開發之前要先做一點準備工作,其中最主要的就是建立資料庫,這裡我採用的是MySQL資料庫,簡單好用;

##使用者表
create table sys_user(
user_id int auto_increment primary key,
user_name varchar(32),
user_password varchar(32),
credits int,
last_visit datetime,
last_ip varchar(32)
##使用者登入日誌表
create table sys_login(
login_id int auto_increment primary key,
user_id int,
login_sign int,
login_ip varchar(32),
login_datetime datetime
)

這裡我們再初始化一條記錄,方便我們登陸
insert into sys_user(user_name,user_password) values('admin','123456');

配置資訊:

1.首先建立一個web專案,然後找到WebRoot下面的WEB_INF下面的web.xml;配置我們的登陸頁面;

<welcome-file-list>
	<welcome-file>login.jsp</welcome-file>
</welcome-file-list>

2.在web.xml裡面配置一下spring的基本資訊;spring可以將所有的配置資訊都統一到一個檔案中,也可以放置到多個檔案中,對於簡單的專案來說,由於配置資訊少,一個檔案就夠了,這裡我們使用spring的擴充套件容器,不適用spring的父容器,採用servlet載入的方式得到我們的擴充套件容器;

<span style="font-size:14px;"><!-- 配置 DispatcherServlet -->
	<servlet>
		<servlet-name>dispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 配置 DispatcherServlet 的一個初始化引數: 配置 SpringMVC 配置檔案的位置和名稱 -->
		<!-- 實際上也可以不通過 contextConfigLocation 來配置 SpringMVC 的配置檔案, 而使用預設的. 預設的配置檔案為: 
			/WEB-INF/<servlet-name>-servlet.xml -->
		<!-- <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> 
			</init-param> -->
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>dispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping></span>
3.匯入架包,這裡使用的是spring4 版本;匯入到WebRoot下面WEB_INF下面的lib下面


配置一下spring容器,以後需要什麼功能再新增:

<pre name="code" class="html"><?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:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

	<!-- 配置自定掃描的包 -->
	<context:component-scan base-package="com.cn.*"></context:component-scan>
	<bean id="configure"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:/dbconfig.properties" />
	</bean> 
	<!-- 配置一個使用DBCP的資料來源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${db.driverClassName}" />
		<property name="url" value="${db.url}${db.basename}" />
		<property name="username" value="${db.username}" />
		<property name="password" value="${db.password}" />
	</bean>
	
	<!-- 定義JDBC模板Bean -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 配置事務管理器 -->
	<bean id="transactionManager" 
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 通過AOP配置實務增強 -->
	<aop:config proxy-target-class="true">  
        <aop:pointcut expression="execution(* com.cn.service..*(..))" id="serviceMethod"/>  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>  
    </aop:config>  
     
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="*"/>  
        </tx:attributes>  
    </tx:advice>  
	
	<!-- 配置檢視解析器: 如何把 handler 方法返回值解析為實際的物理檢視 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<!-- 啟動 @AspectJ 支援 --> 
 	<aop:aspectj-autoproxy/> 
	<!-- 在實際開發中通常都需配置 mvc:annotation-driven 標籤 -->
	<mvc:annotation-driven></mvc:annotation-driven>

</beans>

持久層:

現在市面有很多ORM框架,像hibernate,mybatis,springjpa這些我都用過,個人最喜歡用mybatis了,使用持久層主要是對資料的訪問和操作與資料庫進行互動。spring對這些框架提供了良好的支援,今天就用一個比較原始的框架springJDBC作為持久層的實現技術。

模型層:

模型層也叫實體類,它代表了與真實世界的事物,也可以用來表示業務的狀態。一般來說實體類屬於業務層,和我們的業務直接掛鉤的,但是它貫穿了整個MVC,並被持久化到資料庫中。模型層使得我們以面向物件的形式開發專案,為程式的擴充套件和維護帶來了很大的方便,一個模型往往對應於資料庫的一張表,但是也可以擴展出自己想要的模型,這使得我們的程式更加靈活。在java程式中,一個模型也代表一個javabean;

使用者模型:使用者模型與之對應的是我們的sys_user表,一下省略get,set和構造器方法;

/*/
 * 使用者模型
 */
public class SysUser implements Serializable{
	private int userId; //使用者主鍵
	private String userName; //使用者賬戶名
	private String userPassword;//使用者密碼
	private int credits; //積分
	private String lastIp; //IP地址
	private Date lastVisit;  //登陸時間
登陸日誌模型:

使用者登陸成功之後就會產生一條登陸日誌,所以我們會有一個登陸日誌模型;

public class SysLogin implements Serializable{
	private int loginId; //登陸日誌主鍵
	private int userId; //使用者外來鍵
	private String loginIp; //登陸IP
	private int loginSign; //是否簽到
	private Date loginDatetime; //登陸時間

好了,準備工作做完了,接下來我們就一步一步的來做專案;

屬性檔案:

<span style="font-size:18px;">db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/
db.basename=test
db.username=root
db.password=root</span>

一步一步構造專案:

我們再構造專案的時候一定要一步一步的來,你可以從下到上,先寫dao,再寫service,最後寫control。當然你也可以從外到內再到下,先寫jsp,再去呼叫control,接著往下走直到進入持久層。

那我們就先寫一個登陸頁面的jsp;

<form action="login" method="post">
 			賬號:<input type="text" name="userName">
 			密碼:<input type="password" name="userPassword">
 			<input type="submit" value="登陸">
 		</form>
注意一下我們這裡的name屬性要和javaBean對應;

上面這個請求為login,那麼我們就去建立一個這樣的control;這裡control作為控制器,會判斷我們的使用者匹配程度,從而

進行頁面上的跳轉;

@RequestMapping(value="login")
	public String login(SysUser user,HttpServletRequest request){
		if(!userService.hasMatchUser(user))
			return "login";
		return "success";
	}


</pre><p><span style="font-size:18px">得到control之後,我們要去呼叫service方法,接著再去建立一個UserService;在開發的時候,我們儘量使用介面繼承,這樣可以達到,高內聚低耦合。</span></p><p></p><pre name="code" class="java">public interface UserService {
	
	public boolean hasMatchUser(SysUser user);

@Service
public class UserServiceImpl implements UserService{
	
	@Autowired
	private UserDao userDao;
	public boolean hasMatchUser(SysUser user) {
		int count=userDao.getMatchCount(user.getUserName(),user.getUserPassword());
		if(count>=1)
			return true;
		return false;
	}

這裡的service方法會接著往下呼叫Dao方法:它與我們的資料庫進行互動,

ublic interface UserDao {
	public int getMatchCount(String userName,String userPassword); //根據使用者名稱和密碼獲取匹配的使用者
@Repository
public class UserDaoImpl implements UserDao{
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	public int getMatchCount(String userName,String userPassword) {
		String sql=" select count(*) from sys_user where user_name=?  and  user_password=? ";
		int count=jdbcTemplate.queryForInt(sql,new Object[]{userName,userPassword});
		return count;
	}
到現在,我們的基本登陸方法都已經寫好了,開始啟動程式測試一下,測試成功如果沒有問題就接著完善功能,如果有問題,可能就是細節上的錯誤,這個錯誤就要通過Debug和搜尋引擎進行修改了;

接下來把我們的方法都給完善一下。首先登陸進去之後,我們會去匹配賬號和密碼,如果沒有匹配到就返回登陸頁面,重新登陸,如果登陸成功之後我們就新增登陸日誌。在新增登陸日誌的時候我們會去判斷一下他今天是否簽到,

我們取出此賬號最後一次的登陸時間判斷它是否與今天的時間相等,如果不相等,那麼就證明他今天沒有登陸過,我們會給userBean新增一個標示。

private boolean signStatus; //簽到狀態
在登陸的時候修改簽到狀態,然後在頁面進行簽到流程的控制;
<body>
                         登陸成功!<br>
       <%
         SysUser user=(SysUser)request.getSession().getAttribute("user");
        if(!user.isSignStatus()){
        %>
        	<form action="loginSign" method="post">
        	<input type="submit" value="簽到"> 
        	</form>
        	<%} %>
  </body>

點選簽到後,會去修改他的積分,在修改積分後會新增一條登陸日誌,修改他的狀態為已經簽到;
@RequestMapping(value="login")
	public String login(SysUser user,HttpServletRequest request){
		if(!userService.hasMatchUser(user))
			return "login";
		//新增登陸日誌
		try {
			user=userService.findUserByName(user.getUserName());
			SysLogin login=loginService.getLogin(user.getUserId());
			int toDate=TestUtil.toDate(new Date()); //獲得今天的時間
			int yestDate=TestUtil.toDate(login.getLoginDatetime());  //獲得最後一次的登陸時間
			if(toDate==yestDate){
				if(login.getLoginSign()==1)
				user.setSignStatus(true);
			}
			request.getSession().setAttribute("user", user); //登陸成功之後把使用者放入session裡面
			loginService.insertLogin(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "success";
	}


所以我們會有查詢最後一次登陸資訊的方法,新增登陸日誌的方法,修改登陸日誌的方法,修改使用者資訊的方法。
方法在這裡就不貼出來了,有興趣的可以去下載原始碼。

總結一下:啟動程式挺花時間的,書上沒有說提供哪些Jar包,根據英文提示一個個的去比對,還好程式跑起來了,整個模組其實很簡單。但是準備工作挺多的,歸納起來也不容易,但是大腦裡面的思維會清晰很多。以後要多多學習歸納總結,來提高自己。本來放假三天就可以寫好的,但是放假出去玩了一會,所以只好犧牲下午的一點時間來完善這篇博文,寫到後面也倦了點,希望各位看官不要嫌棄湊合著將近吧。