zoukankan      html  css  js  c++  java
  • 【Spring实战-1】网站登录系统

    系统概述:

    2015年5月8日 14:05:49 
    本系统为一个常规的用户登录系统,主要完成了用户登录界面设计、用户登录后信息校验、更新用户登录信息以及记录用户登录信息等。
    整个系统以Spring框架为基础来实现,项目构架时进行了分层设计,主要包括:持久层、业务层、控制层以及POJO(demain);
    本系统使用的技术为:
    1. 数据库:MySQL;
    2. 数据库操作:Spring jdbc;
    3. MVC框架,Spring MVC;
    4. 容器:Spring容器;


    涉及到的技术点:

    1.  使用 JdbcTemplate 实现Mysql数据库的增、删、改、查操作;
    2.  注解的使用:
         @Repository:注解持久层(dao)bean;
         @Service:注解业务层bean;
         @Controller:展现层(控制层)bean,标注为Spring mvc的控制器;
         @Autowired:将Spring容器中的bean注入进来;
         @ContextConfiguration:指定Spring配置文件的位置;
         @RequestMapping:指定如何映射请求地址;

    3. RowCallbackHandler:查询结果处理的回调接口,实现ResultSet到POJO对象的转换;

    4. 事务管理器:为数据库操作实现事务;

    5. 引入shema命名空间:
      p: 用于简化类的成员变量;
      tx:
     aop:

    6. 利用junit进行测试;

    7. 配置Spring容器:配置Spring容器所必须的两个参数(web.xml)

    1. <!-- 从类路径下加载Spring配置文件,classpath关键字特指从类路径下加载 -->
    2. <context-param>
    3. <param-name>contextConfigLocation</param-name>
    4. <param-value>classpath:applicationContext.xml</param-value>
    5. </context-param>
    6. <!-- 负责启动Spring容器的监听器 -->
    7. <listener>
    8. <listener-class>
    9. org.springframework.web.context.ContextLoaderListener
    10. </listener-class>
    11. </listener>



    8. 配置Spring MVC:(web.xml)
    1. <!-- 配置Spring MVC,其对应的配置文件为:servlet-name-servlet.xml,
    2. 本项目的为:baobaotao-servlet.xml -->
    3. <servlet>
    4. <servlet-name>baobaotao</servlet-name>
    5. <servlet-class>
    6. org.springframework.web.servlet.DispatcherServlet
    7. </servlet-class>
    8. <load-on-startup>3</load-on-startup>
    9. </servlet>
    10. <servlet-mapping>
    11. <servlet-name>baobaotao</servlet-name>
    12. <url-pattern>*.html</url-pattern>
    13. </servlet-mapping>

    9. Spring声明式事务;
    这个以后在具体介绍。

    项目整体布局

    项目整体布局:
     
    主要包括src和test,其中test为junit测试类,主要用于测试业务层;

    使用的jar包

    下面是配置文件及前端界面等;


    Mysql数据库指令

    1. DROP DATABASE IF EXISTS sampledb;
    2. CREATE DATABASE sampledb DEFAULT CHARACTER SET utf8;
    3. USE sampledb;
    4. ##创建用户表
    5. CREATE TABLE t_user (
    6. user_id INT AUTO_INCREMENT PRIMARY KEY,
    7. user_name VARCHAR(30),
    8. credits INT,
    9. password VARCHAR(32),
    10. last_visit datetime,
    11. last_ip VARCHAR(23)
    12. )ENGINE=InnoDB;
    13. ##创建用户登录日志表
    14. CREATE TABLE t_login_log (
    15. login_log_id INT AUTO_INCREMENT PRIMARY KEY,
    16. user_id INT,
    17. ip VARCHAR(23),
    18. login_datetime datetime
    19. )ENGINE=InnoDB;
    20. ##插入初始化数据
    21. INSERT INTO t_user (user_name,password)
    22. VALUES('admin','123456');
    23. COMMIT;

    上述指令执行完成后,在Mysql创建的情况如下:




    源程序

    com.baobaotao.domain包:定义POJO对象

    LoginLog.java

    1. package com.baobaotao.domain;
    2. import java.io.Serializable;
    3. import java.util.Date;
    4. public class LoginLog implements Serializable{
    5. private int loginLogId;
    6. private int userId;
    7. private String ip;
    8. private Date loginDate;
    9. public String getIp() {
    10. return ip;
    11. }
    12. public void setIp(String ip) {
    13. this.ip = ip;
    14. }
    15. public Date getLoginDate() {
    16. return loginDate;
    17. }
    18. public void setLoginDate(Date loginDate) {
    19. this.loginDate = loginDate;
    20. }
    21. public int getLoginLogId() {
    22. return loginLogId;
    23. }
    24. public void setLoginLogId(int loginLogId) {
    25. this.loginLogId = loginLogId;
    26. }
    27. public int getUserId() {
    28. return userId;
    29. }
    30. public void setUserId(int userId) {
    31. this.userId = userId;
    32. }
    33. }



    User.java

    1. package com.baobaotao.domain;
    2. import java.io.Serializable;
    3. import java.util.Date;
    4. public class User implements Serializable{
    5. private int userId;
    6. private String userName;
    7. private String password;
    8. private int credits;
    9. private String lastIp;
    10. private Date lastVisit;
    11. public String getLastIp() {
    12. return lastIp;
    13. }
    14. public void setLastIp(String lastIp) {
    15. this.lastIp = lastIp;
    16. }
    17. public Date getLastVisit() {
    18. return lastVisit;
    19. }
    20. public void setLastVisit(Date lastVisit) {
    21. this.lastVisit = lastVisit;
    22. }
    23. public int getUserId() {
    24. return userId;
    25. }
    26. public void setUserId(int userId) {
    27. this.userId = userId;
    28. }
    29. public String getUserName() {
    30. return userName;
    31. }
    32. public void setUserName(String userName) {
    33. this.userName = userName;
    34. }
    35. public String getPassword() {
    36. return password;
    37. }
    38. public void setPassword(String password) {
    39. this.password = password;
    40. }
    41. public int getCredits() {
    42. return credits;
    43. }
    44. public void setCredits(int credits) {
    45. this.credits = credits;
    46. }
    47. }

    com.baobaotao.dao包

    LoginLogDao.java

    1. package com.baobaotao.dao;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.jdbc.core.JdbcTemplate;
    4. import org.springframework.stereotype.Repository;
    5. import com.baobaotao.domain.LoginLog;
    6. @Repository
    7. public class LoginLogDao {
    8. @Autowired
    9. private JdbcTemplate jdbcTemplate;
    10. /**
    11. * 插入登录信息
    12. * @param loginLog
    13. */
    14. public void insertLoginLog(LoginLog loginLog) {
    15. String sqlStr = "INSERT INTO t_login_log(user_id,ip,login_datetime) "
    16. + "VALUES(?,?,?)";
    17. Object[] args = { loginLog.getUserId(), loginLog.getIp(),
    18. loginLog.getLoginDate() };
    19. jdbcTemplate.update(sqlStr, args);
    20. }
    21. }


    UserDao.java

    1. package com.baobaotao.dao;
    2. import java.sql.ResultSet;
    3. import java.sql.SQLException;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.jdbc.core.JdbcTemplate;
    6. import org.springframework.jdbc.core.RowCallbackHandler;
    7. import org.springframework.stereotype.Repository;
    8. import com.baobaotao.domain.User;
    9. @Repository
    10. public class UserDao {
    11. @Autowired
    12. private JdbcTemplate jdbcTemplate;
    13. /**
    14. * 获取匹配的用户数量
    15. * @param userName
    16. * @param password
    17. * @return
    18. */
    19. public int getMatchCount(String userName, String password) {
    20. String sqlStr = " SELECT count(*) FROM t_user "
    21. + " WHERE user_name =? and password=? ";
    22. return jdbcTemplate.queryForInt(sqlStr, new Object[] { userName, password });
    23. }
    24. /**
    25. * 查询用户
    26. * @param userName
    27. * @return
    28. */
    29. public User findUserByUserName(final String userName) {
    30. String sqlStr = " SELECT user_id,user_name,credits "
    31. + " FROM t_user WHERE user_name =? ";
    32. final User user = new User();
    33. jdbcTemplate.query(sqlStr, new Object[] { userName },
    34. new RowCallbackHandler() {
    35. public void processRow(ResultSet rs) throws SQLException {
    36. user.setUserId(rs.getInt("user_id"));
    37. user.setUserName(userName);
    38. user.setCredits(rs.getInt("credits"));
    39. }
    40. });
    41. return user;
    42. }
    43. /**
    44. * 更新登录信息
    45. * @param user
    46. */
    47. public void updateLoginInfo(User user) {
    48. String sqlStr = " UPDATE t_user SET last_visit=?,last_ip=?,credits=? "
    49. + " WHERE user_id =?";
    50. jdbcTemplate.update(sqlStr, new Object[] { user.getLastVisit(),
    51. user.getLastIp(),user.getCredits(),user.getUserId()});
    52. }
    53. }



    com.baobaotao.service包

    UserService.java

    1. package com.baobaotao.service;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Service;
    4. import com.baobaotao.dao.LoginLogDao;
    5. import com.baobaotao.dao.UserDao;
    6. import com.baobaotao.domain.LoginLog;
    7. import com.baobaotao.domain.User;
    8. @Service
    9. public class UserService {
    10. @Autowired
    11. private UserDao userDao;
    12. @Autowired
    13. private LoginLogDao loginLogDao;
    14. /**
    15. * 是否有匹配的用户
    16. * @param userName
    17. * @param password
    18. * @return
    19. */
    20. public boolean hasMatchUser(String userName, String password) {
    21. int matchCount =userDao.getMatchCount(userName, password);
    22. return matchCount > 0;
    23. }
    24. /**
    25. * 根据用户名查找用户
    26. * @param userName
    27. * @return
    28. */
    29. public User findUserByUserName(String userName) {
    30. return userDao.findUserByUserName(userName);
    31. }
    32. /**
    33. * 登录成功时,更新登录信息并添加登录记录
    34. * @param user
    35. */
    36. public void loginSuccess(User user) {
    37. user.setCredits( 5 + user.getCredits()); //信用加5
    38. LoginLog loginLog = new LoginLog();
    39. loginLog.setUserId(user.getUserId());
    40. loginLog.setIp(user.getLastIp());
    41. loginLog.setLoginDate(user.getLastVisit());
    42. userDao.updateLoginInfo(user);
    43. loginLogDao.insertLoginLog(loginLog);
    44. }
    45. }


    com.baobaotao.web包

    LoginCommand.java

    1. package com.baobaotao.web;
    2. public class LoginCommand {
    3. private String userName;
    4. private String password;
    5. public String getPassword() {
    6. return password;
    7. }
    8. public void setPassword(String password) {
    9. this.password = password;
    10. }
    11. public String getUserName() {
    12. return userName;
    13. }
    14. public void setUserName(String userName) {
    15. this.userName = userName;
    16. }
    17. }


    LoginController.java

    1. package com.baobaotao.web;
    2. import java.util.Date;
    3. import javax.servlet.http.HttpServletRequest;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.servlet.ModelAndView;
    8. import com.baobaotao.domain.User;
    9. import com.baobaotao.service.UserService;
    10. @Controller
    11. public class LoginController{
    12. @Autowired
    13. private UserService userService;
    14. @RequestMapping(value = "/index.html")
    15. public String loginPage(){
    16. return "login";
    17. }
    18. @RequestMapping(value = "/loginCheck.html")
    19. public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){
    20. boolean isValidUser =
    21. userService.hasMatchUser(loginCommand.getUserName(),
    22. loginCommand.getPassword());
    23. if (!isValidUser) {
    24. return new ModelAndView("login", "error", "用户名或密码错误。");
    25. } else {
    26. User user = userService.findUserByUserName(loginCommand
    27. .getUserName());
    28. user.setLastIp(request.getLocalAddr());
    29. user.setLastVisit(new Date());
    30. userService.loginSuccess(user);
    31. request.getSession().setAttribute("user", user);
    32. return new ModelAndView("main");
    33. }
    34. }
    35. }

    说明:
    在mvc架构中,model和view是松耦合的,控制层负责产生model数据,而view负责渲染模型数据。
    request.getSession().setAttribute("user", user);
    return new ModelAndView("main");
    等价于:
    ModelAndView("main", "user", user);




    web.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app version="2.5"
    3. xmlns="http://java.sun.com/xml/ns/javaee"
    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    6. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    7. <!-- 从类路径下加载Spring配置文件,classpath关键字特指从类路径下加载 -->
    8. <context-param>
    9. <param-name>contextConfigLocation</param-name>
    10. <param-value>classpath:applicationContext.xml</param-value>
    11. </context-param>
    12. <!-- 负责启动Spring容器的监听器 -->
    13. <listener>
    14. <listener-class>
    15. org.springframework.web.context.ContextLoaderListener
    16. </listener-class>
    17. </listener>
    18. <!-- 配置Spring MVC,其对应的配置文件为:servlet-name-servlet.xml,
    19. 本项目的为:baobaotao-servlet.xml -->
    20. <servlet>
    21. <servlet-name>baobaotao</servlet-name>
    22. <servlet-class>
    23. org.springframework.web.servlet.DispatcherServlet
    24. </servlet-class>
    25. <load-on-startup>3</load-on-startup>
    26. </servlet>
    27. <servlet-mapping>
    28. <servlet-name>baobaotao</servlet-name>
    29. <url-pattern>*.html</url-pattern>
    30. </servlet-mapping>
    31. </web-app>

    说明:
    web.xml中,contextConfigLocation和ContextLoaderListener是使用Spring容器必须配置的;
    而DispatcherServlet是使用Spring MVC所必须的。




    Spring配置文件

    applicationContext.xml
    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans
    7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    8. http://www.springframework.org/schema/context
    9. http://www.springframework.org/schema/context/spring-context-3.0.xsd
    10. http://www.springframework.org/schema/tx
    11. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    12. http://www.springframework.org/schema/aop
    13. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    14. <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
    15. <context:component-scan base-package="com.baobaotao.dao"/>
    16. <context:component-scan base-package="com.baobaotao.service"/>
    17. <!-- 配置数据源 -->
    18. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    19. destroy-method="close"
    20. p:driverClassName="com.mysql.jdbc.Driver"
    21. p:url="jdbc:mysql://localhost:3306/sampledb"
    22. p:username="root"
    23. p:password="xxx" />
    24. <!-- 配置Jdbc模板 -->
    25. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
    26. p:dataSource-ref="dataSource" />
    27. <!-- 配置事务管理器 -->
    28. <bean id="transactionManager"
    29. class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    30. p:dataSource-ref="dataSource" />
    31. <!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
    32. <aop:config proxy-target-class="true">
    33. <aop:pointcut id="serviceMethod"
    34. expression=" execution(* com.baobaotao.service..*(..))" />
    35. <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
    36. </aop:config>
    37. <tx:advice id="txAdvice" transaction-manager="transactionManager">
    38. <tx:attributes>
    39. <tx:method name="*" />
    40. </tx:attributes>
    41. </tx:advice>
    42. </beans>

    说明:
    上述配置文件中,使用了schema来简化配置。如:<p:...>、<tx:...>、<aop:...>;
    组件扫描:<context:component>扫描标记了@Controller、@Service、@Repository的类,自动为这些类创建bean。


    Spring MVC配置文件

    baobaotao-servlet.xml

    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    7. http://www.springframework.org/schema/context
    8. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    9. <!-- 扫描web包,应用Spring的注解 -->
    10. <context:component-scan base-package="com.baobaotao.web"/>
    11. <!-- 配置视图解析器,将ModelAndView及字符串解析为具体的页面 -->
    12. <bean
    13. class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    14. p:viewClass="org.springframework.web.servlet.view.JstlView"
    15. p:prefix="/WEB-INF/jsp/"
    16. p:suffix=".jsp" />
    17. </beans>

    说明:
    这是配置了InternalResourceViewResolver视图解析器。Spring MVC中的视图解析器有好多种,且每种视图解析器都可以设置优先级。InternalResourceViewResolver视图解析器只是最常用且最普通的一种视图解析器,它的默认优先级是最低的。



    前端jsp界面

    login.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    4. <html>
    5. <head>
    6. <title>论坛登录</title>
    7. </head>
    8. <body>
    9. <c:if test="${!empty error}">
    10. <font color="red"><c:out value="${error}" /></font>
    11. </c:if>
    12. <form action="<c:url value="loginCheck.html"/>" method="post">
    13. 用户名:
    14. <input type="text" name="userName">
    15. <br>
    16. 密 码:
    17. <input type="password" name="password">
    18. <br>
    19. <input type="submit" value="登录" />
    20. <input type="reset" value="重置" />
    21. </form>
    22. </body>
    23. </html>

    说明:
    这里使用了jstl标签,<c:url value="loginCheck.html"/>的jstl标签会在url前自动加上应用程序的部署根目录,假设应用程序部署在bbt目录下,<c:url/>标签将输出:/bbt/loginCheck.html 。通过<c:url />标签,很好的解决了开发和应用部署目录不一致的问题。

    main.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    5. <html>
    6. <head>
    7. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    8. <title>论坛</title>
    9. </head>
    10. <body>
    11. ${user.userName},欢迎您进入宝宝淘论坛,您当前积分为${user.credits};
    12. </body>
    13. </html>


    log4j.properties

    1. log4j.rootLogger=DEBUG,A1
    2. log4j.appender.A1=org.apache.log4j.ConsoleAppender
    3. log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    4. log4j.appender.A1.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n

    程序测试

    在tomcat下运行该系统,在浏览器中输入:http://localhost:8080/LoginProj/loginCheck.html ,
    用户名密码输入错误时:

    用户名密码输入正确时:

    下面是数据库信息:




    Junit测试

    com.baobaotao.service包:TestUserService.java
    1. package com.baobaotao.service;
    2. import static org.junit.Assert.*;
    3. import java.util.Date;
    4. import org.junit.Test;
    5. import org.junit.runner.RunWith;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.test.context.ContextConfiguration;
    8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    9. import com.baobaotao.domain.User;
    10. @RunWith(SpringJUnit4ClassRunner.class)
    11. @ContextConfiguration(locations={"classpath:applicationContext.xml"})
    12. public class TestUserService {
    13. @Autowired
    14. private UserService userService;
    15. @Test
    16. public void testHasMatchUser() {
    17. boolean b1 = userService.hasMatchUser("admin", "123456");
    18. boolean b2 = userService.hasMatchUser("admin", "1111");
    19. assertTrue(b1);
    20. assertTrue(!b2);
    21. }
    22. @Test
    23. public void testFindUserByUserName() {
    24. User user = userService.findUserByUserName("admin");
    25. assertEquals(user.getUserName(), "admin");
    26. }
    27. @Test
    28. public void testAddLoginLog() {
    29. User user = userService.findUserByUserName("admin");
    30. user.setUserId(1);
    31. user.setUserName("admin");
    32. user.setLastIp("192.168.12.7");
    33. user.setLastVisit(new Date());
    34. userService.loginSuccess(user);
    35. }
    36. }


    测试结果如下:



    至此,整个系统全部完成。












    附件列表

    • 相关阅读:
      python学习===从一个数中分解出每个数字
      python学习===复制list
      Jmeter===测试案例参考
      Jmeter==HTTP信息头管理器的作用
      python实战===使用随机的163账号发送邮件
      python实战===实现读取txt每一行的操作,账号密码
      python实战===生成随机数
      python实战===输入密码以******的形式在cmd中展示
      python实战===使用smtp发送邮件的源代码,解决554错误码的问题,更新版!
      python实战===使用smtp发送邮件的源代码,解决554错误码的问题
    • 原文地址:https://www.cnblogs.com/ssslinppp/p/4487552.html
    Copyright © 2011-2022 走看看