JavaWeb
一、JSP
1.1 概念:
Java Server Pages: 运行在Java服务器端的页面。
- 可以理解为:一个特殊的页面,其中既可以指定定义HTML标签,又可以定义Java代码。
- 本质:使用通过response对象获取打印流将页面信息打印至客户端进行网页的书写。
- 用于简化书写!!!
- JSP演变历史:
1、早期只有Servlet,只能使用response输出标签数据,非常麻烦。
2、后来有JSP,简化了Servlet的开发,如果过度使用JSP,在JSP中即写大量的Java代码,又写HTML,造成难于维护,难于分工协作。
3、再后来,Java的Web开发,借鉴MVC开发模式,使得程序的设计更加合理性。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
System.out.println("hello,jsp!");
%>
<h1>hello,jsp !</h1>
</body>
</html>
1.2 JSP的原理
- JSP本质
就是一个Servlet。
第一次请求JSP导致加载JSP响应过慢的情况称之为第一人惩罚策略。
-
运行原理:
1、客户端发送请求
2、JSP翻译成Java文件
3、Java文件编译生成class文件
4、运行class文件,向客户端响应内容 -
执行流程:
当客户端请求对应的JSP时,服务器首先判断的是是否编译过,如果编译过继续判断,判断是否修改,如果修改重新编译,如果没有修改 ,则直接将之前编译的Servlet对象(JSP在执行时会翻译成Servlet)返回并进行服务处理。
1.3 JSP指令
-
作用:
用于配置JSP页面,导入资源文件。
-
格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
-
分类:
1、
page
用于配置当前JSP页面的属性,定义怎样运行JSP页面(一般不会自己特殊书写 而是通过创建自动定义)。- 语法:<%@ page 属性名=“值” 属性名=“值”%>
- 属性:
contentType
:contentType="text/html; charset=UTF-8";
等同于response.setContentType()。- 1、设置响应体的MIME类型以及字符集。
- 2、设置当前JSP页面的编码(只能是高级的IDE-集成开发工具才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)。
-
pageEncoding
:代表的是当前页面的编码,JSP翻译成Java文件,服务器需要知道JSP文件的编码方式,一般设置为UTF-8。 -
language
:定义语言。 -
import
:导入Java包,可以出现多次,也可以写一个,包之间使用逗号隔开。一般直接在<% %>
中书写对应类使用快捷键提示可以直接生成。 -
errorPage
:当前页面发生异常后,会自动跳转到指定的错误页面。 -
isErrorPage
:标识当前也是是否是错误页面。true
:是,可以使用内置对象exception。false
:否。默认值。不可以使用内置对象exception。
-
isElIgnored
:决定jsp页面是否忽略EL表达式(默认不忽略)。true
:是。EL表达式被忽略,使用无效。false
:否。默认值。可以使用EL表达式。
2、
include
完成页面包含的、导入页面的资源文件。- 语法:
<%@include file="xxx.jsp"%>
- 原理:
- 静态包含:把包含文件的代码复制到当前文件,一起翻译为Java文件,一起编译。
- 该指令可以理解为将指定的JSP页面内容复制至当前指定位置。
- 使用:
- 这个指令,经常用于重复功能的书写,将多个页面重复的功能书写在一个JSP中,其他页面通过引用的方式进行使用。例如:网站的导航栏以及尾部信息。
3、
taglib
用于导入资源、导入其他标签库。- 语法:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix
:用于定义前缀,是自定义的。
1.4 JSP的脚本
- JSP定义Java代码的方式:
1、
<% Java代码 %>
:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
2、<%! 声明 %>
:定义的Java代码,在JSP转换后的Java类的成员位置,书写的是方法。
3、<%=Java表达式 %>
:定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。等价于write.print("");
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
System.out.println("hello,jsp!");
int j = 5;//局部变量,在service()方法中。
%>
<%!
//声明方法
public int sum(int c,int d){
return c + d;
}
%>
<%
int a = 10;
int b = 60;
sum(a,b);
%>
<!-- %=之间不能有空格,相对于输出语句。-->
<%= "hello,jsp !" %>
<h1>hello,jsp !</h1>
</body>
</html>
1.5 注释
-
HTML注释:
<!-- 代码 -->
:只能注释HTML代码片段。被注释的代码依旧会被发送到客户端浏览器中,即使浏览器页面不会展示,但F12
检查源码时,在源码中被注释的代码片段还能被查到。会发送至客户端,客户端可以查看。 -
Java注释:
<% //代码 %>
/<% /* 代码 */ %>
:注释Java代码,书写在Java小脚本中。在读取JSP后,解释Java代码、编译时忽略。 -
JSP注释:
<%-- 代码 --%>
:可以注释所有。被注释的代码不会被发送到浏览器中,F12
检查源码时,找不到被注释的内容(推荐以后使用这种注释方法)。在读取JSP时自动忽略。
1.6 动作标签
-
概念:
JSP标签,但是需要放在服务器端运行,才能访问。
-
作用:
JSP动作标签代替Java代码方式,通过标签的使用减少Java代码的书写。
-
分类:
1、页面转发
-
语法:
<jsp:forward page="xxx.jsp">
:代表请求的转发;page代表的是转发的页面。 -
虽然该方法可以转发页面,但是实际开发过程中我们通常使用Servlet转发JSP显示数据的形式进行操作,不会使用JSP转发到JSP,因为在书写代码时尽量减少JSP页面中Java代码的书写,防止混淆。
2、页面引入
-
语法:
<jsp:include page="xxx.jsp" />
:代表页面的包含(动态包含,不管动态包含,静态包含,产生效果一样,但是原理不同)。 -
与include指令一样都可以将指定页面引入到当前页面,效果也是相同,但是原理不同。
-
<!-- 将请求转发 这样look.jsp与当前jsp使用相同的请求对象 -->
<%-- <% request.getRequestDispatcher("look.jsp").forward(request, response); %>
--%>
<!-- jsp提供了相应的标签 替换java代码的书写 -->
<jsp:forward page="look.jsp"/>
<%@ include file="a.jsp"%>
<hr>
<jsp:include page="a.jsp" />
- includle动作标签与include指令的区别:
- includle动作标签是动态引入。是将指定的JSP翻译成Servelt执行后将结果引入到当前Servlet中(会将所有涉及的Servlet全部翻译执行)。
- include指令是静态引入。是在将JSP翻译成Servlet时,将指定页面代码复制至当前页面,之后翻译成一个Servlet之后编译执行(只翻译执行一个servlet)。
- 使用场景:如果使用的JSP中没有书写Java,只是静态页面内容可以直接使用include指令引入,如果相应的JSP中需要执行代码建议使用includle标签,如果考虑到执行效率问题,也可以使用include指令。
1.7 JSP的内置对象
- 在JSP页面中不需要获取和创建,可以直接使用的对象。
- JSP一共有9个内置对象:
pageContext(PageContext) 当前页面
request(HttpServletRequest) 当前请求
session(HttpSession) 当前会话
application(ServletContext) 当前应用
response(HttpServletResponse) 响应信息
page(Object) 当前页面的Servlet对象
out(JspWriter / printWriter) 字符输出流对象
config(ServletConfig) Servlet配置对象
exception(Throwable) 异常对象
变量名 | 真实类型 | 作用 |
---|---|---|
pageContext | PageContext | 在当前页面中共享数据;还可以获取其他八个内置对象。域对象 |
request | HttpServletRequest | 在一次请求中访问的多个资源(转发)。域对象 |
session | HttpSession | 在一次会话多个请求之间共享数据。域对象 |
application | ServletContext | 在整个应用的所有用户之间共享数据。域对象 |
response | HttpServletResponse | 保存请求页面的响应信息对象 |
page | Object | 当前页面(Servlet)对应的对象this |
out | JspWriter | 字符输出流对象,可以将数据输出到页面上。和response.getWriter()类似 |
config | ServletConfig | Servlet的配置对象 |
exception | Throwable | 异常对象。用于存储当前页面异常信息,当页面发送异常时将异常信息存储至当前对象。主要在isErrorPage = true 时,exception对象才能够被使用 |
- response.getWriter()和out.write()的区别:
- 1、在Tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
- 2、response.getWriter()数据输出永远在out.write()之前。
-
pageContext
代表的是当前页面上下文对象,也是一个域对象,代表范围是当前页面。
- 作用:
- 1、域对象,代表范围是当前页面。
- 2、可以获取其他八个内置对象。
ServletRequest request = pageContext.getRequest();//获取request对象
HttpSession session = pageContext.getSession();//获取session对象
ServletContext application = pageContext.getApplication();//获取application 对象
- 3、可以向其他域对象存取值。
pageContext.setAttribute("test", "11", PageContext.SESSION_SCOPE);//通过pageContext向session域对象存入值
pageContext.getAttribute("test", PageContext.SESSION_SCOPE);//通过pageContext从session域对象获取值
pageContext.findAttribute("test")//从小的范围向大的范围依次查找,直到找到为止
- 作用:
-
9个内置对象的代码演示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>page</title>
</head>
<body>
page.jsp
<!-- 四大作用域 -->
<!-- 方法通用 都是为指定作用域中添加数据 获取数据 删除数据 -->
<br>pageContext作用域范围为当前页面<br>
<% pageContext.setAttribute("pageContext", "只有当前页面生效"); %>
<%=pageContext.getAttribute("pageContext") %>
<br>request作用域范围为本次请求,如果通过转发其他页面也可以访问<br>
<% request.setAttribute("request", "本次请求生效"); %>
<%=request.getAttribute("request") %>
<br>session作用域范围为当前会话,浏览器不关闭其他分页打开不同页面也可以访问<br>
<% session.setAttribute("session","本次会话生效"); %>
<%=session.getAttribute("session") %>
<br>application作用域为当前服务器,只要服务器不关闭都可以后期<br>
<% application.setAttribute("applicaton", "当前服务器生效"); %>
<%=application.getAttribute("applicaton") %>
<!-- 将请求转发 这样look.jsp与当前jsp使用相同的请求对象 -->
<% request.getRequestDispatcher("look.jsp").forward(request, response); %>
</body>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>look</title>
</head>
<body>
look.jsp
<!-- 四大作用域 -->
<!-- 方法通用 都是为指定作用域中添加数据 获取数据 删除数据 -->
<br>pageContext作用域范围为当前页面<br>
<%=pageContext.getAttribute("pageContext") %>
<br>request作用域范围为本次请求,如果通过转发其他页面也可以访问<br>
<%=request.getAttribute("request") %>
<br>session作用域范围为当前会话,浏览器不关闭其他分页打开不同页面也可以访问<br>
<%=session.getAttribute("session") %>
<br>application作用域为当前服务器,只要服务器不关闭都可以后期<br>
<%=application.getAttribute("applicaton") %>
</body>
1.8 案例
1.8.1 显示最后一次访问的登录时间
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//设置响应的学习体的数据格式以及编码
response.setContentType("text/html;charset=utf-8");
//1.获取所有Cookie
Cookie[] cookies = request.getCookies();
boolean flag = false;//没有cookie为lastTime
//2.遍历Cookie数组
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
//3.获取cookie的名称
String name = cookie.getName();
//4.判断名称是否是:lastTime
if ("lastTime".equals(name)) {
//有该Cookie,不是第一次访问
flag = true;//有lastTime的cookie
//设置Cookie的value
//获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
System.out.println("编码前:" + str_date);
//URL编码
str_date = URLEncoder.encode(str_date, "utf-8");
System.out.println("编码后:" + str_date);
cookie.setValue(str_date);
//设置cookie的存活时间
cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
response.addCookie(cookie);
//响应数据
//获取Cookie的value,时间
String value = cookie.getValue();
System.out.println("解码前:" + value);
//URL解码:
value = URLDecoder.decode(value, "utf-8");
System.out.println("解码后:" + value);
%>
<h1>欢迎回来,您上次访问时间为:<%=value %>
</h1>
<%
break;
}
}
}
if (cookies == null || cookies.length == 0 || flag == false) {
//没有,第一次访问
//设置Cookie的value
//获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
System.out.println("编码前:" + str_date);
//URL编码
str_date = URLEncoder.encode(str_date, "utf-8");
System.out.println("编码后:" + str_date);
Cookie cookie = new Cookie("lastTime", str_date);
//设置cookie的存活时间
cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
response.addCookie(cookie);
%>
<h1>您好,欢迎您首次访问</h1>
<%
}
%>
</body>
</html>
1.8.2 用户登录并保存登录信息
-
需求:
1、使用request域对象完成,登录失败后页面信息的显示登录成功,进入登录成功页面,登录失败返回登录页面,并在页面打印登录失败相应信息。
2、使用session域对象完成免密登录操作。当请求/login url时,如果没有登录成功过则跳转登录页面,如果已经登录成功过,那么直接跳转至成功页面,无需再次登录。
-
代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>login</title>
</head>
<body>
<form action="login" method="post">
账号:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="登录"><br/>
</form>
<font style="red"><%=request.getAttribute("error") %></font>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>success</title>
</head>
<body>
<%=request.getSession().getAttribute("username")%>,欢迎您
</body>
</html>
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//当请求/login url时 如果没有登录成功过则跳转登录页面,如果已经登录成功过 那么直接跳转至成功页面 无需再次登录
HttpSession session = request.getSession();
Object u1 = session.getAttribute("username");
Object p1 = session.getAttribute("password");
if(u1!=null&&p1!=null){
request.getRequestDispatcher("/success.jsp").forward(request, response);
}else{
request.setAttribute("error", "");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
if ("admin".equals(username) && "admin".equals(password)) {
//登录成功后将数据存储在session中
HttpSession session = request.getSession();
session.setAttribute("username",username);
session.setAttribute("password",password);
request.getRequestDispatcher("/success.jsp").forward(request, response);
} else {
request.setAttribute("error", "账号或密码错误!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
二、EL表达式
2.1概念
Expression Language
:表达式语言。
- 原理:EL表达式的出现目的是替换JSP中的Java的脚本中的
<%= %>
。并且内部进行了null值判断,如果为null则不会输出 ,不为null输出对应数据。
- 使用场景:
1、获取域对象中的值(重要)。
2、执行运算符号。
3、调用Java中方法(了解)。
4、EL表达式内置常用对象(重要)。
2.2 作用
可以替换和简化JSP页面中Java代码的编写。
2.3 语法
-
语法:
${表达式}
-
注意
JSP默认支持EL表达式的。
如果要忽略EL表达式:- 1、设置JSP中page指令中:
isELIgnored="true";
忽略当前JSP页面中所有的EL表达式。 - 2、
\${表达式}
:忽略当前这个EL表达式。
- 1、设置JSP中page指令中:
-
代码演示:
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="true" language="java" %>
<%-- isELIgnored="true"; 忽略当前jsp页面中所有的EL表达式 --%>
<html>
<head>
<title>Title</title>
</head>
<body>
${3 > 4}
<%--
<%= request.getAttribute("msg")%>
--%>
<!-- 等价于<%= %>输出内容 会自动获取域中数据 并进行null值判断 -->
${msg}
<%-- \${表达式}:忽略当前这个el表达式 --%>
\${3 + 4}
</body>
</html>
2.4 EL表达式的使用
2.4.1 运算
基础运算 | 加减乘除取模 | 备注 |
---|---|---|
关系运算 | == eq > gt < lt >= ge <= le != ne | 等于 大于 小于 大于等于 小于等于 不等于 |
逻辑运算 | && and ! not || or | 与 非 或 |
empty运算符 | empty | 判断对象是否存在,或者集合的长度是否为0。${empty list} :判断字符串、集合、数组对象是否为null或者长度为0。${not empty str} :表示判断字符串、集合、数组对象是否不为null 并且 长度>0。 |
- 运算符:
1、算数运算符: +、-、*、/(div)、%(mod)
2、比较运算符: >(gt)、<(lt)、>=(ge)、<=(le)、==(eq)、!=(ne)
3、逻辑运算符: &&(and)、||(or)、!(not)
4、空运算符: empty- 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0。返回值为true / false。
${empty list}
:判断字符串、集合、数组对象是否为null或者长度为0。${not empty str}
:表示判断字符串、集合、数组对象是否不为null,并且长度>0。
- 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0。返回值为true / false。
<h3>算数运算符</h3>
${3 + 4}<br/>
${3 - 4}<br/>
${3 * 4}<br/>
${3 / 4}<br/>
${3 div 4}<br/>
${3 % 4}<br/>
${3 mod 4}<br/>
<h3>比较运算符</h3>
${3 > 4}<br/>
${3 gt 4}<br/>
${3 < 4}<br/>
${3 lt 4}<br/>
${3 == 4}<br/>
${3 eq 4}<br/>
${3 != 4}<br/>
${3 ne 4}<br/>
${3 >= 4}<br/>
${3 ge 4}<br/>
${3 <= 4}<br/>
${3 le 4}<br/>
<h3>逻辑运算符</h3>
${3 > 4 && 3 < 4}<br/>
${3 > 4 and 3 < 4}<br/>
${3 > 4 || 3 < 4}<br/>
${3 > 4 or 3 < 4}<br/>
${!3 < 4}<br/>
${not 3 < 4}<br/>
<h3>空运算符</h3>
<%
String str = "";
requset.setAttribute("str",str);
%>
${empty str} //false,判断域对象中a是否为空或者长度为0
${not empty str} //false,判断域对象中a是否不为空,并且长度 > 0
2.4.2 获取值
-
EL表达式只能从域对象中获取值。
-
语法:
1、
${域名称.键名}
- 从指定域中获取指定键的值。
- 域名称:
- pageScope --> pageContext
- requestScope --> request
- sessionScope --> session
- applicationScope --> application(ServletContext)
- 举例:在request域中存储了name=张三
- 获取:${requestScope.name}
2、
${键名}
:- 表示依次从最小的域中查找是否有该键对应的值,直到找到为止。如果使用自动查找,建议多个域中不要存储相同的key。
${key}
3、获取对象、数组、List集合、Map集合的值
- 对象:
${域名称.键名.属性名}
- 本质上会去调用对象的getter方法
- 数组:
${域名城.键名[索引]}
- List集合:
${域名称.键名[索引]}
- Map集合:
${域名称.键名.key名称}
${域名称.键名["key名称"]}
-
代码演示:
<%-- 向不同域存值 --%>
<%
/*分别为不同域设置相应key 不同值的数据*/
pageContext.setAttribute("key","pageValue");
request.setAttribute("key","requestValue");
session.setAttribute("key","sessionValue");
application.setAttribute("key","applicationValue");
%>
<%-- 从不同域中取值 --%>
<%-- 1.指定取值的域 从中取值 --%>
当前页面:${pageScope.key}<br>
当前请求:${requestScope.key}<br>
当前会话:${sessionScope.key}<br>
当前应用:${applicationScope.key}<br>
<%-- 2.自动查找域中的值 从作用域小的向上查找--%>
<%-- 自动查找会由下向上查找第一个指定的key并返回 如果使用自动查找 建议多个域中不要存储相同的key--%>
自动查找:${key} ——> 查找到的key是pageScope.key
<%-- 获取对象、数组、List集合、Map集合的值 --%>
<h3>从Java的对象中获取值</h3>
<%
User user = new User();
user.setUsername("aaa");
user.setPassword("123");
pageContext.setAttribute("user", user);
%>
${ user.username }
${ user.password }
<h3>从数组中获取值</h3>
<%
String [] arr = {"美美","小风","小花"};
// EL表达式获取的是域对象中的值
pageContext.setAttribute("arr", arr);
%>
${ pageScope.arr[0] }
${ pageScope.arr[1] }
${ arr[2] }
<h3>从Map集合获取值</h3>
<%
Map<String,String> map = new HashMap<String,String>();
map.put("aaa", "美美");
map.put("bbb", "小风");
map.put("ccc", "小花");
pageContext.setAttribute("map", map);
%>
${ map.aaa }
${ map.ccc }
<h3>从List集合中获取Java的对象的值</h3>
<%
List<User> list = new ArrayList<User>();
list.add(new User("aaa","123"));
list.add(new User("bbb","456"));
list.add(new User("ccc","789"));
pageContext.setAttribute("list", list);
%>
${ list[0].username }
<body>
<%-- 从域中取值(数组 list集合 map集合)并打印获取 --%>
<%
//分别创建数组 list集合 map集合 对象 存储至域中
String [] arr={"张三","李四","王五"};
ArrayList<String> arrayList=new ArrayList<>();
Collections.addAll(arrayList,"二狗子","猪蹄子");
HashMap<String,String> hashMap=new HashMap<>();
hashMap.put("username","zhangsan");
hashMap.put("password","123456");
Student student=new Student("lisi","abcddef");
//存到域中
pageContext.setAttribute("arr",arr);
pageContext.setAttribute("arrayList",arrayList);
pageContext.setAttribute("hashMap",hashMap);
pageContext.setAttribute("student",student);
%>
获取数组数据
<%-- 可以直接通过 域key值[索引] 的形式获取数组中对应的数据 --%>
${arr[0]}
${arr[1]}
${arr[2]}
<hr>
获取list集合数据
<%-- 可以直接通过 域key值[索引] 的形式获取数组中对应的数据 --%>
${arrayList[0]}
${arrayList[1]}
<%-- 也可以通过对应对象的方法进行操作(会进行类型转换) --%>
${arrayList.get(0)}
${arrayList.get(1)}
<hr>
获取map集合数据
<%-- 可以直接通过 域key值.map的key 形式获取对应的value--%>
${hashMap.username}
${hashMap.password}
<%-- 也可以通过对应对象的方法进行操作(会进行类型转换) --%>
${hashMap.get("username")}
${hashMap.get("password")}
<hr>
获取对象中的属性值
<%-- 可以直接通过 域key值.属性 形式获取对应的value --%>
${student.username}
${student.password}
<%-- 也可以通过对应对象的方法进行操作(会进行类型转换) --%>
${student.getUsername()}
<%-- 注意 在获取自定义对象属性时 如果使用.属性的形式进行获取 那么必须书写公开的的get方法 --%>
</body>
2.4.3 隐式对象
- EL表达式中有11个隐式对象。
对象 | 含义 |
---|---|
pageScope requestScope sessionScope applicationScope | 代表当前页面 page 代表当前请求 request 代表当前会话 session 代表当前应用 application |
param | 返回客户端请求参数字符串值,相当于request.getParameter(String name) |
initParam | 保存环境参数,相对于application.getInitParameter(String name) |
paramValues | 返回客户端请求参数字符串值,相当于request.getParameterValues(String name) |
pageContext | 可以获取其他八个内置对象,还可以获取虚拟目录 |
header | 保存用户浏览器和服务端用来沟通的数据,相对于request.getHeader(String name) |
headerValues | 代表请求头,相对于request.getHeaders(String name) |
cookie | 代表客户端发送请求中的所有cookie,相对于request.getCookies() |
- pageContext:
1、获取JSP其他八个内置对象。
2、${pageContext.request.contextPath}
:动态获取虚拟目录。
<h3>pageContext获取JSP其他八个内置对象。</h3>
${pageContext.request}
${pageContext.session}
${pageContext.servletContext}
${pageContext.response}
${pageContext.page}
${pageContext.out}
${pageContext.servletConfig}
${pageContext.exception}
<h3>pageContext动态获取虚拟目录</h3>
${pageContext.request.contextPath}
<h3>获取请求参数</h3>
<%= request.getParameter("username") %>
<h3>EL的方式</h3>
${ param.username }
${ paramValues.username[0] }
<h3>获取到请求头的信息</h3>
<%= request.getHeader("user-agent") %>
<h3>EL的方式</h3>
${ header["user-agent"] }
三、JSTL标签库
3.2 概念
JavaServer Pages Tag Library
:JSP标准标签库。
- 是由Apache组织提供的开源的免费的JSP标签<标签>。
- JSTL依赖EL表达式,获取值是由EL表达式来获取的。
- 使用场景:
1、向域对象存取值。
2、判断域对象中的值。
3、循环域对象中的值。
<%-- 书写存储对象的集合 并存储至域中在jsp页面打印 --%>
<%
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("zhangsan", "123456"));
list.add(new Student("wangwu", "456788"));
list.add(new Student("lisi", "987654"));
pageContext.setAttribute("list",list);
pageContext.setAttribute("s",new Student("lisi", "987654"));
%>
<%-- jsp el表达式只是替代获取与输出脚本 不能进行额外的操作 所以在获取集合时 只能依次取出 --%>
<table border="1">
<thead><tr><td>序号</td><td>账号</td><td>密码</td></tr></thead>
<tbody>
<tr><td>1</td><td>${list[0].username}</td><td>${list[0].password}</td></tr>
<tr><td>2</td><td>${list[1].username}</td><td>${list[1].password}</td></tr>
<tr><td>3</td><td>${list[2].username}</td><td>${list[2].password}</td></tr>
<tr><td>4</td><td>${list[3].username}</td><td>${list[3].password}</td></tr>
</tbody>
</table>
<%-- 但是一般数据由后台(servlet)从数据库中取出 不一定有多少条 虽然越界不会显示数据 --%>
<%-- 但是html对应的还是会显示 这个时候就需要使用jstl帮我们进行一些特殊的书写 --%>
3.2 作用
用于简化和替换JSP页面上的Java代码。
3.3 使用步骤
1. 导入JSTL相关jar包
javax.servlet.jsp.jstl.jar
jstl-impl.jar
2. 引入标签库:
- taglib指令:
<%@ taglib prefix=" " uri=" " %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3. 使用标签
//out:输出内容(域对象,常量)
//value:输出的内容 default:代表默认值 escapeXml:是否转义(如果value又特殊字符,不转义)
<c:out value="${requestScope.username}" default="name"></c:out>
<c:out value="<a href='http://www.baidu.com'>点击</a>" escapeXml="false"></c:out>
//set 向域对象中存入值
//var:变量名 value:变量的值 scope:域范围
<c:set var="password" value="12345" scope="request"></j:set>
//remove:从域对象中删除值 var:要移除的key值
<c:remove var="password"></c:remove>
3.4 JSTL标签库的使用
<%-- JSTL功能--%>
<%-- 1.对域对象进行赋值--%>
<%-- (1)c:set var声明变量(存储在域中的key) value值(存储在域中的值) scope选择域(存储在那个域中)--%>
<c:set var="aaa" value="bbb" scope="session"/>
${aaa}
<%-- (2)c:set target对象名(要修改属性的对象) property要修改的属性 value要修改的值 --%>
<c:set target="${s}" property="username" value="sssss"/>
${s}
<%-- 2.将指定数据输出 并进行设置 --%>
<%-- value输出的数据 default当数据为null时替代输出的数据 默认为""空字符串 escapeXml是否转义 --%>
<c:out value="${null}" default="默认值" escapeXml="false"/>
<%-- 3.移除域中指定数据 --%>
<%-- var移除的key scope移除数据的作用域 如果没有会自动查找 --%>
<c:remove var="s" scope="page"/>
<c:out value="${s}" default="没有数据" escapeXml="false"/>
3.5 常用标签
3.5.1 if标签
if
:对语句进行判断;相当于Java代码的if语句。
-
语法:
<c:if test="判断的条件(boolean表达式)" var="条件的结果" scope="作用域"></if>
-
属性:
test
:判断的条件,必须属性,接受boolean表达式。- 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容。
- 一般情况下,test属性值会结合EL表达式一起使用。
var
:把判断的条件的结果(true或者false)保存到var中。scope
:作用域(将var值存放的作用域)。
-
注意:
c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签。
-
代码演示:
<%-- 对域中数据进行判断操作 --%>
<%-- 根据结果对页面内容进行书写 --%>
<%-- c:if 根据test返回的结果执行对应代码块 将结果保存到var定义的变量并存储到scope设置的作用域中 --%>
<c:if test="${s.username eq 'lisi'}" var="jg" scope="page">
你叫李四
</c:if>
<c:if test="${s.username ne 'lisi'}">
你不叫李四
</c:if>
3.5.2 choose标签
choose
:用来进行判断,但是重合的标签;相当于Java代码的switch语句。
- 使用choose标签声明 相当于switch声明
- 使用when标签做判断 相当于case
- 使用otherwise标签做其他情况的声明 相当于default
- 语法:
<c:choose>
<c:when></c:when>
<c:otherwise></c:otherwise>
</choose>
- 代码演示:
<%-- 当判断的条件存在多个并可能取反的时候 需要使用c:choose标签 --%>
<%-- 可以看做 if esle if else --%>
<c:choose>
<c:when test="${s.username eq 'zhangsan'}">你是张三</c:when>
<c:when test="${s.username eq 'lisi'}">你是李四</c:when>
<c:otherwise>我不认识你</c:otherwise>
</c:choose>
3.5.3 foreach标签
foreach
:用来迭代数据;相当于Java代码的for语句。
-
语法:
<c:forEach var=" " begin=" " end=" " step=" " varStatus=" " ></c:forEach>
-
属性:
var
:声明临时变量。begin
:从那开始。end
:结束。step
:步长。varStatus
:变量的状态。- index:当前这次迭代从 0 开始的迭代索引。
- count:当前这次迭代从 1 开始的迭代计数。
- current:当前这次迭代的(集合中的)项。
- first:用来表明当前这轮迭代是否为第一次迭代的标志。
- last:用来表明当前这轮迭代是否为最后一次迭代的标志。
items
:需要遍历的集合。
-
代码演示:
<h3>模拟普通的for循环</h3>
<c:forEach var="i" begin="1" end="10" step="2" varStatus="vs">
${ i }
${ vs.count }
</c:forEach>
<h3>模拟增强for循环的效果</h3>
<!--
for(String s : list){}
-->
<%
List<String> list = new ArrayList<String>();
list.add("美美");
list.add("小风");
list.add("小花");
pageContext.setAttribute("list", list);
%>
<c:forEach var="s" items="${ list }">
${ s }
</c:forEach>
<h3>map集合</h3>
<%
Map<String,String> map = new HashMap<String,String>();
map.put("aaa", "美美");
map.put("bbb", "小风");
map.put("ccc", "小花");
pageContext.setAttribute("map", map);
%>
<c:forEach var="entry" items="${ map }">
${ entry.key } -- ${ entry.value }
</c:forEach>
<h3>List集合中存入对象</h3>
<%
List<User> ulist = new ArrayList<User>();
ulist.add(new User("aaa","123"));
ulist.add(new User("bbb","456"));
ulist.add(new User("ccc","789"));
pageContext.setAttribute("ulist", ulist);
%>
<c:forEach var="user" items="${ ulist }">
${ user.username } -- ${ user.password }
</c:forEach>
<%-- 当需要对域中存储的集合数据进行操作时 需要根据数据的实际数量进行页面的书写 --%>
<%-- 这个时候就需要使用c:foreach标签 --%>
<%-- 1.普通的循环操作 将内容重复指定次数输出 --%>
<%-- var声明保存数据的变量(初始化语句) begin初始化变量的初始值 end结束值 step步长(迭代语句) --%>
<%-- varStatus保存当前变量数据的信息对象 通过设置的对象名.属性名获取对应的信息 --%>
<c:forEach var="i" begin="0" end="10" step="2" varStatus="status">
${i} /${status.end} <br>
</c:forEach>
<%-- 2.遍历域中集合数据 --%>
<%-- 只需要var 以及items 也可以携带 varstatus --%>
<%-- var 每次取出的数据遍历 items域中存储的遍历的集合 --%>
<c:forEach var="student" items="${list}" varStatus="status">
${student}<br>
</c:forEach>
<%-- 通常使用表格以及c:foreach进行数据的展示 --%>
<table border="1">
<thead>
<tr>
<td>序号</td>
<td>账号</td>
<td>密码</td>
</tr>
</thead>
<tbody>
<c:forEach var="student" items="${list}" varStatus="status">
<c:if test="${status.count%2==0}">
<tr style="background-color: red"><td>${status.count}</td><td>${student.username}</td><td>${student.password}</td></tr>
</c:if>
<c:if test="${status.count%2!=0}">
<tr style="background-color: green"><td>${status.count}</td><td>${student.username}</td><td>${student.password}</td></tr>
</c:if>
</c:forEach>
</tbody>
</table>
3.6 案例
-
需求:
在request域中有一个存有User对象的List集合。需要使用JSTL+EL将List集合数据展示到JSP页面的表格table中。
-
代码实现:
导包:
druid.jar
mysql-connector-java.jar
jstl.jar
standard.jar
sql语句:
CREATE TABLE `student` (
`studentid` int(20) NOT NULL,
`studentname` varchar(20) DEFAULT NULL,
`studentage` int(11) DEFAULT NULL,
`studentsex` char(10) DEFAULT NULL,
`studentaddress` varchar(50) DEFAULT NULL,
`classid` int(11) DEFAULT NULL,
PRIMARY KEY (`studentid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `student` VALUES ('2010001', 'Jack', '16', '男', '湖北襄樊', '1');
INSERT INTO `student` VALUES ('2010002', 'Scott', '20', '男', '湖北武汉', '2');
INSERT INTO `student` VALUES ('2010003', 'Lucy', '20', '女', '湖北武汉', '3');
INSERT INTO `student` VALUES ('2010004', 'Alan', '20', '女', '湖北襄樊', '4');
INSERT INTO `student` VALUES ('2010005', 'Bill', '20', '男', '湖北襄樊', '5');
INSERT INTO `student` VALUES ('2010006', 'Bob', '20', '男', '湖北宜昌', '6');
INSERT INTO `student` VALUES ('2010007', 'Colin', '20', '女', '湖北襄樊', '6');
INSERT INTO `student` VALUES ('2010008', 'Fred', '20', '男', '湖北宜昌', '5');
INSERT INTO `student` VALUES ('2010009', 'Hunk', '20', '男', '湖北武汉', '4');
INSERT INTO `student` VALUES ('2010010', 'Jim', '20', '男', '湖北襄樊', '3');
INSERT INTO `student` VALUES ('2010011', 'Jvm', '24', '男', '湖北武汉', '1');
INSERT INTO `student` VALUES ('2010012', 'jxm', '20', '男', '湖北武汉', '2');
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) DEFAULT NULL,
`password` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', 'zhangsan', '123');
INSERT INTO `user` VALUES ('2', 'lisi', '234');
INSERT INTO `user` VALUES ('3', 'wangwu', '123');
INSERT INTO `user` VALUES ('4', 'wangwu', '123');
INSERT INTO `user` VALUES ('5', 'wangwu', '123');
INSERT INTO `user` VALUES ('6', 'zhang', '123456');
INSERT INTO `user` VALUES ('7', 'zhang', '123456');
INSERT INTO `user` VALUES ('8', 'zhang', '123456');
INSERT INTO `user` VALUES ('9', '张三', '123456');
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>login</title>
</head>
<body>
<form action="login" method="post">
账号:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="登录"><br/>
</form>
<font color="red">${error}</font>
</body>
</html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="com.ys.servlet.User"%>
<%@ 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>success</title>
</head>
<body>
<table border="1" cellpadding="0" cellspacing="0" align="center"
width="700px">
<thead>
<tr>
<td>序号</td>
<td>账号</td>
<td>密码</td>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${user}" varStatus="status">
<tr>
<td>${status.count}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
LoginServlet.java
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
/**
* 书写学生类以及对应数据库信息,查询数据库完成登录操作,
* 登录成功后在登录成功页面打印数据库中学生表所有数据
*
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if(user != null){
request.getRequestDispatcher("/success.jsp").forward(request, response);
}else{
request.setAttribute("error", "");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("username");
String pwd = request.getParameter("password");
User loginUser = new User();
loginUser.setUsername(name);
loginUser.setPassword(pwd);
HttpSession session = request.getSession();
String sql1 = "select * from user where username = ? and password = ?";
ArrayList<User> user = AJDBCUtil.query(sql1, User.class, loginUser.getUsername(), loginUser.getPassword());
if (user.size() == 0) {
request.setAttribute("error", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
} else {
session.setAttribute("user", user);
request.getRequestDispatcher("success.jsp").forward(request, response);
}
}
}
AJDBCUtil.java
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.Properties;
public class AJDBCUtil {
private static DataSource druidDataSource = null;// 连接池对象
private AJDBCUtil() {
}
// 获取连接
// 使用Druid连接池加载配置获取连接
// 加载配置在静态代码块中进行执行
static {
try {
Properties p = new Properties();
InputStream is = AJDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties");
p.load(is);
// 创建连接池对象
druidDataSource = DruidDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接的方法本质就是使用连接池工厂对象获取连接池对象 之后获取连接
public static Connection getCon() {
Connection con = null;
try {
con = druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
// 更新操作方法
// 使用不确定参数的形式进行参数的输出
public static int update(String sql, Object... obj) {
// 获取连接
Connection con = getCon();
int count = 0;
try {
// 创建预编译声明对�? 将sql进行预编写
PreparedStatement ps = con.prepareStatement(sql);
// 将占位符数据填入
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
// 执行sql
count = ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return count;
}
// 满足事务操作的方式
public static int update(Connection con, String sql, Object... obj) throws SQLException {
int count = 0;
// 关闭事务的自动提交
con.setAutoCommit(false);
// 创建预编译声明对象 将sql进行预编译
PreparedStatement ps = con.prepareStatement(sql);
// 将占位符数据填入
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
// 执行sql
count = ps.executeUpdate();
return count;
}
// 查询操作方法
// 传入sql 传入保存数据的类的class类型 传入sql参数
public static <E> ArrayList<E> query(String sql, Class<E> c, Object... obj) {
ArrayList<E> list = new ArrayList<>();
// 获取连接
Connection con = getCon();
try {
// 创建预编译对象
PreparedStatement ps = con.prepareStatement(sql);
// 将数据加载
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
// 获取元数据
ResultSetMetaData metaData = ps.getMetaData();
// 获取查询结果列数
int columnCount = metaData.getColumnCount();
// 创建集合保存结果列名
ArrayList<String> columnName = new ArrayList<>();
for (int i = 1; i <= columnCount; i++) {
String cName = metaData.getColumnName(i);
columnName.add(cName);
}
// 执行sql
ResultSet rs = ps.executeQuery();
// 处理结果集
while (rs.next()) {
// 创建对象
E e = c.newInstance();
// 遍历列名 分别进行操作
for (String name : columnName) {
// 通过列名获取数据
Object value = rs.getObject(name);
// 通过反射获取当前类指定属性对象
Field nameField = c.getDeclaredField(name);
nameField.setAccessible(true);
// 将数据添加
nameField.set(e, value);
}
// 将对象存入集合
list.add(e);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
}
Student.java
public class Student {
private int studentid;
private String studentname;
private int studentage;
private String studentsex;
private String studentaddress;
private int classid;
public Student() {
super();
}
public Student(int studentid, String studentname, int studentage, String studentsex, String studentaddress,
int classid) {
super();
this.studentid = studentid;
this.studentname = studentname;
this.studentage = studentage;
this.studentsex = studentsex;
this.studentaddress = studentaddress;
this.classid = classid;
}
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
public int getStudentage() {
return studentage;
}
public void setStudentage(int studentage) {
this.studentage = studentage;
}
public String getStudentsex() {
return studentsex;
}
public void setStudentsex(String studentsex) {
this.studentsex = studentsex;
}
public String getStudentaddress() {
return studentaddress;
}
public void setStudentaddress(String studentaddress) {
this.studentaddress = studentaddress;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
@Override
public String toString() {
return "Student [studentid=" + studentid + ", studentname=" + studentname + ", studentage=" + studentage
+ ", studentsex=" + studentsex + ", studentaddress=" + studentaddress + ", classid=" + classid + "]";
}
}
User.class
public class User {
private int id;
private String username;
private String password;
public User() {
super();
}
public User(int id, String username, String password) {
super();
this.id = id;
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
}
}
druid.properties
url=jdbc:mysql://localhost:3306/db
#这个可以缺省的,会根据url自动识别
driverClassName=com.mysql.jdbc.Driver
username=root
password=root
##初始连接数,默认0
initialSize=10
#最大连接数,默认8
maxActive=30
#最小闲置数
minIdle=10
#获取连接的最大等待时间,单位毫秒
maxWait=2000
#缓存PreparedStatement,默认false
poolPreparedStatements=true
#缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置
maxOpenPreparedStatements=20
四、MVC和三层架构
4.1 MVC开发模式
4.1.1 组成
- MVC框架:
1、M:Model,模型。
JavaBean
- 完成具体的业务操作,如:查询数据库,封装对象。
2、V:View,视图。
JSP
- 展示数据。
3、C:Controller,控制器。
Servlet
- 获取用户的输入。
- 调用模型。
- 将数据交给视图进行展示。
3.1.2 优缺点
-
优点:
1、耦合性低,方便维护,可以利于分工协作。
2、重用性高。 -
缺点:
使得项目架构变得复杂,对开发人员要求高。
4.2 三层架构
4.2.1 组成
- 三层架构(软件设计架构):
1、界面层(表示层)
- 用户看的得界面。用户可以通过界面上的组件和服务器进行交互
2、业务逻辑层
- 处理业务逻辑的。
3、数据访问层
- 操作数据存储文件。
4.2.2 案例:用户信息列表展示
4.2.2.1 需求
用户信息的增删改查操作。
4.2.2.2 设计
-
技术选型:
Servlet + JSP + MySQL + JDBCTemplate + Duird + BeanUtils + Tomcat
-
数据库设计:
create database day17; -- 创建数据库
use day17; -- 使用数据库
create table user( -- 创建表
id int primary key auto_increment,
name varchar(20) not null,
gender varchar(5),
age int,
address varchar(32),
qq varchar(20),
email varchar(50)
);
insert into `user`(`id`,`name`,`gender`,`age`,`address`,`qq`,`email`) values (1,'张三','男',13,'陕西','12345','zhangsan@itcast.cn');
insert into `user`(`id`,`name`,`gender`,`age`,`address`,`qq`,`email`) values (2,'李四','女',15,'北京','88888','ls@itcast.cn');
4.2.2.3 开发
-
环境搭建:
- 创建数据库环境(建库、建表、导入数据)
- 创建项目,导入需要的jar包
- 把前端开发人员设计好的html页面、js、css、image等导入
-
编码:
总体功能流程分析:
- 单个页面功能分析:
- 代码实现:
项目百度链接:用户信息列表展示
提取码:1248
4.2.2.4 测试
4.2.2.5 部署运维
每日一点点进步
不进则退