博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
依然是springMVC+mysql的用户登陆小项目(全注释图解超详细)
阅读量:3898 次
发布时间:2019-05-23

本文共 14370 字,大约阅读时间需要 47 分钟。

要提到的是,这篇博客的主干内容是参考自:

首先是老生常谈的创建项目:
在这里插入图片描述
要注意的是,这里最好用自己导入的maven,不然会很慢:具体可以参考这个:
在这里插入图片描述
然后老老实实创建这几个文件夹,这里要注意的是,按照上面的创建方法,是没有java和resources这两个文件夹的,需要自己创建,可以参考这篇博客:
在这里插入图片描述
然后然后就是老老实实的把这些代码都放入,以下都是按照我自己的顺序来的
1.pom.xml

junit
junit
4.12
test
javax.servlet
javax.servlet-api
4.0.0
provided
javax.servlet.jsp
jsp-api
2.2
provided
javax.servlet
jstl
1.2
mysql
mysql-connector-java
6.0.6
org.springframework
spring-core
5.0.3.RELEASE
org.springframework
spring-beans
5.0.3.RELEASE
org.springframework
spring-test
5.0.3.RELEASE
test
commons-dbcp
commons-dbcp
1.4
org.springframework.boot
spring-boot-autoconfigure
1.5.8.RELEASE
org.springframework.boot
spring-boot-starter-data-jpa
1.5.7.RELEASE
org.springframework
spring-web
5.0.3.RELEASE
org.springframework
spring-webmvc
5.0.3.RELEASE
org.springframework
spring-context
5.0.3.RELEASE

2.domain层的LoginLog

package com.smart.domain;import java.io.Serializable;import java.util.Date;//这些应该是最早创建的public class LoginLog implements Serializable {
private int loginLogId; //这里有个用户id private int userId; private String ip; private Date loginDate; //然后是一系列get set方法 public int getLoginLogId() {
return loginLogId; } public void setLoginLogId(int loginLogId) {
this.loginLogId = loginLogId; } public int getUserId() {
return userId; } public void setUserId(int userId) {
this.userId = userId; } public String getIp() {
return ip; } public void setIp(String ip) {
this.ip = ip; } public Date getLoginDate() {
return loginDate; } public void setLoginDate(Date loginDate) {
this.loginDate = loginDate; }}

3.domain层的User

package com.smart.domain;import java.io.Serializable;import java.util.Date;//继承这个Ser是为了序列化操作public class User implements Serializable {
private int userId; private String userName; private String password; private int credits; private String lastIP; private Date lastVisit; //然后是一系列get set方法 public int getUserId() {
return userId; } public void setUserId(int userId) {
this.userId = userId; } 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 int getCredits() {
return credits; } public void setCredits(int credits) {
this.credits = credits; } public String getLastIP() {
return lastIP; } public void setLastIP(String lastIP) {
this.lastIP = lastIP; } public Date getLastVisit() {
return lastVisit; } public void setLastVisit(Date lastVisit) {
this.lastVisit = lastVisit; }}

4.Dao层的LoginLogDao

package com.smart.dao;import com.smart.domain.LoginLog;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;import java.util.Objects;//首先加上在dao层的备注//并且这一层是用来和数据库进行外接的@Repositorypublic class LoginLogDao {
//私有化属性 private JdbcTemplate jdbcTemplate; //保存登录日志SQL private final static String INSERT_LOGIN_LOG_SQL = "INSERT INTO t_login_log (user_id,ip,login_datetime) VALUES (?,?,?)"; public void insertLoginLog(LoginLog loginLog){
//创建一个用来存的,并对应插入到数据库中 Object[] args={
loginLog.getUserId(),loginLog.getIp(),loginLog.getLoginDate()}; //刚好对应这两个参数 jdbcTemplate.update(INSERT_LOGIN_LOG_SQL,args); } //这里为什么要自动导入方法呢,留个疑问,它是可以导入方法,但是目的不是通过set方法来消除依赖嘛 //难道是因为 这个是private 所以是需要有一个set方法,来实现和public一样的作用? @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate; }}

5.Dao层的UserDao

package com.smart.dao;import com.smart.domain.User;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 java.sql.ResultSet;import java.sql.SQLException;//同理也写下注解@Repositorypublic class UserDao {
//JdbcTemplate是spring 对jdbc封装,有execute:执行所有sql操作 update 执行insert,update,delete的操作 //和queryXxx 用于DQL数据查询语句 private JdbcTemplate jdbcTemplate; //这里也导入进去 @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate; } //首先第一个是更加用户名和密码来获取匹配的用户 //第一个参数是 userName 用户名 //第二个参数是 password 密码 //返回1 表示用户名密码正确 0表示用户名密码错误 public int getMatchCount(String userName,String password){
String sqlStr="SELECT count(*) FROM t_user WHERE user_name=? and password=?"; //然后这里是查询作用,并且返回参数是根据最后一个参数,这个稍微理解一下就行了吧 return jdbcTemplate.queryForObject(sqlStr,new Object[]{
userName,password},Integer.class); } //然后再写两条静态的,直接查找就行的那种,这种final是说明不能修改嘛,这里也不太清楚为什么这两句可以单独先写出来 private final static String MATCH_COUNT_SQL="SELECT * FROM t_user WHERE user_name=?"; private final static String UPDATE_LOGIN_INFO_SQL="UPDATE t_user SET last_visit=?,last_ip=?,credits=?WHERE user_id=?"; //第二个就是通过用户名来获取对象,也就是刚刚的第一句话 //参数是用户名,可是这里为什么要用final 也是搞不太清楚 //返回值是user 对象 public User findUserByUserName(final String userName){
//创建对象 final User user=new User(); //调用sql,RowCallbackHandler这个方法需要看一下 //主要是在于 这个结果有很多行,所以需要增加一个这个 jdbcTemplate.query(MATCH_COUNT_SQL, new Object[]{
userName}, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException{
//我理解是在于 主要这个userName在参数中已经输入了,而id 和credits则是没有set的,是需要导入的 user.setUserId(rs.getInt("user_id")); user.setUserName(userName); user.setCredits(rs.getInt("credits")); } }); return user; } //第三个方法是更新用户积分,最后登录ip和最后登录时间 public void updateLoginInfo(User user){
//依次输入那些参数 jdbcTemplate.update(UPDATE_LOGIN_INFO_SQL,new Object[]{
user.getLastVisit(),user.getLastIP(),user.getCredits(),user.getUserId()}); }}

6.service层的UserService

package com.smart.service;import com.smart.dao.LoginLogDao;import com.smart.dao.UserDao;import com.smart.domain.LoginLog;import com.smart.domain.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;//其次就是最为难懂的service层@Servicepublic class UserService {
//感觉他的作用就是把Dao层的进行了再次调用 //设置两个私有的属性.通过set来让他们变的公有 private UserDao userDao; private LoginLogDao loginLogDao; @Autowired public void setUserDao(UserDao userDao) {
this.userDao = userDao; } @Autowired public void setLoginLogDao(LoginLogDao loginLogDao) {
this.loginLogDao = loginLogDao; } //然后这里就是调用那些User的方法 //第一个方法是判断有没有匹配的用户,如果有的话就是1,没有的话就是0 public boolean hasMatchUser(String userName,String password){
int match=userDao.getMatchCount(userName,password); return match>0; } //第二个方法是找到对应的user,通过username public User findUserByUserName(String userName){
return userDao.findUserByUserName(userName); } //第三个方法先是调用了一个transactional 暂时不能;理解 @Transactional public void loginSuccess(User user){
user.setCredits(5+user.getCredits()); LoginLog loginLog=new LoginLog(); //这里也是需要有userid的 loginLog.setUserId(user.getUserId()); loginLog.setIp(user.getLastIP()); loginLog.setLoginDate(user.getLastVisit()); //再是调用了dao层的代码 userDao.updateLoginInfo(user); //他只有一个插入数据,而这些数据已经刚刚被保存好了 loginLogDao.insertLoginLog(loginLog); }}

7.web层的LoginCommand

package com.smart.web;//这个我也不太清楚,可能是因为登录只需要账号和密码吧public class LoginCommand {
private String userName; private String password; 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; }}

8.web层的LoginController

package com.smart.web;import com.smart.domain.User;import com.smart.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import java.util.Date;//加入注解@Controllerpublic class LoginController {
private UserService userService; //这里就是和前端页面有接触了,并且有点难以理解了 //首先是index.html。处理这个请求 @RequestMapping(value = "/index.html") public String loginPage(){
return "login"; } //然后是登录请求 @RequestMapping("/loginCheck.html") public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){
//一个请求和一个登录需要用的参数 boolean isValidUser=userService.hasMatchUser(loginCommand.getUserName(),loginCommand.getPassword()); //然后判断是否有效 if(!isValidUser){
return new ModelAndView("logError"); }else{
//也就是能登录 User user= userService.findUserByUserName(loginCommand.getUserName()); //这部分细细的看 user.setLastIP(request.getLocalAddr()); user.setLastVisit(new Date()); userService.loginSuccess(user); request.getSession().setAttribute("user",user); return new ModelAndView("main"); } } @Autowired public void setUserService(UserService userService) {
this.userService = userService; }}

9.WEB-iNF下 jsp下的logError.jsp

<%--  Created by IntelliJ IDEA.  User: wzw324  Date: 2020/12/9  Time: 15:31  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>    
error
" method="post">
error

10.WEB-iNF下 jsp下的login.jsp

<%--  Created by IntelliJ IDEA.  User: wzw324  Date: 2020/12/9  Time: 15:24  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> login <%--
--%><%--
--%><%--
--%>
" method="post" onsubmit="return checkUser()">
用户名:
密码:

119.WEB-iNF下 jsp下的main.jsp

<%--  Created by IntelliJ IDEA.  User: wzw324  Date: 2020/12/9  Time: 15:33  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>    
你好${
user.userName},当前积分为${
user.credits};

12.resources下的 smart-context.xml

13.resources下的smart-servlet.xml

最后是web.xml

要注意的是,这里的web.xml最好还是删除重新新建一个xml config的。

contextConfigLocation
classpath:smart-context.xml
org.springframework.web.context.ContextLoaderListener
org.springframework.web.context.request.RequestContextListener
smart
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:smart-servlet.xml
1
smart
*.html

最后的程序样式差不多是这样

在这里插入图片描述
然后按照代码,需要在自己的mysql创建一个对应的数据库
(ps这里数据库的登录密码需要和smart-context里的dataSource 配置一样,主要是端口和账号密码)
首先可以通过
在这里插入图片描述
测试连接一下
在这里插入图片描述
然后在命令行创建一个sampledb数据库
使用 create database sampledb;
然后show databases看一下
在这里插入图片描述

然后就要在数据库里新建一些表和属性了,这里建议使用Navicat哈哈哈

t_user表
在这里插入图片描述
t_login_log表
在这里插入图片描述

然后在t_user表中新建一个用户,方便查找

在这里插入图片描述
在Navicat里做好之后,都是可以在命令行查看的
查看表:
在这里插入图片描述
看表里面的属性
在这里插入图片描述
最后看看那个新建好的用户
在这里插入图片描述
现在就差最后一步,也就是配置Tomcat了
在这里插入图片描述
在这里插入图片描述

这个名字无关紧要的

在这里插入图片描述
(ps经过测试,要把这个给删了,不然他界面会一直在这边,并且要删了之后,可能需要重启电脑,反正我是又新建了一个tomcat)
在这里插入图片描述

运行结果:

在这里插入图片描述
但是之后的操作,出现了
在这里插入图片描述
网上看是需要把mysql-connector-java从6.0.6,改成5.1.6 ,这个报错就不存在了
在这里插入图片描述
继续展示
在这里插入图片描述
在这里插入图片描述

转载地址:http://pifen.baihongyu.com/

你可能感兴趣的文章
织梦系统如何插入优酷视频?
查看>>
Discuz设置特定用户组不启用验证码发帖权限
查看>>
百度云服务器 CentOS 图形界面支持
查看>>
为什么要使用R语言?历数R的优势与缺点
查看>>
[小技巧] Linux 下查询图片的大小
查看>>
Linus Torvalds说那些对人工智能奇点深信不疑的人显然磕了药
查看>>
[小技巧] svn: 不能解析 URL
查看>>
USB_ModeSwitch 介绍
查看>>
大公司和小公司的抢人战,孰胜孰负?
查看>>
通过make编译多文件的内核模块
查看>>
如何调试Javascript代码
查看>>
皮克斯宣布开源Universal Scene Description
查看>>
复盘:一个创业项目的失败之路
查看>>
阿里巴巴宣布加入Linux基金会
查看>>
为什么你应该尝试 “全栈”
查看>>
程序员什么时候该考虑辞职
查看>>
如何写一本书?
查看>>
加班能体现编程的热情吗?
查看>>
Hadley Wickham:一个改变了R的人
查看>>
glibc 指导委员会解散声明
查看>>