JSP
一、Jsp简介
JSP(全称Java Server Pages)java服务器页面。 是一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。
JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求,本质是简化版的Servlet。
jsp 的本质是Servlet; 主要用于数据的呈现.
二、 创建一个JSP页面
如下图所示:点击后 输入页面名字即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U0Hl69dF-1651660782261)(img/image-20210627221130019.png)]
三、jsp的执行原理
第一次访问jsp的执行原理:
在第一次访问jsp页面时,会先将jsp翻译成jsp名_jsp.java 的源文件,然后再将其编译成字节码文件,在交给jvm来运行,然后输出其中静态内容。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8YQjtfFd-1651660782262)(img/img1.png)]
注意: 将jsp翻译成java文件的过程是由服务器完成的,用户是没法干涉的。
第二次访问jsp运行原理
第二次执行会跳过翻译和编译两个过程,直接执行字节码文件,输出响应内容。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0T0oDZEs-1651660782263)(img/img2.png)]
jsp的本质是一个servlet的原因是在编译成java文件之后,生成的java文件和servlet类基本是一致的,其中静态内容是有servlet 中响应对象输出去的,可以在虚拟工作空间查看。
jsp和servlet之间的联系和区别
jsp生成的java文件的继承关系图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLeh2nOY-1651660782263)(img/img3.png)]
联系:
jsp : jsp -> HttpJspBase -> HttpServlet
自定义servlet servlet -> HttpServlet
通过继承关系图可知,继承或者实现的接口都是一样的,只是具体的实现会有些不同。
区别:(记)
- jsp 主要数据的呈现而servlet ,主要数据的处理以对页面跳转的控制。
- jsp 是简化的servlet,是需要服务器来动态的生成java类的,servlet 本身就是一个java类。
- jsp是html作为模板的,其中包含前端静态的内容,而servlet 就是java是没办法包含前端静态内容的。
- jsp主要负责将前端内容利用servlet特性动态生成页面,而servlet负责servlet的所有功能,相对来说更全面。
- jsp中有九大内置对象,而servlet 中没有内置对象的概念。
四、jsp的组成
- 前端内容,包含html、css、javaScript
- java代码
- jsp中指令
- 动态标签
- 注释 <%-- 注释内容 – %>
五、java代码
jsp是以java作为脚本语言的,因此jsp 中是可以编写java代码的,在jsp中就java代码有三种存在形式。分别是java声明、java脚本、java表达式。
1. java声明
java的声明是在jsp 的方法外,类中创建的成员变量或者是方法。
语法: <%! java 声明 %>
2.jsp中的java脚本:
jsp 中的java脚本本质就是jsp中编写的java代码片段,java脚本的位置对应jsp生成的java代码中的service方法中。
语法: <% java脚本; %>
3.jsp中java表达式:
jsp 中的java表达式用于输出内容到页面,表达式的位置在service方法,和print()方法中的参数是一个位置。
语法: <%=表达式 %>
实例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
hello world!!!
<%-- 对于jsp中的java声明,相当于在 类中成员变量的位置写代码, 主要用于声明全局变量 , 创建方法 --%>
<%!
public int num = 10; // 全局变量
// 声明一个方法
public void method(){
System.out.println(num);
}
%>
<%!
int sum = 10 + 20;
%>
<%-- jsp 中的java脚本, 相当在service 方法中写代码 --%>
<%
response.getWriter().print(sum);
method();
%>
<%
int a = 10;
int b = 20;
%>
<%
int su = a + b;
System.out.println("两个数的和是: a + b : " + su);
%>
<%-- jsp中java表达式相当于在service方法中调用 response.getWriter().print(sum); 方法是print 方法中的参数--%>
<%=su%>
<%="我是java表达式"%>
</body>
</html>
jsp 中源码:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/9.0.53
* Generated at: 2021-09-16 08:27:06 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class first_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
public int num = 10; // 全局变量
// 声明一个方法
public void method(){
System.out.println(num);
}
int sum = 10 + 20;
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>Title</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\r\n");
out.write(" hello world!!!\r\n");
out.write("\r\n");
out.write(" ");
out.write("\r\n");
out.write(" ");
out.write("\r\n");
out.write("\r\n");
out.write(" ");
out.write("\r\n");
out.write(" ");
response.getWriter().print(sum);
method();
out.write("\r\n");
out.write(" ");
int a = 10;
int b = 20;
out.write("\r\n");
out.write(" ");
int su = a + b;
System.out.println("两个数的和是: a + b : " + su);
out.write("\r\n");
out.write("\r\n");
out.write('\r');
out.write('\n');
out.print(su);
out.write('\r');
out.write('\n');
out.print("我是java表达式");
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
六、JSP核心
Jsp的内容包含除了以上的html,css,js,jquery,java代码外,还可以包含JSP相关指令,主要作用用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。
1、三大指令
① page指令
<%@ page 属性名="值" 属性名="值" %> 控制整个jsp页面的配置信息
language="java" 支持的语言
contentType="text/html; charset=UTF-8" 内容类型
pageEncoding="UTF-8" 页面的编码格式
import="java.util.List,java.util.ArrayList" 导入jar
autoFlush="true" 自动刷新
errorPage="03-error.jsp" 如果当前页面抛异常 跳转指定页面
session="true" 当前页面中可以直接使用该对象
isELIgnored="false" 是否忽略EL表达式
② include指令
页面包含说的是一个页面可以包含另一个页面的内容,并且能正常加载。
语法:<%@ include file=”被包含的页面名称” %>
案例:
top.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>head</title>
</head>
<body>
<div>
<h1>页面顶部</h1>
</div>
</body>
</html>
body.jsp页面代码(包含top.jsp和footer.jsp):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>页面主体</title>
</head>
<body>
<%-- 将其他写好的页面包含到该页面
作用: 实现也页面的复用
该种包含成为静态包含:
该种包含的方式是先将被包含的页面整合到包含页面,然后在翻译成java文件.
--%>
<%@ include file="top.jsp"%>
<div>页面主体main</div>
<%@ include file="footer.jsp"%>
</body>
</html>
footer.jsp页面代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div>
<h3>页面底部内容</h3>
</div>
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88Cvixqj-1651660782265)(img/image-20210916171339507.png)]
include指令的主要作用:可以将页面公共的部分提取出来,让每个页面包含这个公共的页面,一是为了减少代码量,二是易于后续的维护。
③ taglib指令
后面使用JSTL标准标签库时使用。
语法:<%@ taglib prefix="前缀" uri="引入外部标签库的路径" %>
2、六大动作(了解)
作用:JSP动作标签利用XML语法格式的标记来控制Servlet引擎的行为。利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。
1. <jsp:forward></jsp:forward> 请求转发
<jsp:forward page="01-login.jsp"></jsp:forward>
2. <jsp:include ></jsp:include> 部分转发 也成为动态包含
<jsp:include page="包含页面地址.jsp"></jsp:include>
3. <jsp:useBean></jsp:useBean>
<%-- 3. 创建实体类对象 --%>
<jsp:useBean id="users01" class="com.ujiuye.bean.Users"></jsp:useBean>
4. <jsp:setProperty />
<%-- 4. 实体类对象中赋值 --%>
<jsp:setProperty property="username" name="users01" value="王二小"/>
5. <jsp:getProperty />
<%-- 5. 获取对象中的属性值 --%>
<jsp:getProperty property="username" name="users01"/>
代码示例:
User的实体类:
package com.ujiuye.bean;
public class User {
private String username;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
jsp页面代码:
请求转发:
<jsp:forward page="verifyCode?name=12345"></jsp:forward>
页面包含:
<%--
Created by IntelliJ IDEA.
User: dzm
Date: 2021-09-16
Time: 17:04
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>页面主体</title>
</head>
<body>
<%-- 先翻译后包含, 先将被包含的页面翻译成java文件,在包含页面通过方法引入,在运行时才会真正的将被包含页面包含进去--%>
<%-- 可以通过该指令向被包含页面传递参数 --%>
<jsp:include page="top.jsp">
<jsp:param name="demo" value="李四"/>
</jsp:include>
<div>页面主体main</div>
<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>
bean的用法:
<%--
Created by IntelliJ IDEA.
User: dzm
Date: 2021-09-16
Time: 17:36
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>
<jsp:useBean id="user1" class="com.ujiuye.bean.User"></jsp:useBean>
<jsp:setProperty name="user1" property="username" value="李四"></jsp:setProperty>
姓名: <jsp:getProperty name="user1" property="username"/>
<jsp:setProperty name="user1" property="password" value="123456"></jsp:setProperty>
密码: <jsp:getProperty name="user1" property="password"/>
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bhGTWpLC-1651660782265)(img/image-20210916174951885.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fic4HDrf-1651660782266)(img/image-20210916174558972.png)]
面试题:动态包含和静态包含有什么区别?
1、写法不同:
静态包含是指令包含<%@include file=”***”%>
动态包含是JSP动作标签包含<jsp:include page="***"></jsp:include>
2、编译方式不同:
静态包含:编译过程中将被包含的页面先整合到包含页面再编译。所以只有一个文件 .先包含后翻译
动态包含:编译过程中包含的页面与被包含的页面都编译,运行后内容再通过servlet整合,先翻译后包含
3、参数传递:
静态包含不能向被包含页面传递参数
动态包含可以使用jsp:param标签向被包含页面传递参数
4、运行效率:
静态包含快,当成了一个页面;动态包含是多个页面,运行慢。
3、九大内置对象
内置对象:也称隐式对象,在jsp中,已经初始化好并且给我们封装好了,不需要程序员创建,可以直接使用的对象就是内置对象。
七、九大内置对象的含义:
类型 | 内置对象名称 | 作用 |
---|---|---|
PageContext | pageContext | 设置页面作用域,可以获取页面信息,保存页面数等。作用范围当前页面 . |
HttpServletRquest | request | 请求作用域于,和servlet中的request作用一致。 |
HttpSession | session | 服务器会话对象,也是一个作用域对象。 |
ServletContext | application | 服务器对象,也是一个作用域对象,可以用于存储需要一致保留到服务器的数据。 |
HttpServletResponse | response | 响应对象,可以设置响应信息,和Servlet中response是一个对象 |
JSPWrite 继承PrintWriter | out | 用于响应输出内容到客户端,设置响应体中的数据。 |
ServletConfig | config | 设置和获取jsp的初始化配置信息,等同于Servlet中的ServletConfig。 |
this<=> object | page | 相当于this. |
Exception | pageContext.getException ()来获取 | 用于设置或者是获取页面的错误信息。 |
对象详解:
1.application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。该对象的类型是SevletContext类型,它的生命周期在tomcat服务器启动时创建,关闭时销毁。其作用范围为整个Web应用。
2.request 对象是 javax.servlet.HttpServletRequest类型的对象。该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。request对象的作用域为一次请求。
3.response 对象是 javax.servlet.HttpServletRsponse类型的对象。该对象代表客户端的响应信息,主要是将JSP容器处理过的对象信息返回到客户端。
4.config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
5.page:当前jsp页面的实例,相当于this关键字。
6.session:会话对象。session 对象是由服务器自动创建与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。其作用范围为一次会话。
7.exception对象的作用是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。
8.out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。JSP中的out对象是JspWriter类型。
9.pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,可以获取项目的根目录,还可通过getXXX()获取其他内置对象。
异常对象实例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--errorPage="error.jsp" 设置当前页面如果发生异常用来接收错误页面位置 ,
isErrorPage="false" 表示该页面不是错误页面,jsp页面默认都不是错误页面--%>
<%@ page errorPage="error.jsp" isErrorPage="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
int num = 10 / 0;
%>
</body>
</html>
接收异常信息的页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 表示当前页面专门用来接收错误信息并展示 --%>
<%@ page isErrorPage="true" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>错误页面</h2>
<%
Exception exception1 = pageContext.getException();
%>
<%=exception1.getMessage()%>
</body>
</html>
八、四大作用域
为了在页面、请求、和用户之间传递和共享数据,JSP提供了四个不同的作用域:pageContext(页面作用域)、request(请求作用域)、session(会话作用域)、application(应用程序作用域),这些作用域就规定了数据可以传递和共享的范围以及数据的存活时间。
作用域详解:
1.application 作用域
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。 整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。 application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
application作用域上的信息传递是通过ServletContext实现的,它提供的主要方法如下所示:
Object getAttribute(String name) //从application中获取信息;
void setAttribute(String name, Object value) //向application作用域中设置信息。
2.session作用域
session作用域比较容易理解,同一浏览器对服务器进行多次访问,在这多次访问之间传递信息,就是session作用域的体现。如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
session是通过HttpSession接口实现的,它提供的主要方法如下所示:
Object HttpSession.getAttribute(String name) //从session中获取信息。
void HttpSession.setAttribute(String name, Object value)//向session中保存信息。
HttpSession HttpServletRequest.getSession() //获取当前请求所在的session的对象。
session的开始时刻比较容易判断,它从浏览器发出第一个HTTP请求即可认为会话开始。但结束时刻就不好判断了,因为浏览器关闭时并不会通知服务器,所以只能通过如下这种方法判断:如果一定的时间内客户端没有反应,则认为会话结束。Tomcat的默认值为30分钟,但这个值也可以通过HttpSession的setMaxInactiveInterval()方法来设置:
void setMaxInactiveInterval(int interval);
如果想主动让会话结束,例如用户单击“注销”按钮的时候,可以使用 HttpSession 的 invalidate()方法,用于强制结束当前session:void invalidate()
3.request作用域
一个HTTP请求的处理可能需要多个Servlet合作,而这几个Servlet之间可以通过某种方式传递信息,但这个信息在请求结束后就无效了。request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。 所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
Servlet之间的信息共享是通过HttpServletRequest接口的两个方法来实现的:
void setAttribute(String name, Object value)//将对象value以name为名称保存到request作用域中。
Object getAttribute(String name) //从request作用域中取得指定名字的信息。
JSP中的doGet()、doPost()方法的第一个参数就是HttpServletRequest对象,使用这个对象的 setAttribute()方法即可保存信息。那么在设置好信息之后,要通过何种方式将信息传给其他的Servlet呢?这就要用到RequestDispatcher接口的forward()方法,通过它将请求转发给其他Servlet。
RequestDispatcher ServletContext.getRequestDispatcher(String path) //取得Dispatcher以便转发,path为转发的目的Servlet。
void RequestDispatcher.forward(ServletRequest request, ServletResponse response)//将request和response转发
因此,只需要在当前Servlet中先通过setAttribute()方法设置相应的属性,然后使用forward()方法进行跳转,最后在跳转到的Servlet中通过使用getAttribute()方法即可实现信息传递。
4.pageContext作用域
page对象的作用范围仅限于用户请求的当前页面,对于page对象的引用将在响应返回给客户端之后被释放,或者在请求被转发到其他地方后被释放。page里的变量只要页面跳转了,它们就销毁了。如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
当前页面中将数据存放到四大作用域,并且获取作用域中的数据:
代码示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 作用范围是当前页面,如果切换或者是跳转到另一个页面,作用域中等待数据就会销毁 --%>
<%-- request作用域, 作用范围是一次请求, 只有通过请求转发的方式实现跳转才可以获取到存放到该作用域中的数据 --%>
<%-- session 表示的是一次会话, 默认一次会话的生命周期是浏览器关闭,会话结束.
session 属于服务器会话对象, 实际获取不到数据是因为用来识别用户身份的 JSESSIONID 销毁了,
服务器上的session保存时间默认30分钟 --%>
<%-- 应用程序作用域对象 application -> ServletContext 该作用域的作用范围是,
应用的生命周期,服务器关闭,作用域中等待数据销毁 ,整个应用程序运行的生命周期 --%>
<%
pageContext.setAttribute("page", "页面作用域对象!!");
request.setAttribute("request","request作用域");
session.setAttribute("session","session作用域对象");
application.setAttribute("application","应用程序作用域对象");
%>
<p>
page 作用域: <%=pageContext.getAttribute("page")%>
</p>
<p>
request作用域: <%=request.getAttribute("request")%>
</p>
<p>
session作用域: <%=session.getAttribute("session")%>
</p>
<p>
application 作用域: <%=application.getAttribute("application")%>
</p>
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mxzbaDJV-1651660782267)(img/image-20210917102820030.png)]
根据演示效果可知,不进行页面跳转时,四大作用域中的值都可以获取.
在one.jsp 页面末尾添加请求转发到的跳转. 跳转到two.jsp 页面,代码如下.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J8ItjMgq-1651660782268)(img/image-20210917103034820.png)]
two.jsp 代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>
page 作用域: <%=pageContext.getAttribute("page")%>
</p>
<p>
request作用域: <%=request.getAttribute("request")%>
</p>
<p>
session作用域: <%=session.getAttribute("session")%>
</p>
<p>
application 作用域: <%=application.getAttribute("application")%>
</p>
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Li7vnDVK-1651660782268)(img/image-20210917103150679.png)]
根据演示效果,可知, page作用域中的数据获取不到了,原因是page作用域中的数据只能在当前页面获取; request作用域中数据可以获取是因为请求转发的跳转属于同一个请求,所有可以获取, session属于一个会话,只要不关闭浏览器或者是切换浏览器默认都可以获取. application是整个应用生命周期.
将one.jsp 中的请求换发改成重定向,如下图:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 作用范围是当前页面,如果切换或者是跳转到另一个页面,作用域中等待数据就会销毁 --%>
<%-- request作用域, 作用范围是一次请求, 只有通过请求转发的方式实现跳转才可以获取到存放到该作用域中的数据 --%>
<%-- session 表示的是一次会话, 默认一次会话的生命周期是浏览器关闭,会话结束.
session 属于服务器会话对象, 实际获取不到数据是因为用来识别用户身份的 JSESSIONID 销毁了,
服务器上的session保存时间默认30分钟 --%>
<%-- 应用程序作用域对象 application -> ServletContext 该作用域的作用范围是,
应用的生命周期,服务器关闭,作用域中等待数据销毁 ,整个应用程序运行的生命周期 --%>
<%
pageContext.setAttribute("page", "页面作用域对象!!");
request.setAttribute("request","request作用域");
session.setAttribute("session","session作用域对象");
application.setAttribute("application","应用程序作用域对象");
%>
<p>
page 作用域: <%=pageContext.getAttribute("page")%>
</p>
<p>
request作用域: <%=request.getAttribute("request")%>
</p>
<p>
session作用域: <%=session.getAttribute("session")%>
</p>
<p>
application 作用域: <%=application.getAttribute("application")%>
</p>
<%-- 请求转发实现页面的跳转--%>
<%
// request.getRequestDispatcher("two.jsp").forward(request,response);
response.sendRedirect("two.jsp");
%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: dzm
Date: 2021-09-17
Time: 10:20
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>
<p>
page 作用域: <%=pageContext.getAttribute("page")%>
</p>
<p>
request作用域: <%=request.getAttribute("request")%>
</p>
<p>
session作用域: <%=session.getAttribute("session")%>
</p>
<p>
application 作用域: <%=application.getAttribute("application")%>
</p>
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dkRPkKuJ-1651660782269)(img/image-20210917103638561.png)]
根据演示效果,request 作用域中的数据也获取不到了,原因是重定向不属于一次请求,所以无法获取到request中的数据.但是不管怎么跳转都是一次会话,只要不关闭浏览器或者切换浏览器去访问,都属于一次会话.
切换浏览器或者关闭浏览器重新访问two.jsp,效果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UXsm165-1651660782270)(img/image-20210917103919403.png)]
根据效果,切换浏览器或者关闭浏览器重新访问会重新开启一个会话,会话中的数消失.
关闭或者重启服务前期,application的数据也会消失.
作用域大小排序:
从小到大: pageContext<request<session<application
九、EL表达式
https://baike.so.com/doc/6751385-6965950.html
① 简介
EL(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。
作用: 简化jsp,用来替代jsp中的java代码,使得jsp看起来更加美观和简洁.
el 表达式主要从四大作用域中来获取数据.
② 作用
是一种在JSP页面获取数据的简单方式(只能获取数据,不能设置数据)通过以下方式:
在JSP页面的任何静态部分均可通过:${expression}来获取到指定表达式的值
包含以下几种方式:
${绑定名} 获取javaBean对象或者其他类型数据
${绑定名.属性名} 获取javaBean中对应的属性名
${绑定名[索引值]} 获取集合或者数组中对应的值
${绑定名["key"]} 通过key的值获取在Map中对应的value值
同样也可以在el表达式内部做一些简单的运算:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GwQWYp6J-1651660782271)(img/wps1-16317092576851.jpg)]
代码示例:
<%--
Created by IntelliJ IDEA.
User: dzm
Date: 2021-09-17
Time: 10:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el表达式的运算</title>
</head>
<body>
<h3>算数运算</h3>
+ ${10 + 20} - ${30-10} % ${23%3}
<h3>逻辑运算</h3>
&& ${10 > 2 && 20 > 3} || ${10 < 3 || 10 > 6}
<h3>比较运算</h3>
== ${10 == 5}
<%
pageContext.setAttribute("money", 1000);
%>
${money > 100}
${money != 0}
${money >= 10000}
<%-- el如果获取的值为null 就不显示--%>
${abc}
<h3>空值判断</h3>
${demo != null} false
${empty money} false
10 30 5 <br>
${10> 30 ? (10 > 5 ? 10 : 5) : (30 > 5 ? 30 : 5)}
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofOFrnwL-1651660782271)(img/image-20210917111201846.png)]
③ 原理
依次从四大作用域对象检索对应的绑定名,如果在某一个对象中获取到了,则不再去其他对象检索,否则继续检索,如果都没有查找到则返回的是一个空字符串,而不是null
如果如下操作时:以表达式${user.name}为例
EL表达式会根据name去User类里寻找这个name的get方法,此时会自动把name首字母大写并加上get前缀,一旦找到与之匹配的方法,El表达式就会认为这就是要访问的属性,并返回属性的值。
所以,想要通过EL表达式获取对象属性的值,那么这个属性就必须有与之对应的get方法。
可以通过指定检索四大作用域对象来提升检索速度,如下:
application-->applicationScope
session-->sessionScope
request-->requestScope
pageContext-->pageScope
比如:
${requestScope.user} 表示直接去request对象中获取user绑定名对应的值
④ 案例
分别获取javaBean,javaBean属性,Map值,List,数组类型的值
代码示例:
<%@ page import="com.ujiuye.bean.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>作用域中获取数据</title>
</head>
<body>
<h3>简单类型数据获取</h3>
<% pageContext.setAttribute("name", "demo");
%>
${name}
<h3>javabean 中的数据</h3>
<%
pageContext.setAttribute("us", new User("张三","16723456"));
%>
${us}
${us.username}
${us.getPassword()} | ${us.password}
<h3>数组或者List集合</h3>
<%
String[] arr = {"送悟空","猪八戒","乔丹","宝强"};
pageContext.setAttribute("demo", arr);
%>
<p>
${demo}
${demo[0]}
${demo[1]}
${demo[2]}
${demo[3]}
</p>
<hr>
<%
List<User> uList = new ArrayList<>();
uList.add(new User("翠花","12345"));
uList.add(new User("芙蓉","345675"));
uList.add(new User("西施","9999"));
uList.add(new User("貂蝉","12345"));
pageContext.setAttribute("list", uList);
%>
${list}
<p> ${list.get(0).username} ${list[0].password}</p>
<p> ${list[1].username} ${list[1].password}</p>
<p> ${list[2].username} ${list[2].password}</p>
<p> ${list[3].username} ${list[3].password}</p>
<h3>map集合中的数据</h3>
<%
Map<String,String> map = new HashMap<>();
map.put("key1","西孟庆");
map.put("key2","冠希");
map.put("key3","蒋劲夫");
map.put("key4","吴签");
pageContext.setAttribute("map", map);
%>
${map}
${map['key1']}
${map.key2}
${map.key3}
${map.key4}
</body>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FLEDmD7F-1651660782272)(img/image-20210917113413657.png)]
四大作用域中存放数据相同取值实例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>四大作用域中默认取值顺序</title>
</head>
<body>
<%
pageContext.setAttribute("demo", "页面作用域对象!!");
request.setAttribute("name","request作用域");
session.setAttribute("name","session作用域对象");
application.setAttribute("name","应用程序作用域对象");
%>
<%-- 如果作用域中存放数据的名称相同,默认的取值顺序是按照作用域范围从小到大来搜索 --%>
${name}
从pageContext作用域中取值: ${pageScope.demo} <br>
从request作用域中取值: ${requestScope.name} <br>
从session作用域中取值: ${sessionScope.name} <br>
application: ${applicationScope.name} <br>
</body>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LsTNrsYC-1651660782273)(img/image-20210917141907616.png)]
如果作用域中存放数据的名称相同,默认的取值顺序是按照作用域范围从小到大来搜索,搜索到就直接显示,不再先后继续搜索,如果需要限定从每个作用域中取值可以通过指定作用域的名字,如上实例.
十、JSTL标签库
菜鸟教程https://www.runoob.com/jsp/jsp-jstl.html
① 简介
JSTL(JavaServer Pages Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库。它主要提供给JavaWeb开发人员一个标准通用的标签,开发人员可以利用这些标签取代JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。
需要注意的是:jstl中需要获取值的地方一般都要配合EL表达式去使用
② 使用
1) 导入
jstl.jar standard.jar 两个包
2) 引入
将标签库引入 页面中
<%-- 引入标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3) 常用标签
1.<%--声明变量标签--%>
<c:set var="name" value="柳岩"></c:set>
var:声明的变量名
value:变量的值
2.<%--输出标签--%>
<c:out value="${name}" ></c:out>
value:要输出的变量的值,需要通过el表达式获取
3.<%--删除声明变量--%>
<c:remove var="name"></c:remove>
var:删除要删除的变量的名字
4.<%--if单分支标签--%>
<c:if test="${empty name}">测试if分支标签1</c:if>
test:当值为true的时候显示标签内部的值,否则不显示
5.<%--choose多分支标签--%>
<c:choose>
<c:when test="${1>2}">第一个条件的标签内容</c:when>
<c:when test="${3>2}">第二个条件的标签内容</c:when>
<c:otherwise>以上条件都不满足的标签内容</c:otherwise>
</c:choose>
当when标签的test的值为true的时候,显示标签内容,否则不显示,当多个when标签都为true的时候,值显示第一个为true的when标签内容,如果以上when标签都为false则显示otherwise的标签内容
注意:
when标签出现至少一个
otherwise标签最多出现一个
6.<%--集合或者数组的遍历标签--%>
<c:forEach items="" var="" >
</c:forEach>
items:要遍历的集合或者数组对象,需要通过el表达式获取
var:循环变量,可以理解为集合或者数组中的每一个值或者对象,名称自定义
核心标签代码示例:
<%@ page import="com.ujiuye.bean.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>jstl 使用实例</title>
</head>
<body>
<%-- jstl 将数据存放到session作用域中
var 变量的名字
value是作用域中数据的值
scope : 作用域名称 如page(默认) request session application
--%>
<c:set var="demo" value="123456" scope="session"></c:set>
<%-- 用来输出作用域中存放的数据 value的属性的值为 存放到作用域中数据的名字--%>
<c:out value="${demo}"></c:out> ${demo}
<%-- 可以通过value直接输出内容 --%>
<c:out value="输出内容"></c:out>
<%-- remove 用来移除作用域中的数据
var 作用域中变量名, scope 作用域名称
--%>
<c:remove var="demo" scope="session"></c:remove>
${demo}
<hr>
<%-- if 标签可以进行判断 --%>
<c:set var="money" value="10000"></c:set>
<%-- 如果属性test的值范围为true ,则会输出标签中的内容,如果为false 标签中的内容就不会被执行 --%>
<c:if test="${money > 1000}">
你好有钱!!
</c:if>
<c:if test="${money <= 1000}">
穷的吃土!!
</c:if>
<hr>
<%--多重选择结构 choose -> when -> otherwise--%>
<c:set var="score" value="77"></c:set>
<c:choose>
<%-- 如果test属性的值为true,则输出标签中的内容,只要qianmiad有一个满足,就不会在继续向后之后,
如果前面条件都返回false, 则会执行otherwise 标签中的内容 --%>
<c:when test="${score >= 90}">你很优秀</c:when>
<c:when test="${score >= 80}">很好继续加油</c:when>
<c:when test="${score >= 60}">你的努力努力</c:when>
<c:otherwise>不行啊!!</c:otherwise>
</c:choose>
<hr>
<h3>迭代器foreach</h3>
<%
List<User> uList = new ArrayList<>();
uList.add(new User("翠花","12345"));
uList.add(new User("芙蓉","345675"));
uList.add(new User("西施","9999"));
uList.add(new User("貂蝉","12345"));
uList.add(new User("吕布","12345"));
uList.add(new User("董卓","12345"));
uList.add(new User("曹贼","12345"));
uList.add(new User("奸贼","12345"));
pageContext.setAttribute("list", uList);
%>
<%--
items 用来设置需要需要遍历的集合,主要需要使用el接收集合中的数据
var 迭代出来的每个对象
step 每次迭代所有的增量,默认是加1
begin 遍历时索引的起始位置
end 遍历时索引的结束位置
varStatus 遍历出变量的状态 ,结合 index 可以获取遍历的对象的索引,结合count 可以统计遍历出对象的个数
--%>
<c:forEach items="${list}" var="use" step="2" begin="1" varStatus="stat" end="5">
<p>${stat.index} ${stat.count} ${use} ${use.username} ${use.password}</p>
</c:forEach>
<c:forEach var="num" end="10" begin="0">
${num}
</c:forEach>
</html>
演示效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2HzqSZGD-1651660782273)(img/image-20210917152831320.png)]
格式化和函数标签库的使用:
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fun" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:set var="date" value="<%=new Date()%>"></c:set>
${date}
<hr>
<fmt:formatDate value="${date}" pattern="yyyy-MM-dd hh:mm:ss"></fmt:formatDate>
<c:set var="glod" value="12.5363733"></c:set>
<%-- 数字格式化 --%>
<fmt:formatNumber value="${glod}" pattern="000.0000" ></fmt:formatNumber>
<fmt:formatNumber value="${glod}" pattern="####.###" ></fmt:formatNumber>
<c:set value="曾经有一段真挚的感情,来到我面前,我抓住了,如果上天在给我一次机会,我会说,滚犊子!!" var="desc"></c:set>
<br>
<c:out value="${fun:length('曾经有一段真挚的感情,来到我面前,我抓住了')}"></c:out> <br>
<c:out value="${fun:substring(desc, 0, 21)}"></c:out>...
<br>
<c:if test="${fun:contains(desc, '感情')}">感情好</c:if>
<c:if test="${fun:contains(desc, 'aa')}">不好</c:if>
</body>
</html>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0NheC4fm-1651660782274)(img/image-20210917160053788.png)]
项目分层结构:
持久层 dao 负责直接和数据库打交道,负责数据的增删改查
业务逻辑层 service 属于中间衔接 持久层和 界面层的中间层,用来处理相互之间的调用关系和逻辑处理,以及数据传递.
界面(视图) 层 直接和用户打交道,用来呈现内容给用户.
好处: 低耦合高内聚.
MVC 架构:
M 是Model 的缩写,称为模型层,主要用于数据的封装. 对应javabean , 通常在 entity / pojo / bean
V 是View 的缩写,是视图层,对应jsp,前端内容,直接呈现给用户的界面.
C 是Controller 的缩写,是控制层,主要用于控制视图中数据的获取, 业务逻辑层方法的调用以及页面的跳转.
在项目中使用包名来体现分层结构:
包名规范:
com.ujiuye.controller 控制层对应包名
com.ujiuye.service 业务逻辑层
com.ujiuye.dao 数据交互层
com.ujiuye.bean/entity/model 模型层
com.ujiuye.util 各种工具
项目结构如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jjDMUWgr-1651660782275)(img/image-20210917162420204.png)]
用户登陆
分析:
- 前端页面用户输入用户名和密码,提交给控制层
- 控制层获取用户提交的数据, 交给业务逻辑层处理,返回查询到的User对象,进行页面跳转
- 业务逻辑层获取控制层传递的数据,根据用户名和密码查询用户信息
- 数据交互层查询并返回用户信息
前端页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<p>${mes}</p>
<form action="user" method="get">
<input type="hidden" name="method" value="login">
姓名: <input type="text" name="username"> <br>
密码: <input type="password" name="pwd"> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
控制层:
package com.ujiuye.controller;
import com.ujiuye.bean.User;
import com.ujiuye.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;
import java.util.List;
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取前端传递的数据
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
// 将获取的数据交给业务逻辑层处理
UserService us = new UserService();
// 调用方法获取结果
User user = us.getUserByNameAndPassword(username,pwd);
// 控制页面的跳转
if(user != null){// 表示的登陆成功
resp.sendRedirect("show?method=show");
}else{ // 登陆失败
req.setAttribute("mes", "用户名或者密码错误");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
}
业务逻辑层:
package com.ujiuye.service;
import com.ujiuye.bean.User;
import com.ujiuye.dao.UserDao;
import java.util.List;
/**
* 业务逻辑层
*/
public class UserService {
/**
* 根据用户名和密码查询用户信息
* @param username
* @param pwd
* @return
*/
public User getUserByNameAndPassword(String username, String pwd) {
if(username != null && username.trim() != "" && pwd != null && pwd.trim() != ""){
UserDao ud = new UserDao();
return ud.getUserByNameAndPassword(username,pwd);
}
return null;
}
}
数据交互层
package com.ujiuye.dao;
import com.ujiuye.bean.User;
import com.ujiuye.util.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;
public class UserDao {
// 创建数据库操作对象,并传递数据源
private QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
/**
* 完成数据的查询
* @param username
* @param pwd
* @return
*/
public User getUserByNameAndPassword(String username, String pwd) {
String sql = "select * from user where username = ? and password = ? ";
User user = null;
try {
user = queryRunner.query(sql, new BeanHandler<>(User.class), username, pwd);
} catch (SQLException throwables) {
throw new RuntimeException(throwables.getMessage());
}
return user;
}
}
显示用户信息
控制层代码:
package com.ujiuye.controller;
import com.ujiuye.bean.User;
import com.ujiuye.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;
import java.util.List;
@WebServlet("/show")
public class ShowServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取所有用户信息,传递给show.jsp 页面
UserService userService = new UserService();
List<User> userList = userService.selectAllUser();
// 页面跳转, 选择作用域对象时考虑因素 1. 是否可以获取的到数据 2.内存的利用率
req.setAttribute("ulist",userList);
req.getRequestDispatcher("show.jsp").forward(req,resp);
}
}
业务逻辑层:
/**
* 获取所有用户信息
* @return 用户信息列表
*/
public List<User> selectAllUser() {
UserDao ud = new UserDao();
return ud.selectAllUser();
}
数据交互层:
public List<User> selectAllUser() {
String sql = "select * from user";
List<User> uli = null;
try {
uli = queryRunner.query(sql, new BeanListHandler<>(User.class));
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return uli;
}
前端页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table border="1" cellspacing="0" width="600px" align="center">
<tr>
<th>编号</th>
<th>用户名</th>
<th>密码</th>
<th>姓名</th>
<th>电话</th>
<th>生日</th>
<th>操作</th>
</tr>
<c:forEach items="${ulist}" var="user">
<tr>
<td>${user.uid}</td>
<td>${user.username}</td>
<td>${user.password}</td>
<td>${user.name}</td>
<td>${user.telephone}</td>
<td>${user.birthday}</td>
<td><a href="user?uid=${user.uid}">删除</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
控制层整合代码示例:
package com.ujiuye.controller;
import com.ujiuye.bean.User;
import com.ujiuye.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;
import java.util.List;
@WebServlet({"/user","/show"})
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
String uri = req.getRequestURI();
System.out.println("uri = " + uri);
switch (method){
case "login": login(req,resp); break; // 用户登陆
case "show": show(req,resp); break; // 用户登陆
}
// if(uri.contains("/usermanager_war_exploded/user")){
// login(req,resp); // 用户登陆
// }else if(uri.contains("/usermanager_war_exploded/show")){
// show(req,resp);
// }
}
private void show(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("show");
// 获取所有用户信息,传递给show.jsp 页面
UserService userService = new UserService();
List<User> userList = userService.selectAllUser();
// 页面跳转, 选择作用域对象时考虑因素 1. 是否可以获取的到数据 2.内存的利用率
req.setAttribute("ulist",userList);
req.getRequestDispatcher("show.jsp").forward(req,resp);
}
private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
// 获取前端传递的数据
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
// 将获取的数据交给业务逻辑层处理
UserService us = new UserService();
// 调用方法获取结果
User user = us.getUserByNameAndPassword(username,pwd);
// 控制页面的跳转
if(user != null){// 表示的登陆成功
resp.sendRedirect("show?method=show");
}else{ // 登陆失败
req.setAttribute("mes", "用户名或者密码错误");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
}
hod");
String uri = req.getRequestURI();
System.out.println("uri = " + uri);
switch (method){
case “login”: login(req,resp); break; // 用户登陆
case “show”: show(req,resp); break; // 用户登陆
}
// if(uri.contains(“/usermanager_war_exploded/user”)){
// login(req,resp); // 用户登陆
// }else if(uri.contains(“/usermanager_war_exploded/show”)){
// show(req,resp);
// }
}
private void show(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("show");
// 获取所有用户信息,传递给show.jsp 页面
UserService userService = new UserService();
List<User> userList = userService.selectAllUser();
// 页面跳转, 选择作用域对象时考虑因素 1. 是否可以获取的到数据 2.内存的利用率
req.setAttribute("ulist",userList);
req.getRequestDispatcher("show.jsp").forward(req,resp);
}
private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
// 获取前端传递的数据
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
// 将获取的数据交给业务逻辑层处理
UserService us = new UserService();
// 调用方法获取结果
User user = us.getUserByNameAndPassword(username,pwd);
// 控制页面的跳转
if(user != null){// 表示的登陆成功
resp.sendRedirect("show?method=show");
}else{ // 登陆失败
req.setAttribute("mes", "用户名或者密码错误");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
}