JSP核心技术
JSP的概述(熟悉)-------------------------
JSP的概念:
JSP是Java Server Pages的简称,跟Servlet一样可以动态生成HTML响应, JSP文件命名为xxx.jsp
与Servlet不同,JSP文件以HTML标记为主,然后内嵌Java代码段,用于处理动态内容
JSP的示例:
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello Time</title>
</head>
<body>
现在的时间是:<%= new Date()%>
</body>
</html>
JSP与Servlet的关系:
![在这里插入图片描述](https://img-blog.csdnimg.cn/e7a4cb567a76483388287fdddbeeac02.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
本来由于Servlet要有界面到网页时,只能通过IO流(如打印流PrintWriter)
虽然有个文档,类似于网络编程的那个文档,但是是空的,这时,若要有大量的界面,那么就要输出大量的字符串
IO流需要对应的标签,用字符串包括,非常的麻烦
于是就有了Jsp,每一个JSP页面都会被Web容器编译成一个Java类,供web容器调用,并且生成HTML页面回馈给用户
然后编译成.classjsp = java + html
servlet = java + out.print(html),IO流中放html
JSP是Servlet技术的扩展,本质上就是Servlet的简易方式,JSP编译后是"类servlet"
具体过程如下:
客户端发送请求给web容器
web容器将jsp首先转译成servlet源代码,他的内容html就放在IO流中(这里直接帮我们写了html代码)
否则平常的话,我们写Servlet还需要输出大量的html代码
html中间有我们的java代码操作,如表达式的代码直接进行连接
而全局的则在对应Servlet方法外,局部的在对应Servlet方法内,表达式的代码直接连接html,即IO流的输出
有多个输出,且局部的会有位置顺序,只所以可以这样
是因为Jsp中的java代码段由不同的符号包括,在转译时
就会判断,然后服务器就自动根据出现的不同结果来生成Servlet的一系列代码
可以看一下转译的部分源代码:
![在这里插入图片描述](https://img-blog.csdnimg.cn/358e6959101743d4a4ed25ea33ea6cbd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到全局的在类里面
对应方法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/85836761f0d249bab1a97d3f4a7de855.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/f6393d8096f94de08fb12b3d6ecbe4ae.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到局部在有顺序的放入,在方法里面
![在这里插入图片描述](https://img-blog.csdnimg.cn/2d2fc6a7368f442da850e333701b11a2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到在IO的输出流里面直接连接输出,最后将对应文档显示在客户端,如浏览器
下面的就是平常Servlet操作了
web容器将servlet源代码编译成.class 文件
web容器执行.class 文件
web容器将结果响应给客户端(文档中IO流输出的结果),因为读取文档
![在这里插入图片描述](https://img-blog.csdnimg.cn/faa09e703c9a423d9a570d8cb720f511.png#pic_center)
由着可以得出,tomcat需要jdk的运行环境,即必须要jre,jdk的其他东西可以不要
实际上无论还是什么操作,如反射,都是class在运行的,我们java都是编译过去
且可以看出Jsp与Html底层有很大的不同,html是不用编译直接执行的,jsp需要转译和编译
java,jsp:需要编译运行
mysql,html,css,js:都直接运行,基本一行一行读取,从上到下
JSP的语法(熟悉):
注意:Jsp与Java一样需要重新部署才可,因为是先放到服务器内存中的,与html不一样,html是放在服务器文件等待读取的
JSP语法结构:
声明区,程序,代码区,表达式,注释,指令和动作,内置对象
声明区:
基本语法:
当Jsp是要读取的文件时,下面的符号,Servlet可以判断,并做出对应转化执行(html可能不会)
<%! %>说明:
可以定义全局变量、方法、类
<%!
int i;
public void setName(){… …}
%>
程序代码区:
基本语法:
<%程序代码区%>
说明:可以定义局部变量以及放入任何的Java程序代码
<%
int j;
for (int k=0; k<10; k++) { … … }
%>
表达式:
基本语法:
<%=… …%>
说明:可以输出一个变量或一个具体内容,但=后面必须是字符串变量或者可以被转换成字符串的表达式
注意:不需要以" ; " 结束,只有一行
<%=
"hello world"
%>
<%=
i+1
%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试变量的声明和打印</title>
<%!
int ia; // 这是一个全局变量
//类方法
public void show() {
System.out.println("这是全局方法!");
}
//内部类
public class MyClass {
{
System.out.println("这是一个全局类哦!");
}
}
%>
<%
//相当于在main方法里
int ib = 20; // 这是一个局部变量
for (int i = 0; i < 3; i++) {
System.out.println("随便放入Java程序代码吧!");
}
%>
</head>
<body>
<!-- 相当于直接计算 -->
<%= ia+1 %> <%-- 1 --%>
<%= ib %> <%-- 20 --%>
<%= "我就暂时写到这里吧!"%> <%-- 我就暂时写到这里吧!,这里是jsp注释的方法,底层不识别--%>
</body>
</html>
注意:在转译时,是不会判断是否错误的,即先全部按照规则变成java,即可以分开写,如
<%! public void f(){
%>
<%!
}
%>
<!--或者-->
<%
int a=%><%3;%>
<!--上面可以这样写的-->
<!--那是因为java可以这样
public void f(){
//其他操作
} 隔开
int a= 3 隔开,但java代码块之间不可换行
换行的话会被 out.write占据,使得报错,因为我们是要变成java代码
所以java代码要识别这个换行
-->
<!--下面不可以,因为只算作一行-->
<%=
6+
%>
<%=
4
%>
<!--那是因为这里直接当作括号了,即(6+),和(4)-->
上述结果的出现,主要是位置问题,在类里面,没有使用out.write方法,在方法里有使用out.write方法
又因为Jsp的每个java代码块之间的换行都会被这个使用
使得有些不可操作,如赋值时,中间不可有该方法,但其他合理的可以有,如循环时可以有
简单来说:将Jsp的所有内容,进行转译表示成java代码后(java代码块里是java操作)
再编译,即这个编译需要识别java里的错误的,即需要合理的位置
最终java的执行,使得out.write方法对页面的渲染操作,看如下案例题目对这的具体操作
案例题目:
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>实现表格的绘制</title>
</head>
<body>
<table>
<tr>
<td>id</td>
<td>name</td>
<td>age</td>
<td>salary</td>
</tr>
<%
for (int i = 1; i < 6; i++) {
%>
<tr>
<td> <%= i %> </td>
<td> <%= i %> </td>
<td> <%= i %> </td>
<td> <%= i %> </td>
</tr>
<%
}
%>
</table>
</body>
</html>
源代码循环如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/e123d6a4f88b4657bbc8a842052f3c32.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
输出了多次,即文档内容又多了起来
注释:
格式:
<!--… …--> HTML文件的注释,浏览器可以查看到,到java代码里面的out.write方法里面可以看到
<%--… …--%> JSP文件的注释,浏览器看不到,到java代码里面不可以看到
<%//… …%> Java语言中的单行注释,浏览器看不到,到java代码里面可以看到
<%/*… …*/%> Java语言中的多行注释,浏览器看不到注释的内容不会被执行,到java代码里面可以看到
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注释的测试</title>
</head>
<body>
<!-- 这是HTML文件中的注释方式,浏览器是可以看到的 -->
<%-- 这是JSP文件中的注释方式,该方式浏览器是看不到的 --%>
<%
// Java语言中的单行注释 浏览器看不到哦
/* Java语言中的多行注释 浏览器看不到哦! */
%>
</body>
</html>
指令和动作:
指令格式:
<%@指令 属性=“属性值”%>
指令的属性可以设定多个
JSP常用指令有:page、taglib、include
page指令:
page指令用于导包和设置一些页面属性,常用属性如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/8628094e72d246e1af2fda0e287a387e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
编码中间可以操作,最后解码交给显示,上面导入包的Jsp格式会被转译为java的导包
上面的其他转译,一般都是会到Java代码中显示,有些没有,这是转译的底层操作
注意:上面的pageEncoding就是字面的意思,在java中,改变他保存就是当前页面内容的编码格式,可以参照idea右下角的显示,可以发现发生了改变(可能不同的idea有所不同,即并不保证是这样的)
<%@ page import="java.util.List" %>
<%@ page import="java.util.LinkedList" %>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<html>
<head>
<title>page指令的使用</title>
</head>
<body>
<%
List<String> list = new LinkedList<String>();
%>
</body>
</html>
taglib指令:
taglib指令用来扩展JSP程序的标签元素,引入其他功能的标签库文件:
<%@taglib uri="tagLibary" prefix="prefix"%>
include指令:
include指令用于引入另一个JSP程序或HTML文件等,格式如下:
<%@include file="被包含的文件地址"%>
注意:Jsp的转译也是一行一行的,即只要符合就可以识别,且也是从上往下的的放入具体位置
JSP引擎会在JSP文件的转换时期先把file属性设定的文件包含进来,然后开始执行转换及编译的工作
jsp:include/jsp:param:
jsp:include动作用于引入另一个JSP程序或HTML文件等
执行到include时,被include的文件才会被编译
如果include的是jsp文件,那它不会被转换成Servlet文件
<jsp:include page="URLSpec" flush="true"/>
<jsp:include page="URLSpec" flush="true">
<jsp:param name="key" value="value"/>
</jsp:include>
include指令和include动作的区别:
include指令是在JSP程序的转换时期就将file属性所指定的程序内容嵌入再编译执行(静态包含)
include动作在转换时期是不会被编译的,只有在客户端请求时期被执行到才会被动态的编译载入(动态包含,推荐)
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 表示包含或引入head.jsp文件 include指令的方式 静态包含
先包含,然后转译,再编译,运行,只有一个class,其中资源不可改变了,因为包含了--%>
<%--<%@ include file="head.jsp"%>--%>
<%-- include动作的方式 动态包含 推荐
一起转译,在编译,运行时有两个class,类似于java导入类,使用了类的信息,即class运行时操作,动态的改变--%>
<jsp:include page="head.jsp"></jsp:include>
<html>
<head>
<title>文件引入的使用</title>
</head>
<body>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>被引入的通用文件</title>
</head>
<body>
所有页面的公共头部部分就可以写在这里,然后让所有页面包含或引入该文件即可
</body>
</html>
jsp:forward/jsp:param:
forward动作用于在JSP中实现转发,将请求转发到另一个指定的JSP程序或者Servlet中处理:
<jsp:forward page="urlSpec" flush="true"/>
<jsp:forward page="urlSpec">
<jsp:param name="key" value="value"/>
</jsp:forward>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP页面的转发实现</title>
</head>
<body>
<jsp:forward page="target.jsp">
<jsp:param name="name" value="zhangfei"/>
</jsp:forward>
<%-- 设置属性,即给请求信息添加属性,保存在request里面--%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>转发的目标文件</title>
</head>
<body>
<h1>服务器转发后执行这里的代码哦!</h1>
<%= "获取到的数值为:" + request.getParameter("name")%><br/>
<%--实际上由于有两个class,即两个servlet,即转发时
可以得到request的值,由于共享,即扩展,所以也可以得到对应name的值 --%>
</body>
</html>
JSP内置对象(重点):
基本概念:
在JSP程序中有9个内置对象由容器为用户进行实例化,程序员可以不用定义就直接使用这些变量
在JSP转换成Servlet后,会自动追加这些变量的定义,使用内置对象可以简化JSP的开发
对象名称:
![在这里插入图片描述](https://img-blog.csdnimg.cn/0c76ac8cf9bc4802aa961c1149c658c4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
out内置对象:
out内置对象是一个缓冲的输出流,用来给客户端输出信息
常用方法如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/0f36d3a2135e417bb43668a7253dd9d7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>out内置对象的使用</title>
</head>
<body>
<%
out.println("<h1>");
out.println("Hello World!");
out.println("</h1>");
//out.close();
int bufferSize = out.getBufferSize();
System.out.println("缓冲区的总大小是:" + bufferSize);
int remaining = out.getRemaining();
System.out.println("缓冲区的剩余字节数为:" + remaining);
System.out.println("已经使用的字节数为:" + (bufferSize - remaining));
out.clear(); // 清除缓冲区 数据不会输出
remaining = out.getRemaining();
System.out.println("缓冲区的剩余字节数为:" + remaining);
%>
</body>
</html>
request内置对象:
request对象封装的是调用JSP页面的请求信息,它是HttpServletRequest接口的一个实例
该对象的属性值只在一个请求中保存
常用方法如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/530f045c52434b559bf979a8607a1a2a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>request内置对象的使用</title>
</head>
<body>
<%
String serverName = request.getServerName();
System.out.println("获取到的服务器名称为:" + serverName);
int serverPort = request.getServerPort();
System.out.println("获取到的服务器端口号为:" + serverPort);
request.setAttribute("name", "guanyu");
%>
<%-- 实现转发效果,也就是服务器跳转 --%>
<jsp:forward page="requestTarget.jsp"></jsp:forward>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取request对象中的属性值</title>
</head>
<body>
<%= "获取到的属性值为:" + request.getAttribute("name")%> <%-- guanyu --%>
</body>
</html>
response内置对象:
response对象用于给客户端相应输出处理结果,它是HttpServletResponse接口的一个实例
经常用于设置HTTP标题,添加cookie、设置响应内容的类型和状态、发送HTTP重定向和编码URL
常用方法如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/b7aa50d880974ec182c09ba065a65fbb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %><%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>response内置对象的使用</title>
</head>
<body>
<%
// 表示每隔1秒刷新一次
response.addHeader("refresh", "1");
//添加的信息根据对应名称操作,当然也可以随便写,只是浏览器不识别而已
//refresh 刷新的意思,每隔1秒刷新一次,浏览器会识别这个refresh属性,使得当前页面进行每隔一秒刷新操作
// 获取当前系统时间
Date d1 = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = sdf.format(d1);
%>
<%= "当前时间为:" + format %>
</body>
</html>
session内置对象:
session对象表示浏览器和服务器之间的一次会话,一次会话可以包含多次请求
在多次请求之间可以借助session对象存储信息,它是HttpSession类型的一个实例
该对象的属性值在一次会话范围中保存,保存在服务器端,只要不关闭服务器,默认半个小时内都可以访问,即30分钟
常用方法如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/e5ed100878ac410694d45ecfe921ddc9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>session内置对象的使用</title>
</head>
<body>
<%
session.setAttribute("name", "liubei");
System.out.println("session内置对象中的数据设置成功!");
%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取session内置对象中的数据</title>
</head>
<body>
<%= "获取到的属性值为:" + session.getAttribute("name")%>
</body>
</html>
application内置对象:
application对象是一个web程序的全局变量,它是ServletContext类型的一个实例
在整个服务器上保存数据,所有用户共享
常用方法如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/d3de0b3aded748489e691a4161a1fb3a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>application内置对象的使用</title>
</head>
<body>
<%
application.setAttribute("name", "zhaoyun");
System.out.println("application内置对象中的数据设置成功!");
%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>application内置对象的获取</title>
</head>
<body>
<%= "获取到的application内置对象的属性为:" + application.getAttribute("name")%> <%-- zhaoyun --%>
</body>
</html>
pageContext内置对象:
pageContext对象是PageContext类型的对象,可以使用这个对象来管理其他的隐含对象
只在一个页面中保存数据,即其他的请求就没有了
![在这里插入图片描述](https://img-blog.csdnimg.cn/dca5d72832d04a72994a1c5afca3e0bf.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>pageContext内置对象的使用</title>
</head>
<body>
<%
pageContext.setAttribute("name", "huangzhong");
System.out.println("pageContext内置对象中的数据设置成功!");
%>
<%= "获取到的pageContext内置对象中的属性值为:" + pageContext.getAttribute("name")%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>pageContext内置对象属性的获取</title>
</head>
<body>
<%= "获取到的pageContext内置对象中的属性值为:" + pageContext.getAttribute("name")%> <%-- null --%>
</body>
</html>
exception内置对象:
exception 对象是Throwable的实例,表示的是JSP的异常信息
如果要使用它,必须将对应页面page指令的isErrorPage属性设置成true
单个页面的处理方式
<%@page errorPage="error.jsp" %>
在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">
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
</web-app>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error.jsp" %><%--指定异常的页面,当发生错误时
将这个页面信息给文档,而不是将原来默认的信息给文档
若和配置文件一起,则因为就近原则,使用这个文件,导致不读取配置文件了,否则读取配置文件
--%>
<html>
<head>
<title>exception内置对象的使用</title>
</head>
<body>
<%
int ia = 10;
int ib = 0;
System.out.println(ia / ib); // 算术异常
%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>发生另外一种异常的页面</title>
</head>
<body>
<%
int[] arr = new int[5];
System.out.println(arr[5]); // 数组下标越界异常
%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %> <%--将这个页面设置为错误页面,别人发生错误时
<%@ page errorPage="error.jsp" %>使用这个指向
则会使用这个页面
若没有设置true,则下面的exception就会报错,不可使用
--%>
<html>
<head>
<title>异常处理的页面</title>
</head>
<body>
<%
if (exception != null) {
out.println("异常的错误信息为:" + exception.getMessage()); //异常信息
}
%>
</body>
</html>
JavaBean组件(熟悉)-----------------------------
基本概念:
JavaBean 是使用 Java 语言开发的一个可重用的组件,在 JSP 开发中可以使用 JavaBean 减少重复代码
使整个 JSP 代码的开发更加简洁
JavaBean本质上就是Java类,通常要求如下:
属性:全部私有化,通过get和set方法进行访问
方法:必须是public关键字修饰。
构造器 :必须有无参构造方法
package com.lagou.demo02;
public class Student {
private int id;
private String name;
public Student() {
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<%@ page import="com.lagou.demo02.Student" %><%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JavaBean组件的使用</title>
</head>
<body>
<%-- 表示创建Student类型的对象由student引用变量负责记录 有效范围是当前页面
相当于给你创建对象,不用自己创建对象了,即Student student = new Student();
所以Student这个变量就使用了,即不可再用Student这个变量了,否则报错
--%>
<jsp:useBean id="student" scope="page" class="com.lagou.demo02.Student"/>
<%-- 表示将student对象中名字为id的属性值设置为1002
--%>
<jsp:setProperty name="student" property="id" value="1002"/>
<%-- 表示将student对象中名字为name的属性值设置为guanyu--%>
<jsp:setProperty name="student" property="name" value="guanyu"/>
<%--
注意:id和name是student引用的属性值,即成员变量的名字,不可忽略大小写
使用上面相当于调用对应的setxxx,xxx是他们对应成员变量的首字母忽略大小写的名字
如setId,setid等等,setName,setname等等,实际上是成员变量对应set的首字母大小写忽略
--%>
<%
// 创建Student类型的对象并设置成员变量的数值
//Student student = new Student(); 上面若创建对象,则这个名字不可使用
//student.setId(1001);
//student.setName("zhangfei");
%>
<%--<%= "获取到的学号是:" + student.getId() %> <%– 1001 1002 –%>
<%= "获取到的姓名是:" + student.getName() %> <%– zhangfei guanyu –%>--%>
<%-- 表示获得student对象中名字为id的属性值
--%>
学号是:<jsp:getProperty name="student" property="id"/><br/>
<%-- 表示获得student对象中名字为name的属性值
--%>
姓名是:<jsp:getProperty name="student" property="name"/><br/><%--其中property的值也可以是class
获得对应Class对象,返回class com.lagou.demo02.Student
--%>
<%--
注意:id和name是student引用的属性值,即成员变量的名字,不可忽略大小写
获取对应值,getxxx,xxx首字母大小写忽略
实际上是成员变量对应get的首字母大小写忽略
如getId,getid,getName,getname等等
--%>
<%--上面无论是set还是get只对名称要求,内容不做要求,如getId一般内容是return id
但是可以改成return 4,不会报错
--%>
</body>
</html>
使用方式:
使用jsp:useBean的方式创建javaBean实例:
<jsp:useBean id=“对象名” scope=“保存范围 class=“包名.类名” />
保存范围有:page|request|sessin|application,默认为page范围
使用jsp:setProperty的方式设置javaBean的属性值:
<jsp:setProperty name="对象名" property="属性名" value="属性值" param="参数名"/>
<%--注意:value和param不能一起,否则报错--%>
使用jsp:getProperty的方式获取javaBean的属性值:
<jsp:getProperty name="对象名" property="属性名"/>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>实现向JavaBean组件传入参数的使用</title>
</head>
<body>
<form action="bean2.jsp" method="post">
学号:<input type="text" name="id1"/><br/>
姓名:<input type="text" name="name1"/><br/>
<input type="submit" value="向JavaBean组件传参"/>
</form>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>实现前端页面传入过来参数的接收和设置</title>
</head>
<body>
<jsp:useBean id="student" scope="session" class="com.lagou.demo02.Student"/>
<jsp:setProperty name="student" property="id" param="id1"/>
<jsp:setProperty name="student" property="name" param="name1" value="1" />
<%--
注意:param需要其他请求信息的数据,即其他页面传过来的参数,且不 能和value一起,否则报错
因为他们都是对数据进行操作的,底层只能操作一个,若有多个,则会报错的
且要注意空格要写,你写是去,会提示你的,若执意运行,则报错
--%>
</body>
</html>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>实现JavaBean组件中对象属性值的打印</title>
</head>
<body>
<jsp:useBean id="student" scope="session" class="com.lagou.demo02.Student"/>
<%-- 获取名字为student对象中属性为id的数值并打印 --%>
经过参数赋值后获取到的学号是:<jsp:getProperty name="student" property="id"/><br/>
经过参数赋值后获取到的姓名是:<jsp:getProperty name="student" property="name"/><br/>
<%--
对于jsp:useBean的底层,他是会先去调用对应的getAttribute("student"))方法,来获得Student对象
若没有,则创建该类型对象,然后设置进去,由于是地址,那么若有setProperty,则会设置值给这个对象
所以若需要里面的东西,就要取出来,则必须还要使用jsp:useBean方式
使得调用对应的getAttribute("student"))方法取出来
--%>
</body>
</html>
上面取Student对象和设置对象和获得对象的底层代码如下:
首先取出对应对象,没有再创建,相当于是将对象设置到范围的对象中去,这里是Session对象
![在这里插入图片描述](https://img-blog.csdnimg.cn/95846bc3082e458aa7ea4b8c469aee84.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
由于地址相同,然后设置值,那么地址的值发生改变,即设置了值,其中id1和name对应的方法是取请求信息的数据,然后设置
![在这里插入图片描述](https://img-blog.csdnimg.cn/e92758b04773404eb58ca3537123bfba.png#pic_center)
最后还要取,并调用对象的get方法来获得
![在这里插入图片描述](https://img-blog.csdnimg.cn/f7b37fc5ecbb4759a09d474dc31d52d6.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
这就是上面jsp:useBean的底层原理
在取的时候,后面有跟着范围,这个范围就是对应对象的范围,这里是Session对象
就是对Session对象的操作,即取出,设值,再取出,得值
就类似于session.setAttribute()和session.getAttribute(),他们都有一个类型来获得他们,就如上面的student
所以这就是为什么需要两个jsp:useBean的原因了
保存范围:
JavaBean的保存范围有page、request、session以及application,默认是page范围
删除方式:
<%
内置对象.removeAttribute("JavaBean的名字");
%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>实现JavaBean组件数据的删除</title>
</head>
<body>
<%
// 表示从session对象中删除名字为student的属性
session.removeAttribute("student");
%>
<%= "删除数据成功!" %>
</body>
</html>
MVC设计模式(重点)----------------------------
基本概念:
MVC是模型(Model)和视图(View)以及控制器(Controller)的简写
是一种将数据、界面显示和业务逻辑进行分离的组织方式,这样在改进界面及用户交互时,不需要重新编写业务逻辑
从而提高了代码的可维护性
M:主要用于封装业务数据的JavaBean(Bean) 和 业务逻辑的JavaBean(Service)及访问数据库的DAO对象
V:主要负责数据收集 和 数据展现,通常由JSP文件完成
C:主要负责流程控制 和 页面跳转,通常由Servlet完成
基本模型:
![在这里插入图片描述](https://img-blog.csdnimg.cn/97964b7f1fa04b8085bb88cd82c71623.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iuf5oiQ5aSn5L2s,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
服务器让请求到Servlet,然后转发给Jsp,然后Jsp自己创建Servlet,最后响应,第一次都是由服务器来交给的
即找到对应的文档(直接的访问)或本地资源(Jsp)
package com.lagou.demo03.bean;
public class User {
private int id;
private String userName;
private String password;
public User() {
}
public User(String userName, String password) {
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{" +
"userName='" + userName + '\'' +
", password='" + password + '\'' +
'}';
}
}
package com.lagou.demo03.dao;
import com.lagou.demo03.bean.User;
public interface UserDao {
public abstract User userLogin(User user);
}
package com.lagou.demo03.dao;
import com.lagou.demo03.bean.User;
import com.lagou.demo03.util.DbUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDaoImp implements UserDao {
@Override
public User userLogin(User user) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DbUtil.getConnection();
String sql = "select * from t_user where userName = ? and password = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, user.getUserName());
preparedStatement.setString(2, user.getPassword());
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
User tu = new User(resultSet.getString("userName"), resultSet.getString("password"));
return tu;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
DbUtil.closeResource(connection, preparedStatement);
if (null != resultSet) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
}
package com.lagou.demo03.service;
import com.lagou.demo03.bean.User;
import com.lagou.demo03.dao.UserDao;
import com.lagou.demo03.factory.UserDaoFactory;
public class UserService {
private UserDao userDao;
public UserService() {
this.userDao = UserDaoFactory.getUserDao();
}
public User userLoginService(User user) {
return userDao.userLogin(user);
}
}
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>实现简单的登录功能</title>
</head>
<body>
<form action="login" method="post">
用户名:<input type="text" name="userName"/><br/>
密 码:<input type="text" name="password"/><br/>
<span style="color: red">
<%= request.getAttribute("error")==null?"":request.getAttribute("error")%>
</span><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
package com.lagou.demo03.factory;
import com.lagou.demo03.bean.User;
import com.lagou.demo03.dao.UserDao;
import com.lagou.demo03.dao.UserDaoImp;
public class UserDaoFactory {
public static UserDao getUserDao() {
return new UserDaoImp();
}
}
package com.lagou.demo03.servlet;
import com.lagou.demo03.bean.User;
import com.lagou.demo03.service.UserService;
import javax.servlet.RequestDispatcher;
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(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
String userName = request.getParameter("userName");
System.out.println("获取到的用户名为:" + userName);
String password = request.getParameter("password");
System.out.println("获取到的密码为:" + password);
UserService userService = new UserService();
User user = userService.userLoginService(new User(userName, password));
if (null == user) {
System.out.println("登录失败,用户名或密码错误!");
request.setAttribute("error", "登录失败,用户名或密码错误!");
RequestDispatcher requestDispatcher = request.getRequestDispatcher("login.jsp");
requestDispatcher.forward(request, response);
} else {
System.out.println("登录成功,欢迎使用!");
request.getSession().setAttribute("user", user);
response.sendRedirect("main.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
this.doPost(request, response);
}
}
package com.lagou.demo03.test;
import com.lagou.demo03.bean.User;
import com.lagou.demo03.dao.UserDao;
import com.lagou.demo03.dao.UserDaoImp;
import com.lagou.demo03.service.UserService;
public class UserServiceTest {
public static void main(String[] args) {
UserDao userDao = new UserDaoImp();
UserService userService = new UserService();
User admin = userService.userLoginService(new User("admin", "1234566"));
System.out.println("找到的数据为:" + admin);
}
}
package com.lagou.demo03.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DbUtil {
private static String jdbcName;
private static String dbUrl;
private static String dbUserName;
private static String dbPassword;
static {
jdbcName = "com.mysql.jdbc.Driver";
dbUrl = "jdbc:mysql://localhost:3306/db_web";
dbUserName = "root";
dbPassword = "123456";
try {
Class.forName(jdbcName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
Connection con = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
return con;
}
public static void closeResource(Connection con, PreparedStatement psts) throws SQLException {
if (null != con) {
con.close();
}
if (null != psts) {
psts.close();
}
}
}
<%@ page import="com.lagou.demo03.bean.User" %><%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页面</title>
</head>
<body>
<h1>登录成功,欢迎<%= ((User)session.getAttribute("user")).getUserName() %>使用!</h1>
</body>
</html>
这个工程,说明了设计模式的重要性,使得程序之间维护的作用