要提到的是,这篇博客的主干内容是参考自:https://blog.csdn.net/u012393192/article/details/79741148
首先是老生常谈的创建项目:
要注意的是,这里最好用自己导入的maven,不然会很慢:具体可以参考这个:https://blog.csdn.net/yup1212/article/details/81631030
然后老老实实创建这几个文件夹,这里要注意的是,按照上面的创建方法,是没有java和resources这两个文件夹的,需要自己创建,可以参考这篇博客:https://blog.csdn.net/qq_41115379/article/details/110939947
然后然后就是老老实实的把这些代码都放入,以下都是按照我自己的顺序来的
1.pom.xml
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test 测试-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.3.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
</dependencies>
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层的备注
//并且这一层是用来和数据库进行外接的
@Repository
public 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;
//同理也写下注解
@Repository
public 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层
@Service
public 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;
//加入注解
@Controller
public 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"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>error</title>
</head>
<body>
<form action="<c:url value="/index.html" />" method="post">
<table align="center" >
<tr>
<td>error</td>
</tr>
<tr>
<td colspan="2",align="center">
<input type="submit" value="返回" />
</td>
</tr>
</table>
</form>
</body>
</html>
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"%>
<html>
<head>
<title>login</title>
<script>
function checkUser(){
var result=document.getElementById("userid").value;
var passowrd=document.getElementById("password").value;
if(result==""){
alert("用户名不能为空");
return false;
}
if(password=""){
alert("密码不能为空");
return false;
}
}
</script>
</head>
<body>
<%--<c:if test="${!empty error}">--%>
<%--<font color="red"><c:out value="%{error}" /></font>--%>
<%--</c:if>--%>
<form action="<c:url value="/loginCheck.html" />" method="post" onsubmit="return checkUser()">
<table align="center" >
<tr>
<td>用户名:</td><td><input type="text" name="userName" id="userid" /></td>
</tr>
<tr>
<td>密码:</td><td><input type="password" name="password" id="userpassid" /></td>
<tr/>
<tr>
<td colspan="2",align="center">
<input type="submit" value="登录" id="check" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
</html>
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" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>你好</title>
</head>
<body>
${user.userName},当前积分为${user.credits};
</body>
</html>
12.resources下的 smart-context.xml
<?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: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/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!--扫描类包,将标注为注解的类自动转化为Bean,同时完成Bean的注入-->
<context:component-scan base-package="com.smart.dao"/>
<context:component-scan base-package="com.smart.service"/>
<!--对数据库的配置-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" primary="true">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<!--mysql现在是需要指定时区的-->
<property name="url" value="jdbc:mysql://localhost:3306/sampledb?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
</bean>
<!--引入jdbc配置文件-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<aop:config proxy-target-class="true">
<aop:pointcut id="serviceMethod" expression="(execution(* com.smart.service..*(..))) and
(@annotation(org.springframework.transaction.annotation.Transactional))" />
<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>
13.resources下的smart-servlet.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--先扫描-->
<context:component-scan base-package="com.smart.web"/>
<!--配置视图解析器,将ModelAndView及字符串解析为具体页面-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
最后是web.xml
要注意的是,这里的web.xml最好还是删除重新新建一个xml config的。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
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_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:smart-context.xml</param-value>
<!--这里默认是/WEB-INF/applicationContext.xml.classpath关键字特指类路径下加载,多个配置文件可用逗号或空格分隔-->
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>smart</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:smart-servlet.xml</param-value>
<!-- 默认是/WEB-INF/[servlet名字]-servlet.xml -->
</init-param>
<load-on-startup>1</load-on-startup>
<!--启动优先级-->
</servlet>
<servlet-mapping>
<servlet-name>smart</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
最后的程序样式差不多是这样
然后按照代码,需要在自己的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 ,这个报错就不存在了
继续展示