一、JSP
1、基础语法
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>基础语法</title>
</head>
<body>
<pre>
JSP中一种有两种类型的注释:
1. 显式注释
能够在客户端查看的注释
1. 继承HTML风格的注释 <!-- HTML注释 -->
<!-- HTML注释 -->
2. 隐式注释
不能在客户端查看的注释
1. JSP自己的注释 <%--JSP自己的注释--%>
<%--JSP自己的注释--%>
2. 继承Java风格的注释
// 单行注释
/* 多行注释 */
</pre>
<%-- Java脚本段 --%>
<%
// 这是单行注释
/* 这是多行注释 */
%>
</body>
</html>
2、Scriptlet脚本小程序
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Scriptlet脚本小程序</title>
</head>
<body>
<%--
Scriptlet脚本小程序
JSP一共有三种Scriptlet脚本小程序:
第一种:Java脚本段,可以写Java代码,定义局部变量、编写语句等
<%
// 可以写Java代码
%>
生成的代码在servlet中的service方法体中
第二种:声明,声明全局变量、方法、类等
<%!
// 声明全局变量
%>
生成的代码在servlet的类体中
第三种:输出表达式,可以输出变量或字面量
<%=数值 %>
生成的代码在servlet中的service方法体中,相当于out.print()输出
--%>
<%-- 第一种:Java脚本段,可以写Java代码,定义局部变量、编写语句等 --%>
<%
// 定义局部变量
String str = "Hello Jsp";
// 输出内容到控制台
System.out.println(str);
// 输出内容到浏览器
out.print(str);
out.write("------");
// 输出全局变量
out.write("全局变量:" + num);
out.write("------");
%>
<%-- 第二种:声明,声明全局变量、方法、类等 --%>
<%!
// 声明全局变量
int num = 10;
%>
<%-- 第三种:输出表达式,可以输出变量或字面量 --%>
<%=str %>
</body>
</html>
3、头部和尾部
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>头部</title>
</head>
<body>
<h2>头部内容</h2>
<%
int num = 1;
%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>底部</title>
</head>
<body>
<h2>底部内容</h2>
<%
int a = 10;
// 获取动态包含传递的参数
String uname = request.getParameter("uname");
String msg = request.getParameter("msg");
out.print(uname+","+msg);
%>
</body>
</html>
4、include静态包含
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include静态包含</title>
</head>
<body>
<%--
include静态包含
格式:
<%@include file="要包含的页面地址"%>
特点:
1. 将内容进行了直接的替换
2. 静态包含只会生成一个源码文件,最终的内容全部在_jspService方法体中(源码文件中)
3. 不能出现同名变量
4. 运行效率高一点点。耦合性较高,不够灵活。
--%>
<%@include file="04-header.jsp"%>
<h2>主体内容</h2>
<%
// int num = 1;
%>
<%@include file="04-footer.jsp"%>
</body>
</html>
include动态包含
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include动态包含</title>
</head>
<body>
<%--
include动态包含
格式:
<jsp:include page="要包含的页面路径"></jsp:include>
特点:
1. 动态包含相当于方法的调用
2. 动态包含会生成多个源码文件
3. 可以定义同名变量
4. 效率高,耦合度低
注:
当动态包含不需要传递参数时,include双标签之间不要有任何内容,包括换行和空格
使用动态包含传递参数
<jsp:include page="要包含的页面路径">
<jsp:param name="参数名" value="参数值"/>
</jsp:include>
注:name属性不支持表达式,value属性支持表示
获取参数:
request.getParameter(name); 通过指定参数名获取参数值
--%>
<jsp:include page="04-header.jsp"></jsp:include>
<h2>主体内容</h2>
<%
int a = 1;
%>
<jsp:include page="04-footer.jsp"></jsp:include>
<%-- 动态包含传递参数 --%>
<%
String str = "hello";
String url = "04-footer.jsp";
%>
<jsp:include page="<%=url%>">
<jsp:param name="uname" value="admin"/>
<jsp:param name="msg" value="<%=str%>"/>
</jsp:include>
</body>
</html>
5、JSP的四大域对象
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的四大域对象</title>
</head>
<body>
<%--
JSP的四大域对象
page作用域
在当前页面有效,跳转后无效
request作用域
在一次请求中有效,服务端跳转有效,客户端跳珠失效
session作用域
在一次会话中有效,服务端和客户端跳转有效
application作用域
在整个应用中有效
JSP中跳转方式
1. 服务端跳转
<jsp:forward page="跳转的页面地址"></jsp:forward>
2. 客户端跳转
超链接
--%>
<%
// 设置page范围的域对象
pageContext.setAttribute("name1","zhangsan");
// 设置request范围的域对象
request.setAttribute("name2","lisi");
// 设置session范围的域对象
session.setAttribute("name3","wangwu");
// 设置application范围的域对象
application.setAttribute("name4","zhaoliu");
%>
<%-- jsp中服务端跳转 --%>
<%--<jsp:forward page="06-JSP的四大域对象-02.jsp"></jsp:forward>--%>
<%-- 超链接跳转--%>
<a href="06-JSP的四大域对象-02.jsp">跳转</a>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的四大域对象</title>
</head>
<body>
<%--
JSP的四大域对象
--%>
<%
// 获取域对象中的值
out.print("page范围:" + pageContext.getAttribute("name1") + "<br>");
out.print("request范围:" + request.getAttribute("name2") + "<br>");
out.print("session范围:" + session.getAttribute("name3") + "<br>");
out.print("application范围:" + application.getAttribute("name4") + "<br>");
%>
</body>
</html>
6、简单登录网页
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置客户端的编码格式
request.setCharacterEncoding("UTF-8");
// 接收客户端传递的参数
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
// 判断参数是否为空
if (uname == null || "".equals(uname.trim())) {
// 提示用户信息
request.setAttribute("msg","用户姓名不能为空!");
// 请求转发跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
}
if (upwd == null || "".equals(upwd.trim())) {
// 提示用户信息
request.setAttribute("msg","用户密码不能为空!");
// 请求转发跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
}
// 判断账号密码是否真确 uname=admin upwd=admin
if (!"admin".equals(uname) || !"admin".equals(upwd)) {
// 提示用户信息
request.setAttribute("msg","登录失败!");
// 请求转发跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
}
// 登录成功
// 设置登录信息到session作用域
request.getSession().setAttribute("uname",uname);
// 跳转到index.jsp
response.sendRedirect("index.jsp");
}
}
二、JSTL
1、JSTL的使用
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 通过taglib标签引入所需要的标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>JSTL的使用</title>
<%--
JSTL的使用
1. 下载JSTL所需要的jar包 (standard.jar 和 jstl.jar)
2. 在项目的web目录下的WEB-INF中新建lib目录,将jar拷贝进去
3. 选择"File",再选择"Project Structure"
4. 选择"Modules",选择右侧的"Dependencies",选择右侧的"+"号,将对应的lib目录加载进来
5. 在需要使用标签库的JSP页面通过taglib标签引入指定库
--%>
</head>
<body>
<c:if test="${1==1}">
Hello JSTL
</c:if>
</body>
</html>
2、if 标签
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>if 标签</title>
</head>
<body>
<%--
if 标签
格式:
<c:if test="<boolean>" var="<string>" scope="<string>">
...
</c:if>
常用属性:
test:条件判断,操作的是域对象,接收返回结果是boolean类型的值 (必要属性)
var:限域变量名(存放在作用域中的变量名),用来接收判断结果的值(可选属性)
scope:限域变量名的范围(page、request、session、application)(可选属性)
注:
1. 标签操作的一般都是域对象
2. if标签标签没有else,如果想要else的效果,就需要设置两个完全相反的条件
--%>
<%
// 设置数据
request.setAttribute("num",0);
%>
<c:if test="${num > 0}" >
数值大于0
</c:if>
<c:if test="${num <= 0}">
数值不大于0
</c:if>
<br>
<c:if test="${num > 100}" var="flag" scope="request"></c:if>
${flag}-- ${requestScope.flag} -- ${sessionScope.flag}
</body>
</html>
3、choose、when 和 otherwise 标签
<%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>choose、when 和 otherwise 标签</title>
</head>
<body>
<%--
choose、when 和 otherwise 标签
格式:
<c:choose>
<c:when test="<boolean>">
...
</c:when>
<c:when test="<boolean>">
...
</c:when>
...
...
<c:otherwise>
...
</c:otherwise>
</c:choose>
属性:
1. choose标签没有属性
2. when标签只有一个test属性,必须属性
3. otherwise标签没有属性
注意:
1. choose标签和otherwise标签没有属性,而when标签必须有一个test属性
2. choose标签中必须包含至少一个when标签,可以没有otherwise标签 (Illegal "choose" without child "when" tag)
3. otherwise标签必须设置在最后一个when标签之后 (Illegal "c:when" after "c:otherwise" tag in "c:choose" tag.)
4. choose标签中只能设置when标签与otherwise标签(Illegal child tag in "c:choose" tag: "c:if" tag)
5. when标签和otherwise标签中可以嵌套其他标签
6. otherwise标签会在所有的when标签不执行时才会执行
--%>
<%
request.setAttribute("score",90);
%>
<c:choose>w
<c:when test="${score < 60}">
<h2>你个小渣渣!</h2>
</c:when>
<c:when test="${score == 60}">
<h2>分不在高,及格就行!</h2>
<c:if test="${1==1}">111</c:if>
</c:when>
<c:when test="${score > 60 && score < 80}">
<h2>哎哟不错哦!</h2>
</c:when>
<c:otherwise>
<h2>你很棒棒哦!</h2>
<c:if test="${1==1}">111</c:if>
</c:otherwise>
</c:choose>
</body>
</html>
4、forEach标签
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.xxxx.po.User" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>forEach标签</title>
</head>
<body>
<%--
forEach标签
格式:
<c:forEach
items="<object>"
begin="<int>"
end="<int>"
step="<int>"
var="<string>"
varStatus="<string>">
</c:forEach>
属性:
begin:开始数
end:结束数
step:间隔数
var:限域变量名,用来接收当前遍历的成员
items:要循环的数据(数组、List、Map等)
forEach varStatus 属性
index: 当前这次迭代从 0 开始的迭代索引
count: 当前这次迭代从 1 开始的迭代计数
first: 用来表明当前这轮迭代是否为第一次迭代的标志
last: 用来表明当前这轮迭代是否为最后一次迭代的标志
1. 迭代主体内容多次
<c:forEach begin="开始数" end="结束数" step="间隔数" var="限域变量名">
</c:forEach>
相当于Java中for...int
for (int i = 0; i < 10; i++) {
}
2. 循环
<c:forEach items="要被循环的数据" var="限域变量名">
</c:forEach>
相当于Java中的foreach
for(String str : list) {
}
--%>
<%-- 迭代主体内容多次 --%>
<c:forEach var="i" begin="1" end="10" step="2">
${i}
</c:forEach>
<hr>
<%-- 循环 --%>
<%
List<String> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add("A:" + i);
}
pageContext.setAttribute("li", list);
%>
<c:forEach items="${li}" var="item">
${item}
</c:forEach>
<hr>
<table align="center" width="800" border="1" style="border-collapse: collapse;">
<tr>
<th>名称</th>
<th>当前成员下标</th>
<th>当前成员循环数</th>
<th>是否第一次被循环</th>
<th>是否最后一次被循环</th>
</tr>
<c:forEach items="${li}" var="item" varStatus="itemp">
<tr>
<td>${item}</td>
<td>${itemp.index}</td>
<td>${itemp.count}</td>
<td>${itemp.first}</td>
<td>${itemp.last}</td>
</tr>
</c:forEach>
</table>
<hr>
<%-- 循环对象集合 --%>
<%
List<User> userList = new ArrayList<User>();
User user = new User(1,"zhangsan","123456");
User user2 = new User(2,"lisi","123321");
User user3 = new User(3,"wangwu","654321");
userList.add(user);
userList.add(user2);
userList.add(user3);
// 将数据设置到作用域中
request.setAttribute("userList", userList);
%>
<%-- 判断集合是否为空 --%>
<c:if test="${!empty userList}">
<%-- 当集合不为空时,遍历集合 --%>
<table align="center" width="800" border="1" style="border-collapse: collapse;">
<tr>
<th>用户编号</th>
<th>用户名称</th>
<th>用户密码</th>
<th>用户操作</th>
</tr>
<c:forEach items="${userList}" var="user">
<tr align="center">
<td>${user.userId}</td>
<td>${user.uname}</td>
<td>${user.upwd}</td>
<td><button>修改</button></td>
</tr>
</c:forEach>
</table>
</c:if>
<%-- 循环Map --%>
<%
Map<String,Object> map = new HashMap<>();
map.put("map1", "aaa");
map.put("map2", "bbb");
map.put("map3", "ccc");
pageContext.setAttribute("map", map);
%>
<c:forEach items="${map}" var="m">
key:${m.key} value:${m.value} <br>
</c:forEach>
</body>
</html>
5、格式化动作标签
<%@ page import="java.util.Date" %><%--
Created by IntelliJ IDEA.
User: Lisa Li
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 引入格式化标签库 --%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>格式化动作标签</title>
</head>
<body>
<%--
格式化动作标签
formatNumber标签
将数值型转化成指定格式的字符串
语法格式:
<fmt:formatNumber
value="<string>"
type="<string>"
var="<string>"
scope="<string>"/>
常用属性:
value:要格式化的数值
type:要格式化的类型
number 数值型 (默认)
percent 百分比类型
currency 货币类型
var:限域变量名,用来接收格式化后的结果
scope:var属性的范围 (page|request|session|apllication)
注:
1. 如果使用了var属性,标签不会输出结果,需要通过el表达式获取
2. 默认的类型(type)的取值为number
formatDate标签
将Date型的数据转化成指定格式的字符串
语法格式:
<fmt:formatDate
value="<string>"
type="<string>"
dateStyle="<string>"
timeStyle="<string>"
pattern="<string>"
timeZone="<string>"
var="<string>"
scope="<string>"/>
常用属性:
value:要格式化的日期
type:格式化的类型
date 日期型 年月日
time 时间型 时分秒
both 日期时间型
dateStyle:日期格式
timeStyle:日期时间
pattern:自定义模式
y M d H m s
timeZone
var
scope
parseNumber标签
将指定格式的数值字符串转化成数值型
语法格式:
<fmt:parseNumber
value="<string>"
type="<string>"
var="<string>"
scope="<string>"/>
parseDate标签
将日期型的字符串转换成Date型
格式语法:
<fmt:parseDate
value="<string>"
type="<string>"
dateStyle="<string>"
timeStyle="<string>"
pattern="<string>"
var="<string>"
scope="<string>"/>
--%>
<fmt:formatNumber value="10" type="number" var="num" /> ${num } <br>
<fmt:formatNumber value="10" type="percent" /> <br>
<fmt:formatNumber value="10" type="currency" /> <br>
<!-- 设置时区 -->
<fmt:setLocale value="en_US"/>
<fmt:formatNumber value="10" type="currency" /> <br>
<hr>
<%-- 格式化日期 --%>
<%
request.setAttribute("myDate",new Date());
%>
${myDate} <br>
<fmt:formatDate value="${myDate}" /> <br>
<fmt:formatDate value="${myDate}" type="date" /> <br>
<fmt:formatDate value="${myDate}" type="time" /> <br>
<fmt:formatDate value="${myDate}" type="both" /> <br>
<fmt:formatDate value="${myDate}" type="both" dateStyle="FULL" /> <br>
<fmt:formatDate value="${myDate}" type="both" timeStyle="short" /> <br>
<fmt:formatDate value="${myDate}" pattern="yyyy-MM-dd" /> <br>
<hr>
<fmt:setLocale value="zh_CN"/>
<fmt:parseNumber value="100" /> <br>
<fmt:parseNumber value="100" type="number" /> <br>
<fmt:parseNumber value="100%" type="percent" /> <br>
<fmt:parseNumber value="¥10.00" type="currency" /> <br>
<hr>
<fmt:parseDate value="2020-01-06" type="date" /> <br>
<fmt:parseDate value="2020/01/06" pattern="yyyy/MM/dd" /> <br>
</body>
</html>
三、用户登录网页(前后端交互)
1、java项目包
1、mysql.propertirs
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/java_test?serverTimezone=UTC&useSSL=false&characterEncoding=UTF-8
username=root
password=root
2、mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
properties 标签中的配置可以供整个配置文件使用,在任何位置都可以引入其中配置的值。
properties 标签可以通过子标签 property 标签来配置一些子元素信息,也可以配置外部的动态文件。
-->
<properties resource="mysql.properties"/> <!-- 也可以配置url,但url和resource只能存在一个 -->
<!-- 类型别名 -->
<!--<typeAliases>
<typeAlias alias="User" type="com.xxxx.entity.User" />
</typeAliases>-->
<!-- 对事务的管理和连接池的配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- mappers映射器 -->
<mappers>
<!-- 映射文件方式1,一个一个的配置 -->
<!--<mapper resource="com/xxxx/mapper/UserMapper.xml"/>-->
<!--<mapper class="com.xxxx.mapper.UserMapper"/>-->
<!-- 映射文件方式2,自动扫描包内的Mapper接口与配置文件 -->
<package name="com.xxxx.mapper"/>
</mappers>
</configuration>
3、com.xxxx包
1、util
package com.xxxx.util;
/**
* 字符串工具类
*/
public class StringUtil {
/**
* 判断字符串是否为空
* 如果为空,返回true;
* 如果不为空,返回false
* @param str
* @return
*/
public static boolean isEmpty(String str) {
if (str == null || "".equals(str.trim())) {
return true;
}
return false;
}
}
package com.xxxx.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class GetSqlSession {
/**
* 获取SqlSession对象
* @return
*/
public static SqlSession createSqlSession () {
SqlSessionFactory sqlSessionFactory = null;
InputStream input = null;
SqlSession session = null;
try {
// 获得mybatis的环境配置文件
String resource = "mybatis-config.xml";
// 以流的方式获取recource(mybatis的环境配置文件)
input = Resources.getResourceAsStream(resource);
// 创建会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 通过工厂得到SqlSession
session = sqlSessionFactory.openSession();
return session;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
2、entity
package com.xxxx.entity;
/**
* User实体类
*/
public class User {
private Integer userId; // 用户编号
private String userName; // 用户姓名
private String userPwd; // 用户密码
private Integer userAge; // 用户年龄
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
}
1、vo
package com.xxxx.entity.vo;
/**
* 消息模型对象 (数据响应)
* 状态码
* 1=成功,0=失败
* 提示信息
* 字符串
* 回显数据
* object对象
*/
public class MessageModel {
private Integer code = 1; // 状态码 (1=成功,0=失败)
private String msg = "成功!"; // 提示信息
private Object object; // 回显对象 (基本数据类型、字符串类型、List、Map等)
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
3、mapper
package com.xxxx.mapper;
import com.xxxx.entity.User;
/**
* 用户接口类
*/
public interface UserMapper {
public User queryUserByName(String userName);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 首先来解析 namespace: 命名空间,此属性通常用来映射Dao(Mapper)层接口. -->
<mapper namespace="com.xxxx.mapper.UserMapper">
<!-- id: 对应Dao(Mapper)层接口方法名 parameterType:指定输入参数类型 -->
<!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->
<select id="queryUserByName" parameterType="String" resultType="com.xxxx.entity.User">
select * from tb_user where userName = #{userName}
</select>
</mapper>
4、service
package com.xxxx.service;
import com.xxxx.entity.User;
import com.xxxx.entity.vo.MessageModel;
import com.xxxx.mapper.UserMapper;
import com.xxxx.util.GetSqlSession;
import com.xxxx.util.StringUtil;
import org.apache.ibatis.session.SqlSession;
/**
* 业务逻辑
*/
public class UserService {
/**
* 用户登录
1. 参数的非空判断
如果参数为空
将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
2. 调用dao层的查询方法,通过用户名查询用户对象
3. 判断用户对象是否为空
如果为空,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
4. 判断数据库中查询到的用户密码与前台传递过来的密码作比较
如果不相等,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
5. 登录成功,成功状态、提示信息、用户对象设置消息模型对象,并return
* @param uname
* @param upwd
* @return
*/
public MessageModel userLogin(String uname, String upwd) {
MessageModel messageModel = new MessageModel();
// 回显数据
User u = new User();
u.setUserName(uname);
u.setUserPwd(upwd);
messageModel.setObject(u);
// 1. 参数的非空判断
if (StringUtil.isEmpty(uname) || StringUtil.isEmpty(upwd)) {
// 将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
messageModel.setCode(0);
messageModel.setMsg("用户姓名和密码不能为空!");
return messageModel;
}
// 2. 调用dao层的查询方法,通过用户名查询用户对象
SqlSession session= GetSqlSession.createSqlSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.queryUserByName(uname);
// 3. 判断用户对象是否为空
if (user == null ) {
// 将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
messageModel.setCode(0);
messageModel.setMsg("用户不存在!");
return messageModel;
}
// 4. 判断数据库中查询到的用户密码与前台传递过来的密码作比较
if (!upwd.equals(user.getUserPwd())) {
// 如果不相等,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
messageModel.setCode(0);
messageModel.setMsg("用户密码不正确!");
return messageModel;
}
// 登录成功,将用户信息设置到消息模型中
messageModel.setObject(user);
return messageModel;
}
}
5、controller
package com.xxxx.controller;
import com.xxxx.entity.vo.MessageModel;
import com.xxxx.service.UserService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class UserServlet extends HttpServlet {
// 实例化UserService对象
private UserService userService = new UserService();
/**
* 用户登录
1. 接收客户端的请求(接收参数:姓名、密码)
2. 调用service层的方法,返回消息模型对象
3. 判断消息模型的状态码
如果状态码是失败
将消息模型对象设置到request作用域中,请求转发跳转到login.jsp
如果状态码是成功
将消息模型中的用户信息设置到session作用域中,重定向跳转到index.jsp
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 接收客户端的请求(接收参数:姓名、密码)
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
// 2. 调用service层的方法,返回消息模型对象
MessageModel messageModel = userService.userLogin(uname,upwd);
// 3. 判断消息模型的状态码
if (messageModel.getCode() == 1 ) { // 成功
// 将消息模型中的用户信息设置到session作用域中,重定向跳转到index.jsp
request.getSession().setAttribute("user",messageModel.getObject());
response.sendRedirect("index.jsp");
} else { // 失败
// 将消息模型对象设置到request作用域中,请求转发跳转到login.jsp
request.setAttribute("messageModel",messageModel);
request.getRequestDispatcher("login.jsp").forward(request,response);
}
}
}
2、web项目包
1、js包下
导入jquery.js
2、WEB-INF
1、lib包下
导入mybatis包
导入mybatis-connector-java依赖包
2、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
3、用户登录流程.txt
用户登录
1. 数据库创建对应的用户表 tb_user (MySQL)
2. 前台页面
登录页面 login.jsp
用户登录 JS校验
登录表单验证
1. 给登录按钮绑定点击事件
2. 获取用户姓名和密码的值
3. 判断姓名是否为空
如果姓名为空,提示用户(span标签赋值),并且return
4. 判断密码是否为空
如果密码为空,提示用户(span标签赋值),并且return
5. 如果都不为空,则手动提交表单
首页 index.jsp
3. 后代实现
登录功能
思路:
1. 接收客户端的请求(接收参数:姓名、密码)
2. 参数的非空判断
如果参数为空
通过消息模型对象返回结果(设置状态、设置提示信息、回显数据)
将消息模型对象设置到request作用域中
请求转发跳转到登录页面
return
3. 通过用户姓名查询用户对象
4. 判断用户对象是否为空
如果为空
通过消息模型对象返回结果(设置状态、设置提示信息、回显数据)
将消息模型对象设置到request作用域中
请求转发跳转到登录页面
return
5. 将数据库中查询到的用户密码与前台传递的密码作比较
如果不相等
通过消息模型对象返回结果(设置状态、设置提示信息、回显数据)
将消息模型对象设置到request作用域中
请求转发跳转到登录页面
如果相等,表示登录成功
将用户信息设置到session作用域中
重定向跳转到首页
controller层(接收请求、响应结果)
1. 接收客户端的请求(接收参数:姓名、密码)
2. 调用service层的方法,返回消息模型对象
3. 判断消息模型的状态码
如果状态码是失败
将消息模型对象设置到request作用域中,请求转发跳转到login.jsp
如果状态码是成功
将消息模型中的用户信息设置到session作用域中,重定向跳转到index.jsp
service层 (业务逻辑)
1. 参数的非空判断
如果参数为空
将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
2. 调用dao层的查询方法,通过用户名查询用户对象
3. 判断用户对象是否为空
如果为空,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
4. 判断数据库中查询到的用户密码与前台传递过来的密码作比较
如果不相等,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
5. 登录成功,成功状态、提示信息、用户对象设置消息模型对象,并return
mapper层(Dao层)
定义对应的接口
分层思想(解耦:高内聚低耦合)
controller层
接收请求
(调用service层,返回结果)
响应结果
service层
业务逻辑判断
mapper
接口类
mapper.xml mybatis与数据库的相关操作
entity(po、model)
JavaBean实体
util
工具类(通用的方法/类)
test
测试类/方法
3、登录页面.jsp
<%--
Created by IntelliJ IDEA.
User: 17624
Date: 2022/11/10
Time: 20:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户登录</title>
</head>
<body>
<div style="text-align: center">
<form action="login" method="post" id="loginForm">
姓名:<input type="text" name="uname" id="uname" value="${messageModel.object.userName}" > <br>
密码:<input type="password" name="upwd" id="upwd" value="${messageModel.object.userPwd}"> <br>
<span id="msg" style="font-size: 12px;color: red">${messageModel.msg}</span> <br>
<button type="button" id="loginBtn">登录</button>
<button type="button">注册</button>
</form>
</div>
</body>
<%-- 引入Jquery的js文件 --%>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
/**
* 登录表单验证
1. 给登录按钮绑定点击事件(通过id选择器绑定)
2. 获取用户姓名和密码的值
3. 判断姓名是否为空
如果姓名为空,提示用户(span标签赋值),并且return
4. 判断密码是否为空
如果密码为空,提示用户(span标签赋值),并且return
5. 如果都不为空,则手动提交表单
*/
$("#loginBtn").click(function () {
// 获取用户姓名和密码的值
var uname = $("#uname").val();
var upwd = $("#upwd").val();
// 判断姓名是否为空
if (isEmpty(uname)) {
// 如果姓名为空,提示用户(span标签赋值),并且return html()
$("#msg").html("用户姓名不可为空!");
return;
}
// 判断密码是否为空
if (isEmpty(upwd)) {
// 如果密码为空,提示用户(span标签赋值),并且return html()
$("#msg").html("用户密码不可为空!");
return;
}
// 如果都不为空,则手动提交表单
$("#loginForm").submit();
});
/**
* 判断字符串是否为空
* 如果为空,返回true
* 如果不为空,返回false
* @param str
* @returns {boolean}
*/
function isEmpty(str) {
if (str == null || str.trim() == "") {
return true;
}
return false;
}
</script>
</html>
4、主页.jsp
<%--
Created by IntelliJ IDEA.
User: 17624
Date: 2022/11/10
Time: 20:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h2>欢迎${user.userName}登录成功!</h2>
</body>
</html>
3、数据库项目包
单纯在java_text数据库下创建了一个tb_user表供前端访问
userId | userName | userPwd | userAge |
---|---|---|---|
1 | zhangsan | 1234 | 21 |
2 | admin | admin | null |
3 | 李四 | 1234 | null |