作者:实验室2015级刘雪薇

本文将介绍在javaSE基础之上如何利用Spring框架制作登录模块实例。

注:本文大部分指导、代码来自陈雄华《Spring3.x企业应用开发实战》,但是鉴于Spring已经更新至4,因此不建议读者使用此书入门。(笔者已亲身试错……)

感谢刘力超、江健、马名骏三位师兄3个小时不间断的单方面碾压凌虐式Code Review,笔者受益匪浅,感激感恩感谢。

我不会用专业术语,很多描述上都有不尽不实的地方,在我多看了一些书后会回来修改下的。

模块需求

首先登录界面提供一个带用户名和密码的输入表单,用户填写并提交表单后,服务端检查是否有匹配的用户名和密码,如果用户名密码不匹配,返回到登录界面并给出提示。如果用户名、密码匹配,记录用户的成功登录日志,更新用户的最后登录时间和IP并给用户增加5个积分,然后重定向至欢迎页面。

开始之前

建立maven工程

在开始学习和使用Spring之前,必须先获取Spring的包。使用Maven构建Spring项目是一个很好的选择,只要通过配置文件引用Maven仓库即可。

使用eclipse建立maven项目后,在路径下pom.xml配置文件中引入相关的依赖jar包,如下:

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.lab</groupId>
	<artifactId>demo1</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo1MavenWebapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<java-version>1.7</java-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
		<!--Spring-->
		<spring-framework.version>4.1.6.RELEASE</spring-framework.version>
		<!--Junit-->
		<junit.version>4.11</junit.version>
		<!--Jackson-->
		<jackson.version>2.6.0</jackson.version>
	</properties>
	<dependencies>
		<!--Spring-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
			<exclusions>
				<!--ExcludeCommonsLogginginfavorofSLF4j-->
				<exclusion>
				<groupId>commons-logging</groupId>
				<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		
		<!--SpringWebSocket-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-websocket</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-messaging</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		
		<!--jackson-->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		
		<!--AspectJ-->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>
		
		<!--Logging-->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
		<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>
		
		<!--@Inject-->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
	
		<!--commons.dbcp数据库连接池-->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.1.1</version>
		</dependency>
		
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>
	
		<!--Servlet-->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		
		<!--Test-->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>demo1</finalName>
	</build>
</project>

需要的jar包均已在dependency中引入,但是这其中也引入了一些冗余的包,欢迎有志之读者精简之。(因为这个是我从人家电脑上扒的……懒得筛)

另外,如果你像我一样没有安装mysql数据库也没有mysql基础的话,请发挥您的搜索意识,自行百度。

完成数据库建表。数据库名称为sampledb,创建t_user(用户信息表)和t_login_log(用户登录日志表)作为实例所用的两张表。在t_user表里初始化一条数据:用户名/密码为admin/123456。

类包规划

类包以分层的方式进行组织,共划分为四个包,分别是dao,daomin,service和web。领域对象从严格意义讲属于业务层,但由于领域对象可能还同时被持久层和展现层共享,所以一般将其单独划分到一个包中。

(注:一开始我以为类包规划是个挺重的东西,后来发现其实它也就是个习惯。当然,在学习之初养成良好的习惯很重要。)

在看下面的内容前,想想一下,如果你直接上手,你会写什么?

写几个对象,在哪里实例化?谁来访问?写什么样的方法?写在哪里?如何分配接口?

如果你了然于胸……那你就不要看了。

如果你一团浆糊的话,那请继续看下去,因为开始前我是直接抄代码往下写的。

现在回过头来,我尝试解释一下这个demo的结构。这种解读是缺乏专业基础的后验式解读。

在整个demo结构中,有两个对象是贯穿于demo的整个生命周期中的,就是user对象和log对象。登录的所有功能实现都围绕着这两个对象内数据改变展开。这两个对象的对应的数据库与java的连接需要靠DAO层实现(这部分就是使用orm框架或是Jdbc语句的范畴)。service业务层是业务逻辑的实现,controller响应需求并在后台自动运行。(这部分使用的是Spring MVC)

Spring MVC

在展示代码的时候我也同样选择了从controller入手,它是处理登录请求并响应,根据登录成功与否选择是否跳转到欢迎或失败页面。这在我看来更容易理解(但是并不容易写……)。

bean的注解配置和配置文件配置异同自行百度吧亲

package web;//这种命名是错误的,别学我

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

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.servlet.ModelAndView;

import domin.User;
import service.UserService;

//标注一个成为mvc的controller
@Controller
public class LoginController {
	
	@Autowired
	private UserService userService;
	
	//负责处理/index.html的请求
	@RequestMapping(value="/index")
	public String loginPage(){
		return "login";
	}
	
	//负责处理/loginCheck.html的请求
	@RequestMapping(value = "/loginCheck",method=RequestMethod.POST)
	public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){
		boolean isValidUser = userService.hasMatchUser(loginCommand.getUserName(), loginCommand.getPassword());
		System.out.println(loginCommand.getUserName());
		System.out.println(loginCommand.getPassword());
		if(!isValidUser){
			return new ModelAndView("login","error","用户名或密码错误");
		}else{
			User user = userService.findUserByUserName(loginCommand.getUserName());
			user.setLastip(request.getRemoteAddr());
			user.setLastVisit(new Date());
			userService.loginSuccess(user);
			//
			request.getSession().setAttribute("user", user);
			return new ModelAndView("main");
		}
	}
}

@RequestMapping制定方法如何映射请求路径:它既可以返回一个ModelAndView对象,也可以返回一个字符串,解析返回相应响应页面。

返回ModelAndView对象给前端控制器以控制页面,既包含数据又包含视图信息。(这个对象的具体用法请见源码,小技巧是在eclipse里按住ctrl点击相应方法对象等,即可打开源码查看具体用法!!这是一个非常非常实用的自学技巧。要是打开了显示不出来,注意联网,它自己会下载的。)

使用到的的LoginCommand对象是一个POJO(普通JavaBeans != bean),仅包含用户和密码。

//pojo的格式是用于数据的临时传递,它只能装载数据, 作为数据存储的载体,而不具有业务逻辑处理的能力。

package web;

public class LoginCommand {
	private String userName;
	private String password;
        //private对象必须写get,set方法方能正常读写,读者可通过ide自动生成而不用手动输入。
}

SpringMVC配置文件如下

<?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: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-3.2.xsd   
    http://www.springframework.org/schema/tx   
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.2.xsd  
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">  
 
  
    <!--1默认的注解映射的支持,自动注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->  
    <mvc:annotation-driven />  
  	<context:component-scan base-package="web"></context:component-scan>

    <!-- 2视图解释类 -->  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/jsp/"/>  
        <property name="suffix" value=".jsp"/>  
    </bean>  
      
    <!-- 3对静态资源文件的访问-->  
    <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>  
    <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>  
    <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>  
  
</beans>   

1.扫描包启动注解配置。2视图路径解析增加前后缀3引入静态文件(这里是用不着的因为根本没有~)

然后就把JSP顺手也看了,这个登录只有两个页面,login和main。只有html基础的读者也可以轻松理解jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix ="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title></title>
</head>
<body>
	<c:if test="${!empty error }">
	<font color="red">${error }</font>
	</c:if>
	<form action="<c:url value="/loginCheck"/>" method="post">
		用户名:
		<input type="text" name="userName">
		<br>
		密码:
		<input type="password" name="password">
		<br>
		<input type="submit" value= "登录"/>
		<input type="reset" value="重置"/>
	</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>登陆成功</title>
</head>
<body>
	${user.userName},欢迎您进入。您当前积分为${user.credits};
</body>
</html>

Service

(感觉我在倒着讲代码……不过我觉得构思的时候应该也是这个思路?)

业务层只有一个业务类,UserService,完成功能:密码认证、登录日志;

这部分就比较实际了,我个人的感觉就是这部分就是自己随便写的单机小程序和web程序间的差异。

UserService代码如下。

package service;//com.demo.service才是正道……

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import dao.LoginLogDao;
import dao.UserDao;
import domin.LoginLog;
import domin.User;


@Service
public class UserService {
	@Autowired
	private UserDao userDao;
	
	@Autowired
	private LoginLogDao loginLogDao;
	
	//用户密码认证
	public boolean hasMatchUser(String userName, String password){
		int matchCount = userDao.getMatchCount(userName, password);
		return matchCount >0;
	}
	
	
	//以用户名为条件加载User对象
	public User findUserByUserName(String userName){
		return userDao.findUserByUserName(userName);
	}
	
	/**
	 * 用户登录成功后调用
	 * @param user 
	 */
	public void loginSuccess(User user){
		user.setCredits( 5 + user.getCredits());
		LoginLog loginLog = new LoginLog();
		loginLog.setUserId(user.getUserId());
		loginLog.setIp(user.getLastip());
		loginLog.setLoginDate(user.getLastVisit());;
		userDao.updateLoginIngo(user);
		loginLogDao.insertLoginLog(loginLog);
		
	}

}

这里插一句:要是学javaSE只跟着书老老实实地写了几个练习题,就会对JavaEE这个代码示例的构建方法感觉陌生。初学者的练习题中,由于结构简单,一个类的Field中引入的其他类往往就在这个类文件中写了,所以练习题大部分都是一个文件的形式;但是学JavaEE时,一上手就已经是比较正统的工程整体式开发,java文件有非常严格的层级划分,所以不同的类写在自己不同的文件、放在不同的包里。这一点菜鸟既不能习惯,也 会对理解工程增加困难。我建议在一开始理解代码时是不要太拘泥于一个又一个文件,一个又一个窗口,而是先想象所有类都在一个窗口内,在想象中安排他们各自的顺序最终符合自己的逻辑顺序;并且把POJO对象单拎出来因为它不符合菜鸟开发的习惯。

//至于构思的时候应该怎么思考……我也没搞清楚……熟能生巧吧。

至于这个Bean呢,我觉得挺难解释的。首先,它应该是一个实例,背后拥有实现类,不是方法;二,它应该是可复用的,组件;三,它是由Spring容器直接控制实例化的。我能看到的最直观的好处——在别层java类中实例化Bean对象不用写包名……

有两个网页说的比我好,使用Spring容器Bean基本概念。同样都是看一本书,人家读书笔记洋洋洒洒,我看得囫囵吞枣。

//直接学比较先进的框架而没学过之前的甚至是底层实现就有这个麻烦:书里告诉说,这个机制如何完善如何完善,可是菜鸟看了一脸懵逼:我一开始学的不就是这样吗?能有多麻烦?没有比较就无法对这些进步产生直观的感受……所以直接当语法照着写吧,反正我也不会其他方法,下次再看见两页宣传进步性的直接跳过即可,那是给学过历史版本的人看的。

DAO

DAO(Data Access Object) 数据访问对象是面向对象的数据库接口。

用Hibernate最好但是我还不会用。所以这里都是原始的JDBC语句…… 不是说JDBC易学方便,而是教程上用的这个我方便直接抄。

UserDao:

package dao;//说了包名别学我!!!

import java.sql.ResultSet;
import java.sql.SQLException;

import org.aspectj.weaver.NewConstructorTypeMunger;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
import org.springframework.validation.annotation.Validated;

import domin.User;

@Repository 
public class UserDao {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	//根据用户名和密码获取匹配的用户数
	public int getMatchCount(String userName, String password){
		String sqlStr = "select count(*) from t_user  "
				+" where user_name = ? and password = ?";
		return jdbcTemplate.queryForInt(sqlStr, new Object[]{ userName,password});//这个过时了
		
	}
	
	
	//根据用户名获取User对象
	public User findUserByUserName(final String userName){
		
		String sqlStr = " SELECT user_id,user_name,credits "
				+" FROM `t_user` WHERE user_name = ? ";
		final User user = new User();
		jdbcTemplate.query(sqlStr, new Object[]{userName},
			new RowCallbackHandler() {
			
				
				@Override
				public void processRow(ResultSet rs) throws SQLException {
					user.setUserId(rs.getInt("user_id"));
					user.setUserName(userName);
					user.setCredits(rs.getInt("credits"));
				}
			});
		return user;
	}
	
	//更新用户积分、最后登录ip和最后登录时间
	public void updateLoginIngo(User user){
		String sqlStr = " UPDATE t_user SET last_vist=?,last_ip=?,credits=? "
				+" WHERE user_id = ?";
		jdbcTemplate.update(sqlStr, new Object[] {user.getLastVisit(),
			user.getLastip(),user.getCredits(),user.getUserId()});
	}
	
}

这个jdbcTemplate就是一个我要使用Jdbc时要用的Bean,回头在配置文件里定义一下。@Autowired是用来自动装配Bean的,所有Bean在Spring容器自动启动时就会自动实例化

附上jdbcTemplate所在的配置文件

<?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:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:p="http://www.springframework.org/schema/p"
	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/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

	<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
	<context:component-scan base-package="dao"></context:component-scan>
	<context:component-scan base-package="web"></context:component-scan>
	
	<!-- 扫描service类包,应用Spring的注解配置 -->
	<context:component-scan base-package="service"></context:component-scan>
	
	<!-- 定义一个使用DBCP实现的数据源 -->
	<bean id = "dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
	 destroy-method="close"
	 p:driverClassName="com.mysql.jdbc.Driver"
	 p:url="jdbc:mysql://localhost:3309/sampledb"
	 p:username="root"
	 p:password="密码怎么能让你……嘿嘿嘿"
	></bean>
	
	<!-- 定义Jdbc模板Bean --> 
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
	 p:dataSource-ref="dataSource"></bean>
 	
 	<!-- 配置事务管理器 -->
 	<bean id="transactionManager"
 		class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
	 	p:dataSource-ref="dataSource"></bean>
	 	
	<!-- 通过AOP配置提供事务增项,让service包下所有Bean的所有方法拥有事务 -->
	<aop:config proxy-target-class="true">
		<aop:pointcut expression="execution(* service..*.*(..))" id="serviceMethod"/>
		<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>
		</aop:config>
		<tx:advice id="txAdvice" transaction-manager="transactionManager">
			<tx:attributes>
				<tx:method name="*"/>
			</tx:attributes>
		</tx:advice>
		
</beans>

如果要配置其他Bean也要在<beans></beans>这里。事务管理器什么的用来写着玩吧,用不到。

 

然后是LoginDao

package dao;//你知道为啥举手之劳可我就是不改包名?因为配置文件里有相应的路径,,可我记不清楚怕改少了用不了……


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import domin.LoginLog;

@Repository
public class LoginLogDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public void insertLoginLog(LoginLog loginLog){
		String sqlStr = " INSERT INTO t_login_log(user_id,ip,login_datetime) "
				+ " VALUES(?,?,?)";
		Object[] args = { loginLog.getUserId(),loginLog.getIp(),loginLog.getLoginDate()};
		jdbcTemplate.update(sqlStr,args);
		
	}
}

我觉得读者根据以上可以自己推出User和LoninLog两个POJO里到底要写什么,留个作业自行解决。

web.xml

SpringMVC和Spring的配置文件前面都已经给出。这个web.xml是web工程一般性的配置文件,具体怎么配置我也没看懂,大概是包括监听器(listener)和SpringMVC适配器(servlet)两块。

配置文件啥的上网一搜,复制粘贴,大致浏览一下按需求删减即可,大同小异。

<?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/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
    id="WebApp_ID" version="3.0">   
  <listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
   </listener> 
	<!--contextConfigLocation在 ContextLoaderListener类中的默认值是 /WEB-INF/applicationContext.xml-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
  <!-- ================spring mvc 适配器================ -->  
    <servlet>  
        <servlet-name>springMVC</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <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>springMVC</servlet-name>  
        <url-pattern>/</url-pattern>  
    </servlet-mapping>  
    
    <welcome-file-list>  
        <welcome-file>index.html</welcome-file>  
    </welcome-file-list>  
</web-app>  

然后在Eclipse里运行一下就ok了!

记得装Tomcat。

over