javaweb
什么是javaweb?
所有通过Java语言编写可以通过浏览器访问的程序的总称,叫JavaWeb。是基于请求和响应来开发的。
请求和响应
web资源的分类
- 静态资源:html、css、js、txt、mp4视频,jpg图片
- 动态资源:jsp页面、Servlet程序
什么是C/S结构和B/S结构,各有什么优缺点
- C/S又称Client/Server或客户/服务器模式。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统。客户端需要安装专用的客户端软件。
- B/S是Brower/Server的缩写,客户机上只要安装一个浏览器(Browser),服务器安装数据库。浏览器通过Web Server 同数据库进行数据交互。
-
前端开发流程
-
网页的三大组成部分
- 内容(结构),是我们在页面中可以看到的数据。我们称之为内容。一般内容我们使用html技术来展示。
- 表现,指的是这些内容在页面上的展示形式。比如说。布局,颜色,大小等等。一般使用CSS技术实现
- 行为,指的是页面中元素与输入设备交互的响应。一般使用javascript技术实现
-
web静态工程创建html文件
html文件右键run即可
Tomcat
由Apache组织提供的一种Web服务器,提供对jsp和Servlet的支持。它是一种轻量级的javaWeb容器(服务器),也是当前应用最广的JavaWeb服务器(免费)。
tomcat安装与环境配置
节省时间,直接借别人的笔记了
创建一个javaweb项目并且添加tomcat配置
1.左上角新建项目,名字自定
2.右键选择添加框架支持,勾选Web应用程序-确定
3.建立成功页面,多了web文件夹
4.给项目添加tomcat
1.点击添加配置文件
2.点击这个+
3.选择这个tomcat的本地
注意:是Tomcat服务器,不是TomEE服务器
4.点击配置-----然后点击+号
如果是第一次配置的小伙伴可以看下面的这个额外步骤
额外步骤:如果是第一次配置的,会出现这个界面,然后在里面填入tomcat的文件夹位置就好
5.点击这个主目录的选择文件夹
6.选择自己tomcat的解压包位置---确定
注意:这个选择的包是bin包的上一级包那个才是
选择正确的界面
7.点击修复,idea会自动帮忙配置工件
8.在自动跳出来的页面点击应用--确定
9.点击这个运行按钮
10.跳出来这个界面就是部署安装成功(如果是404,那就是一些idea版本不带index.jsp或者没有这个文件,自己创建一个就可以了)
创建动态工程
web工程目录介绍
将创建的动态模块部署到tomcat中
尝试创建多个模块分别部署到tomcat以作区分
点击编辑配置
服务器的名称设置成与项目模块相关,更好识别
在部署中添加要运行的项目模块,应用程序上下文是项目运行路径
两个项目模块分别配置好之后就会有如上两个运行配置可供选择,切换运行之前,需要先停止上一次的运行。
给动态web工程添加额外jar包
2、添加你你类库需要的jar包文件。
3、选择你添加的类库,给哪个模块使用:
4、选择Artifacts选项,将类库,添加到打包部署中:
jar包需要外部下载引入
热部署
进行上面操作之后,页面只需要刷新即可得到修改之后的页面
xml详解
在生活中,我们经常会遇到一些存在关联的数据,又比如说在数据结构中的树结构,或者说中国有很多省份,每个省份又有很多城市,这些城市可以用一张树状图来表示,但是对于程序而言,解析树结构是非常困难的,这时采用XML文件保存这种具有树状结构的数据是最好的选择。
XML是Extensible Markup Language的缩写,是一种类似于HTML的标记语言,称为可标记扩展语言,而HTML称为超文本标记语言。而这里所谓的扩展,指的是用户可以按照XML规则自定义标记。
<?xml version="1.0" encoding="UTF-8"?>
<中国>
<浙江>
<城市>杭州</城市>
<城市>金华</城市>
</浙江>
<河南>
<城市>南阳</城市>
<城市>郑州</城市>
</河南>
</中国>
作用
- 用来保存数据,而且这些数据具有自我描述性
- 它还可以做为项目或者模块的配置文件
- 还可以做为网络传输数据的格式(现在JSON为主)
创建一个xml文件,用来描述图书信息
图书有id属性表示唯一标识,书名,有作者,价格的信息
<!--xml声明version是版本的意思encoding是编码-->
<?xmlversion="1.0"encoding="UTF-8"?>
<books><!--这是xml注释-->
<book id="SN123123413241"><!--book标签描述一本图书id属性描述的是图书的编号-->
<name>java编程思想</name><!--name标签描述的是图书的信息-->
<author>华仔</author><!--author单词是作者的意思,描述图书作者-->
<price>9.9</price><!--price单词是价格,描述的是图书的价格-->
</book>
<book id="SN12341235123"><!--book标签描述一本图书id属性描述的是图书的编号-->
<name>葵花宝典</name><!--name标签描述的是图书的信息-->
<author>班长</author><!--author单词是作者的意思,描述图书作者-->
<price>5.5</price><!--price单词是价格,描述的是图书的价格-->
</book>
</books>
xml语法
1.文档声明
在一个完整的XML文档中,必须包含一个XML文档的声明,并且该声明必须位于文档的第一行,这个声明表示该文档是一个XML文档,以及遵循哪个XML版本的规范。
<?xml 版本信息[编码信息] [文档独立性信息]?>
文档声明以符号"<?“开头,以符号”?>“结尾,中间可以版本声明、编码信息以及文档独立信息。需要注意的是在”<“和”?“之间、”?“和”>“之间以及第一个”?"和xml之间不能有空格;另外中括号括起来的部分是可选的。
<?xml version="1.0" encoding="UTF-8"? standalone="yes"?>
2.元素定义
在XML文档中,主体内容都是由元素(Element)组成的。元素一般是由开始标记、属性、元素内容和结束标记构成,具体如下。
<城市>北京</城市>
上面的示例中,"<北京>“就是XML文档中的标记,标记的地名也就是元素的名称。在一个元素中可以嵌套若干子元素。如果一个元素没有嵌套在其他元素内,则这个元素称为根元素。根元素是XML文档定义的第一个元素。如果一个元素中没有嵌套子元素,也没有包含文本内容,这样的元素称为空元素,空元素可以不使用结束标记。但必须在起始标记的”>“前增加一个正斜杠”/"来说明该元素是一个空元素,例如:<img></img>可以简写成<img/>
3.属性定义
在XML文档中,可以为元素定义属性。属性是对元素的进一步描述和说明。在一个元素中,可以有多个属性,并且每个属性都有自己的名称和取值,具体如下:
<零售价 单位="元">54.2</零售价>
在上面的示例中,<售价>元素中定义了一个属性“单位”。需要注意的是,在XML文档中,属性的命名规范同元素相同,属性值必须用双引号("")或者单引号(‘’)引起来,否则被视为错误。
4.注释
如果想在XML文档中插入一些附加信息,比如作者姓名、地址和电话等信息,或者想暂时屏蔽某些XML语句,这时可以通过注释的方式实现,被注释的内容会被程序忽略而不被解析和处理,XML的注释和HTML注释写法基本一致,具体方法如下:
<!--注释信息-->
severlet
javaweb三大组件
Servlet程序 Filter过滤器 Listener监听器
Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。
创建一个servlet工程
继承servlet类
1.先创建动态工程
2.文件->项目结构
3.
应用之后,点击确定
4.servlet程序
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse)throws ServletException, IOException {
System.out.println("HelloServlet被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
5.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">
<!--servlet标签给Tomcat配置Servlet程序-->
<servlet><!--servlet-name标签Servlet程序起一个别名(一般是类名)-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class是Servlet程序的全类名-->
<servlet-class>alva.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping标签给servlet程序配置访问地址-->
<servlet-mapping><!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern标签配置访问地址<br/>/斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径<br/>/hello表示地址为:http://ip:port/工程路径/hello<br/>-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
思路是先配置程序,再配置地址
我们选择服务器访问之后运行的是index.jsp页面,想要访问servlet程序的话就输入对应的工程路径
url地址到Servlet程序的访问
Servlet的生命周期
以下第一、二步,是在第一次访问,的时候创建Servlet程序会调用。第三步每次访问都会调用。第四步,在web工程停止的时候调用。
- 执行Servlet构造器方法
- 执行init初始化方法。
- 执行service方法
- 执行destroy销毁方法
GET和POST请求的分发处理
service方法是专门用来处理请求和响应的
做一个get请求
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse)throws ServletException, IOException {
System.out.println("3service===HelloServlet被访问了");
//类型转换(因为它有getMethod()方法)
HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest;
//获取请求的方式
String method = httpServletRequest.getMethod();
if("GET".equals(method)){
doGet();
}else if("POST".equals(method)){
doPost();
}
}
/**
* 做get请求的操作
**/
public void doGet(){
System.out.println("get请求");
System.out.println("get请求");
}
/**
*做post请求的操作
**/
public void doPost(){
System.out.println("post请求");
System.out.println("post请求");
}
tohello.html
<form action="http://localhost:8099/server/hello" method="get">
<input type="submit">
</form>
访问 http://localhost:8099/server/tohello.html 点击按钮之后,控制台输出
将method的get改成post之后在运行操作得到的结果如下
通过继承HttpServlet实现Servlet程序
一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现Servlet程序。
- 编写一个类去继承HttpServlet类
- 根据业务需要重写doGet或doPost方法
- 到web.xml中的配置Servlet程序的访问地址
public class servlethaha extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("do get");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("do post");
}
}
访问 http://localhost:8099/server/hello1 改成post同理
创建servlet程序有快捷方式,因为我用的是新版的idea2022,不同的idea可能方法不一致
idea创建Servlet
Servlet类的继承体系
ServletConfig类
ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类。
Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用。Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象。
ServletConfig类的三大作用
- 可以获取Servlet程序的别名servlet-name的值
- 获取初始化参数init-param
- 获取ServletContext对象
<servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>alva.servlet</servlet-class>
<!-- 初始化参数-->
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/alva</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
public class servlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
//1、可以获取Servlet程序的别名servlet-name的值
System.out.println("HelloServlet程序的别名是:"+config.getServletName());
//2、获取初始化参数init-param
System.out.println("初始化参数username的值是;"+config.getInitParameter("username"));
System.out.println("初始化参数url的值是;"+config.getInitParameter("url"));
//3、获取ServletContext对象
System.out.println(config.getServletContext());
}
}
ServletContext类
什么是ServletContext?
- ServletContext是一个接口,它表示Servlet上下文对象
- 一个web工程,只有一个ServletContext对象实例
- ServletContext对象是一个域对象
- ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁
什么是上下文对象?
上下文对象是服务器容器的全局变量,部署后,启动Tomcat时,Tomcat将为每一个应用创建一个对象,这个对象称之为上下文对象
什么是域对象?
- 域对象,是可以像Map一样存取数据的对象,叫域对象。
- 这里的域指的是存取数据的操作范围,整个web工程。
存数据 | 取数据 | 删除数据 | |
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
ServletContext类的四个作用
- 获取web.xml中配置的上下文参数context-param
- 获取当前的工程路径,格式:/工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像Map一样存取数据
<!--context-param是上下文参数,它属于整个web工程,配置的时候放webapp标签内-->
<context-param>
<param-name>username</param-name>
<param-value>alva</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>123</param-value>
</context-param>
public class ServletContext extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取web.xml中配置的上下文参数context-param
jakarta.servlet.ServletContext context = getServletConfig().getServletContext();
String username=context.getInitParameter("username");
System.out.println("context-param参数username的值是:"+username);
System.out.println("context-param参数password的值是:"+context.getInitParameter("password"));
//2、获取当前的工程路径,格式:/工程路径
System.out.println("当前工程路径:"+context.getContextPath());
//3、获取工程部署后在服务器硬盘上的绝对路径/***/斜杠被服务器解析地址为:http://ip:port/工程名/映射到IDEA代码的web目录<br/>*/
System.out.println("工程部署的路径是:"+context.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:"+context.getRealPath("/css"));
System.out.println("工程下imgs目录1.jpg的绝对路径是:"+context.getRealPath("/imgs/1.jpg"));
}
}
存取数据
System.out.println("保存之前:Context1获取key1的值是:"+context.getAttribute("key1"));
context.setAttribute("key1","value1");
System.out.println("Context1中获取域数据key1的值是:"+context.getAttribute("key1"));
在其他含有ServletContext对象的servlet类中也可以获取
HTTP协议
什么是协议?
协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP协议。
- HTTP协议中的数据又叫报文。
- 请求的HTTP协议格式客户端给服务器发送数据叫请求。
- 服务器给客户端回传数据叫响应。
- 请求又分为GET请求,和POST请求两种
GET请求
请求行
请求的方式 GET
请求的资源路径 [+?+请求参数]
请求的协议的版本号 HTTP/1.12
请求头
key:value 组成不同的键值对,表示不同的含义。
POST请求
请求行
请求的方式 POST
请求的资源路径 [+?+请求参数]
请求的协议的版本号 HTTP/1.12
请求头
key:value 不同的请求头,有不同的含义空行
请求体===>>>就是发送给服务器的数据
常用请求头的说明
- Accept: 表示客户端可以接收的数据类型
- Accpet-Languege: 表示客户端可以接收的语言类型
- User-Agent: 表示客户端浏览器的信息
- Host:表示请求时的服务器ip和端口号
哪些是GET请求,哪些是POST请求GET请求有哪些:
- form标签method=get
- a标签
- link标签引入css
- Script标签引入js文件
- img标签引入图片
- iframe引入html页面
在浏览器地址栏中输入地址后敲回车POST请求有哪些:
- form标签method=post
响应的HTTP协议格式
响应行
(1)响应的协议和版本号
(2)响应状态码
(3)响应状态描述符
响应头
key:value不同的响应头,有其不同含义
空行
响应体---->>>就是回传给客户端的数据
常用的响应码说明
- 200 表示请求成功
- 302 表示请求重定向
- 404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
- 500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
-
405 提交方式是POST,在httpservlet里没有dopost方法
MIME类型说明
MIME是HTTP协议中数据类型。MIME的英文全称是"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
常见的MIME类型:
谷歌浏览器如何查看HTTP协议:
火狐浏览器如何查看HTTP协议:
HttpServletRequest类
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过HttpServletRequest对象,获取到所有请求的信息。
HttpServletRequest类的常用方法
- i.getRequestURI() 获取请求的资源路径
- ii.getRequestURL() 获取请求的统一资源定位符(绝对路径)
- iii.getRemoteHost() 获取客户端的ip地址
- iv.getHeader() 获取请求头
- v.getParameter() 获取请求的参数
- vi.getParameterValues() 获取请求的参数(多个值的时候使用)
- vii.getMethod() 获取请求的方式GET或POST
- viii.setAttribute(key,value); 设置域数据
- ix.getAttribute(key); 获取域数据
- x.getRequestDispatcher() 获取请求转发对象
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("do get");
// 获取请求的资源路径
System.out.println("uri =>" + req.getRequestURI());
// 获取请求的统一资源定位符 (绝对路径)
System.out.println("url =>" + req.getRequestURL());
// getRemoteHost()获取客户端的ip地址
System.out.println("客户端ip地址=>"+req.getRemoteHost());
// iv.getHeader()获取请求头
System.out.println("请求头User-Agent==>>"+req.getHeader("User-Agent"));
// getMethod()获取请求的方式GET或POST
System.out.println("请求的方式==>>"+req.getMethod());
}
编写程序获取请求参数
前台表单
<form action="http://localhost:8099/server/hello" method="get">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
</form>
Java代码
public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求参数
String username=req.getParameter("username");
String password=req.getParameter("password");
String[] hobby=req.getParameterValues("hobby");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
System.out.println("兴趣爱好:"+ Arrays.asList(hobby));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("do post");
}
}
乱码解决
请求转发
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。
编程实现
base标签的作用
怎么理解呢?就是base标签是放在头部标签中的,用来设置相对路径,在body中,发生页面跳转时的路径都是按照这个相对跳转的
上面提到的请求转发,就是用servlet程序设置请求转发到要设置的路径,前台设置跳转到servlet路径
Web中的相对路径和绝对路径
web中/斜杠的不同意义
HttpServletResponse类
HttpServletResponse类和HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。
HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息
我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置
两个输出流的说明
字节流 getOutputStream(); 常用于下载(传递二进制数据)
字符流 getWriter(); 常用于回传字符串(常用)
两个流同时只能使用一个。使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
编程实现
PrintWriter writer = resp.getWriter();
writer.write("给客户端传字符串");
响应的乱码解决
//它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
//此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("给客户端传字符串");
请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)
resp.sendRedirect("http://localhost:8080");
请求转发和重定向的区别
转发是指当前Servlet将请求转交给其他的Servlet进行再次处理
转发特点:
- 转发时浏览器只发送1次请求
- 转发是在服务器端进行的
- 转发时浏览器的地址栏没有发生改变
- 浏览器感知不到转发的发生
重定向
重定向是Servlet发送给浏览器的一个特殊的响应,这个响应告诉浏览器再去请求另一个地址,类似于政府的相关部门,该特殊响应的报文格式如下:
HTTP/1.1 302 Found Location: http://localhost:8080/04_WEB_Servlet/target.html
这个特殊响应的响应状态码是302,还有一个特殊的响应头Location指向的是一个新的地址,当浏览器收到302这个响应状态码以后,就会自动的再次向Location所指向的地址发送请求
重定向的特点:
- 重定向时浏览器一共发送了2次请求
- 重定向是在浏览器端进行的
- 浏览器的地址栏会发生改变
- 浏览器可以感知到重定向的发生
页面跳转的时候什么时候用转发,什么时候用重定向
-
如果在上一个Servlet当中向request域当中绑定了数据,希望从下一个Servlet当中把request域里面的数据取出来,使用转发机制。
-
剩下所有的请求均使用重定向。(重定向使用较多。)
转发带来的问题
如果最后一次转发的是一次提交,那么每一次刷新由于没有跳转的正确的页面都会重新提交,最终导致重复提交
-
删除之后,重定向
-
修改之后,重定向
-
保存之后,重定向
-
重定向:
-
成功
-
失败
-
转发和重定向的比较:
比较内容 | 转发 | 重定向 |
浏览器请求次数 | 1 | 2 |
发生的位置 | 服务器 | 浏览器 |
地址栏变化 | 无 | 有 |
浏览器感知 | 无 | 有 |
1
111
JSP
JSP(全称Java Server Pages)是由Sun公司专门为了解决动态生成HTML文档的技术
jsp以java基础开发。所以它沿用了java强大的api功能,jsp页面中的html代码用来显示静态内容的部分,嵌入到页面中的Java代码与jsp标记来生成动态的内容部分
Servlet程序输出html页面
学习jsp技术之前,如果我们要往客户端输出一个页面。我们可以使用Servlet程序来实现。具体的代码如下
在浏览器中输入访问Servlet的程序地址得到以下结果
通过Servlet输出简单的html页面信息都非常不方便。那我们要输出一个复杂页面的时候,就更加的困难,而且不利于页面的维护和调试。所以sun公司推出一种叫做jsp的动态页面技术帮助我们实现对页面的输出繁锁工作。
jsp页面的访问千万不能像HTML页面一样。托到浏览器中。只能通过浏览器访问Tomcat服务器再访问jsp页面
jsp文件的创建
在web目录下面右键创建即可,和html文件运行的方式一样
jsp运行原理
jsp的本质,其实是一个Servlet程序。
使用tomcat运行之后,jsp文件会生成对应的java类文件,打开文件查看里面的内容:发现,生成的类继承于HttpJspBase类。这是一个jsp文件生成Servlet程序要继承的基类
HttpJspBase这个类就是所有jsp文件生成Servlet程序需要去继承的基类。并且这个HttpJspBase类继承于HttpServlet类。所以jsp也是一个Servlet小程序
jsp的语法
jsp文件头部声明介绍(page指令介绍)
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
这是jsp文件的头声明。表示这是jsp页面。language属性值只能是java。
jsp的三种脚本
声明脚本
<%!
java代码
%>
- 我们可以定义全局变量
- 定义static静态代码块
- 定义方法
- 定义内部类
- 几乎可以写在类的内部写的代码,都可以通过声明脚本来实现
表达式脚本
<%= 表达式 %>
表达式脚本用于向页面输出内容
表达式脚本翻译到Servlet程序的service方法中以out.print()打印输出 out是jsp的一个内置对象,用于生成html的源代码
注意:表达式不要以分号结尾,否则会报错表达式脚本可以输出任意类型。组成“<%=”标记的各字符之间不可以有空格
比如:1.输出整型2.输出浮点型3.输出字符串4.输出对象
代码脚本
<% java代码 %>
- 代码脚本里可以书写任意的java语句
- 代码脚本的内容都会被翻译到service方法中
- 所以service方法中可以写的java代码,都可以书写到代码脚本中
jsp注释
<%--jsp注释--%>
隐式注释
JSP 隐藏注释在 JSP 源代码中,它不会被 JSP 引擎处理,也不会在客户端的 Web 浏览器上显示,格式如下:
- <%--comment--%>
- <% 行注释 %>
- <% /* 块注释 */ %>
jsp九大内置对象
- request对象: 是 javax.servlet.httpServletRequest类型的对象。
- response对象: 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。
- session对象: 是由服务器自动创建的与用户请求相关的对象。
- application对象:可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。
- out 对象: 用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。
- pageContext 对象:作用是取得任何范围的参数,可以获取 JSP页面的out、request、reponse、session、application 等对象。
- config 对象: 主要作用是取得服务器的配置信息。
- page 对象: 代表JSP本身,只有在JSP页面内才是合法的。
- exception 对象:作用是是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。
九大内置对象,都是我们可以在【代码脚本】中或【表达式脚本】中直接使用的对象。
jsp四大域对象
四大域对象经常用来保存数据信息。
- pageContext 可以保存数据在同一个jsp页面中使用
- request 可以保存数据在同一个request对象中使用。经常用于在转发的时候传递数据session 可以保存在一个会话中使用
- application(ServletContext) 就是ServletContext对象
新建两个jsp页面来测试
<body>
测试四大域对象 <br>
<%
//设置page域的数据
pageContext.setAttribute("key","pageContext-value");
//设置request域的数据
request.setAttribute("key","request-value");
//设置session域的数据
session.setAttribute("key","session-value");
//设置application域的数据
application.setAttribute("key","application-value");
%>
<%--测试当前页面的作用域--%>
<%=pageContext.getAttribute("key")%><br>
<%=request.getAttribute("key")%><br/>
<%=session.getAttribute("key")%><br/>
<%=application.getAttribute("key")%><br/>
</body>
<body>
这是context2页面<br/>
<%=pageContext.getAttribute("key")%><br/>
<%=request.getAttribute("key")%><br/>
<%=session.getAttribute("key")%><br/>
<%=application.getAttribute("key")%><br/>
</body>
out输出流和response.getwriter()输出流
<body>
测试四大域对象 <br>
<%
//out输出
out.write("这是out的第一次输出<br/>");
//out flush之后。会把输出的内容写入writer的缓冲区中
out.flush();
//最后一次的输出,由于没有手动flush,会在整个页面输出到客户端的时候,自动写入到writer缓冲区
out.write("这是out的第二次输出<br/>");
//writer的输出
response.getWriter().write("这是writer的第一次输出<br/>");
response.getWriter().write("这是writer的第二次输出<br/>");
%>
</body>
图解out流和writer流的两个缓冲区如何工作
将out.flush注释之后再运行
JSP7 个 动作指令
- jsp:forward: 执行页面转向,将请求的处理转发到下一个页面。
- jsp:param: 用于传递参数,必须与其他支持参数曲标签一起使用。
- jsp:include: 用于动态引入一个 JSP 页面。
- jsp:pugin: 用于下载 JavaBean 或 Applet 到客户端执行。
- jsp:useBean: 使用 JavaBean。
- jsp:setProperty: 修改 JavaBean 实例的属性值。
- jsp:getProperty: 获取 JavaBean 实例的属性值。
jsp常用标签
静态包含
<%@ include file="index.jsp" %>
静态包含是把包含的页面内容原封装不动的输出到包含的位置
动态包含--很少用
<jsp:include page=""></jsp:include>
动态包含会把包含的jsp页面单独翻译成servlet文件,然后在执行到时候再调用翻译的servlet程序。并把计算的结果返回。
动态包含是在执行的时候,才会加载。所以叫动态包含。
页面转发--常用
<jsp:forward page=""></jsp:forward>
转发功能相当于 request.getRequestDispatcher("/xxxx.jsp").forward(request,response);的功能。
静态包含和动态包含的区别
在这里需要补充说明一点:我们在工作中,几乎都是使用静态包含。理由很简单。因为jsp页面虽然可以写java代“玩转”Java系列码,做其他的功能操作。但是由于jsp在开发过程中被定位为专门用来展示页面的技术。也就是说。jsp页面中,基本上只有html,css,js。还有一些简单的EL,表达式脚本等输出语句。所以我们都使用静态包含
Listener监听器
监听器就是实时监视一些事物状态的程序,我们称为监听器
ServletContextListener监听器
javax.servlet.ServletContextListener ServletContext监听器
监听器的使用步骤
第一步:我们需要定义一个类。然后去继承生命周期的监听器接口。
第二步:然后在Web.xml文件中配置。ServletContextListener监听器,一定要在web.xml文件中配置之后才会生效
<listener>
<listener-class>全类名</listener-class>
</listener>
生命周期监听器两个方法
创建一个类实现ServletContextListener接口
public class listener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了");
}
}
web.xml配置
<listener>
<listener-class>alva.listener</listener-class>
</listener>
服务器启动和停止时分别输入上面两句
JavaBean
JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
- 这个Java类必须具有一个无参的构造函数
- 属性必须私有化。
- 私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
javaBean示例
1/**
4 * @author gacl
5 * Person类就是一个最简单的JavaBean
6 */
7 public class Person {
8
9 //------------------Person类封装的私有属性---------------------------------------
10 // 姓名 String类型
11 private String name;
12 // 性别 String类型
13 private String sex;
14 // 年龄 int类型
15 private int age;
16 //是否已婚 boolean类型
17 private boolean married;
18 //---------------------------------------------------------
19
20 //------------------Person类的无参数构造方法---------------------------------------
21 /**
22 * 无参数构造方法
23 */
24 public Person() {
25
26 }
27 //---------------------------------------------------------
28
29 //------------------Person类对外提供的用于访问私有属性的public方法---------------------------------------
30 public String getName() {
31 return name;
32 }
33
34 public void setName(String name) {
35 this.name = name;
36 }
37
38 public String getSex() {
39 return sex;
40 }
41
42 public void setSex(String sex) {
43 this.sex = sex;
44 }
45
46 public int getAge() {
47 return age;
48 }
49
50 public void setAge(int age) {
51 this.age = age;
52 }
53
54 public boolean isMarried() {
55 return married;
56 }
57
58 public void setMarried(boolean married) {
59 this.married = married;
60 }
61 //---------------------------------------------------------
62 }
在JSP中使用JavaBean
JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为:
- <jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
- <jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
- <jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
<jsp:useBean>标签
用于在指定的域范围内查找指定名称的JavaBean对象,如果存在则直接返回该JavaBean对象的引用,如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。
常用语法:
<jsp:useBean id="beanName" class="package.class" scope="page|request|session|application"/>
- "id"属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
- "class"属性用于指定JavaBean的完整类名(即必须带有包名)。
- "scope"属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session和application等四个值中的一个,其默认值是page
使用范例
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%--
3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
5 ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
6 ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
7 ┝class:此对象对应的包.类名称
8 ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11 <%
12 //person对象在上面已经使用jsp:useBean标签实例化了,因此在这里可以直接使用person对象
13 //使用setXxx方法为对象的属性赋值
14 //为person对象的name属性赋值
15 person.setName("孤傲苍狼");
16 //为person对象的Sex属性赋值
17 person.setSex("男");
18 //为person对象的Age属性赋值
19 person.setAge(24);
20 //为person对象的married属性赋值
21 person.setMarried(false);
22 %>
23 <!DOCTYPE HTML>
24 <html>
25 <head>
26 <title>jsp:useBean标签使用范例</title>
27 </head>
28
29 <body>
30 <%--使用getXxx()方法获取对象的属性值 --%>
31 <h2>姓名:<%=person.getName()%></h2>
32 <h2>性别:<%=person.getSex()%></h2>
33 <h2>年龄:<%=person.getAge()%></h2>
34 <h2>已婚:<%=person.isMarried()%></h2>
35 </body>
36 </html>
<jsp:setProperty>标签
用于设置和访问JavaBean对象的属性。
语法格式一:
<jsp:setProperty name="beanName" property="propertyName" value="string字符串"/>
语法格式二:
<jsp:setProperty name="beanName" property="propertyName" value="<%= expression %>" />
语法格式三:
<jsp:setProperty name="beanName" property="propertyName" param="parameterName"/>
语法格式四:
<jsp:setProperty name="beanName" property= "*" />
- name属性用于指定JavaBean对象的名称。
- property属性用于指定JavaBean实例对象的属性名。
- value属性用于指定JavaBean对象的某个属性的值,value的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。
- param属性用于将JavaBean实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的JavaBean属性的类型。
<jsp:setProperty>标签使用范例1:使用jsp:setProperty标签设置person对象的属性值
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%--
3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
5 ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
6 ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
7 ┝class:此对象对应的包.类名称
8 ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11
12 <%--
13 使用jsp:setProperty标签设置person对象的属性值
14 jsp:setProperty在设置对象的属性值时会自动把字符串转换成8种基本数据类型
15 但是jsp:setProperty对于复合数据类型无法自动转换
16 --%>
17 <jsp:setProperty property="name" name="person" value="白虎神皇"/>
18 <jsp:setProperty property="sex" name="person" value="男"/>
19 <jsp:setProperty property="age" name="person" value="24"/>
20 <jsp:setProperty property="married" name="person" value="false"/>
21 <%--
22 birthday属性是一个Date类型,这个属于复合数据类型,因此无法将字符串自动转换成Date ,用下面这种写法是会报错的
23 <jsp:setProperty property="birthday" name="person" value="1988-05-07"/>
24 --%>
25 <jsp:setProperty property="birthday" name="person" value="<%=new Date()%>"/>
26 <!DOCTYPE HTML>
27 <html>
28 <head>
29 <title>jsp:setProperty标签使用范例</title>
30 </head>
31
32 <body>
33 <%--使用getXxx()方法获取对象的属性值 --%>
34 <h2>姓名:<%=person.getName()%></h2>
35 <h2>性别:<%=person.getSex()%></h2>
36 <h2>年龄:<%=person.getAge()%></h2>
37 <h2>已婚:<%=person.isMarried()%></h2>
38 <h2>出生日期:<%=person.getBirthday()%></h2>
39 </body>
40 </html>
<jsp:setProperty>标签使用范例2:使用请求参数为bean的属性赋值
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%--
3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
5 ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
6 ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
7 ┝class:此对象对应的包.类名称
8 ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11
12 <%--
13 jsp:setProperty标签可以使用请求参数为bean的属性赋值
14 param="param_name"用于接收参数名为param_name的参数值,然后将接收到的值赋给name属性
15 --%>
16 <jsp:setProperty property="name" name="person" param="param_name"/>
17
18 <!DOCTYPE HTML>
19 <html>
20 <head>
21 <title>jsp:setProperty标签使用范例</title>
22 </head>
23
24 <body>
25 <%--使用getXxx()方法获取对象的属性值 --%>
26 <h2>姓名:<%=person.getName()%></h2>
27 </body>
28 </html>
<jsp:setProperty>标签使用范例3:用所有的请求参数为bean的属性赋值
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%--
3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
5 ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
6 ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
7 ┝class:此对象对应的包.类名称
8 ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11
12 <%--
13 jsp:setProperty标签用所有的请求参数为bean的属性赋值
14 property="*"代表bean的所有属性
15 --%>
16 <jsp:setProperty property="*" name="person"/>
17
18 <!DOCTYPE HTML>
19 <html>
20 <head>
21 <title>jsp:setProperty标签使用范例</title>
22 </head>
23
24 <body>
25 <%--使用getXxx()方法获取对象的属性值 --%>
26 <h2>姓名:<%=person.getName()%></h2>
27 <h2>性别:<%=person.getSex()%></h2>
28 <h2>年龄:<%=person.getAge()%></h2>
29 </body>
30 </html>
<jsp:getProperty>标签
用于读取JavaBean对象的属性,也就是调用JavaBean对象的getter方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中。
语法:
<jsp:getProperty name="beanInstanceName" property="PropertyName" />
- name属性用于指定JavaBean实例对象的名称,其值应与<jsp:useBean>标签的id属性值相同。
- property属性用于指定JavaBean实例对象的属性名。
如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty>标签输出该属性的结果将是一个内容为“null”的字符串。
范例:使用jsp:getProperty获取bean对象的属性值
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%--
3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
5 ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
6 ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
7 ┝class:此对象对应的包.类名称
8 ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11
12 <%--
13 使用jsp:setProperty标签设置person对象的属性值
14 jsp:setProperty在设置对象的属性值时会自动把字符串转换成8种基本数据类型
15 但是jsp:setProperty对于复合数据类型无法自动转换
16 --%>
17 <jsp:setProperty property="name" name="person" value="白虎神皇"/>
18 <jsp:setProperty property="sex" name="person" value="男"/>
19 <jsp:setProperty property="age" name="person" value="24"/>
20 <jsp:setProperty property="married" name="person" value="false"/>
21 <%--
22 birthday属性是一个Date类型,这个属于复合数据类型,因此无法将字符串自动转换成Date ,用下面这种写法是会报错的
23 <jsp:setProperty property="birthday" name="person" value="1988-05-07"/>
24 --%>
25 <jsp:setProperty property="birthday" name="person" value="<%=new Date()%>"/>
26 <!DOCTYPE HTML>
27 <html>
28 <head>
29 <title>jsp:getProperty标签使用范例</title>
30 </head>
31
32 <body>
33 <%--使用jsp:getProperty标签获取对象的属性值 --%>
34 <h2>姓名:<jsp:getProperty property="name" name="person"/></h2>
35 <h2>性别:<jsp:getProperty property="sex" name="person"/></h2>
36 <h2>年龄:<jsp:getProperty property="age" name="person"/></h2>
37 <h2>已婚:<jsp:getProperty property="married" name="person"/></h2>
38 <h2>出生日期:<jsp:getProperty property="birthday" name="person"/></h2>
39 </body>
40 </html>
jsp指令(伪指令)
jsp中有三大指令,分别是:
- page指令,最复杂,也是最常用的
- include —>静态包含,这个和requestDispatcher.include区别是后者是动态包含
- taglib -->导入标签库
在jsp文件中使用指令的格式为:<%@指令名 属性名=属性值 %>
EL表达式
Expression Language。是表达式语言。
EL表达式的什么作用:
EL表达式主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出。因为EL表达式在输出数据的时候,要比jsp的表达式脚本要简洁很多。
<%
request.setAttribute("a","哈哈哈");
%>
表达式脚本输出key的值是:
<%= request.getAttribute("a") == null ?"" :request.getAttribute("a") %> <br>
EL表达式输出key的值是:
${a}
EL表达式在输出null值的时候,输出的是空串。jsp表达式脚本输出null值的时候,输出的是null字符串
EL表达式搜索域数据的顺序
EL表达式主要是在jsp页面中输出数据。主要是输出域对象中的数据。当四个域中都有相同的key的数据的时候,EL表达式会按照四个域的从小到大的顺序去进行搜索,找到就输出。
page - request - session - application
<%
//往四个域中都保存了相同的key的数据。
request.setAttribute("key","request");
session.setAttribute("key","session");
application.setAttribute("key","application");
pageContext.setAttribute("key","pageContext");
%>
${key}
最先输出的是 pageContext
输出Bean的普通属性,数组属性。List集合属性,map集合属性
需求——输出Person类中普通属性,数组属性。list集合属性和map集合属性
public class Student {
// 需求——输出Person类中普通属性,数组属性。list集合属性和map集合属性
private String name;
private String[] phones;
private List<String> cities;
private Map<String,Object> map;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getPhones() {
return phones;
}
public void setPhones(String[] phones) {
this.phones = phones;
}
public List<String> getCities() {
return cities;
}
public void setCities(List<String> cities) {
this.cities = cities;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public int getAge(){
return 18;
}
}
<%
Student student = new Student();
student.setName("alva");
student.setPhones(new String[]{"123214","1245314","23412412"});
List<String> cities = new ArrayList<String>();
cities.add("北京");
cities.add("上海");
cities.add("深圳");
student.setCities(cities);
Map<String,Object> map = new HashMap<>();
map.put("a","a");
map.put("b","b");
map.put("c","c");
student.setMap(map);
pageContext.setAttribute("p",student);
%>
输出Student:${p}<br/>
输出Student的name属性:${p.name}<br>
输出Student的pnones数组属性值:${p.phones[2]}<br>
输出Student的cities集合中的元素值:${p.cities}<br>
输出Student的List集合中个别元素值:${p.cities[2]}<br>
输出Student的Map集合:${p.map}<br>
输出Student的Map集合中某个key的值:${p.map.c}<br>
输出Person的age属性:${p.age}<br>
EL表达式运算
关系运算
逻辑运算
算数运算
empty运算
empty运算可以判断一个数据是否为空,如果为空,则输出true,不为空输出false。
以下几种情况为空:
- 值为null值的时候,为空
- 值为空串的时候,为空
- 值是Object类型数组,长度为零的时候
- list集合,元素个数为零
- map集合,元素个数为零
“.”点运算和[]中括号运算符
.点运算,可以输出Bean对象中某个属性的值。[]中括号运算,可以输出有序集合中某个元素的值。并且[]中括号运算,还可以输出map集合中key里含有特殊字符的key的值
<html>
<head>
<title>index</title>
</head>
<body>
<%
Map<String,Object>map=new HashMap<String,Object>();
map.put("a.a.a","aaaValue");
map.put("b+b+b","bbbValue");
map.put("c-c-c","cccValue");
request.setAttribute("map",map);
%>${map['a.a.a']}<br>
${map["b+b+b"]}<br>
${map['c-c-c']}<br>
</body>
</html>
EL表达式的11个隐含对象
EL个达式中11个隐含对象,是EL表达式中自己定义的,可以直接使用
EL获取四个特定域中的属性
<%
pageContext.setAttribute("key1","pageContext1");
pageContext.setAttribute("key2","pageContext2");
request.setAttribute("key2","request");
session.setAttribute("key2","session");
application.setAttribute("key2","application");
%>
${applicationScope.key2}
输出 application
pageContext对象的使用
<html>
<head>
<title>index</title>
</head>
<body>
<%
pageContext.setAttribute("req", request);
%>
<%=request.getScheme()%><br>
1.协议:${req.scheme}<br>
2.服务器ip:${pageContext.request.serverName}<br>
3.服务器端口:${pageContext.request.serverPort}<br>
4.获取工程路径:${pageContext.request.contextPath}<br>
5.获取请求方法:${pageContext.request.method}<br>
6.获取客户端ip地址:${pageContext.request.remoteHost}<br>
7.获取会话的id编号:${pageContext.session.id}<br>
</body>
</html>
EL表达式其他隐含对象的使用
web.xml中的配置
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql:///test</param-value>
</context-param>
JSTL标签库
JSP Standard TagLibrary JSP标准标签库
是一个不断完善的开放源代码的JSP标签库。EL表达式主要是为了替换jsp中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个jsp页面变得更佳简洁
JSTL由五个不同功能的标签库组成
IDEA中使用jstl标签库
<c:set />(使用很少)
作用:set标签可以往域中保存数据
<c:set scope="session" var="abc" value="abcValue"/>
保存之后:${sessionScope.abc}<br>
<c:if/ >
- if标签用来做if判断
- test属性表示判断的条件(使用EL表达式输出)
<c:if test="${12 == 12}">
<h1>12等于12</h1>
</c:if>
<c:if test="${12 != 12}">
<h1>12不等于12</h1>
</c:if>
<c:choose><c:when><c:otherwise>
标签作用:多路判断。跟switch...case....default非常接近
<c:forEach/>
作用:遍历输出使用
遍历1到10,输出
<table border="1">
<c:forEach begin="1" end="10" var="i">
<tr>
<td>第${i}行</td>
</tr>
</c:forEach>
</table>
遍历Object数组
<% request.setAttribute("arr",newString[{"18610541354","18688886666","18699998888"});
%>
<c:forEach items="${requestScope.arr}" var="item">
${item}<br>
</c:forEach>
遍历Map集合
<%
Map<String,Object> map=new HashMap<String,Object>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
request.setAttribute("map",map);%>
<c:forEach items="${requestScope.map}" var="entry">
<h1>${entry.key}=${entry.value}</h1>
</c:forEach>
Cookie饼干
- Cookie翻译过来是饼干的意思
- Cookie是服务器通知客户端保存键值对的一种技术
- 客户端有了Cookie后,每次请求都发送给服务器
- 每个Cookie的大小不能超过4kb
- web程序是使用HTTP协议传输的,而HTTP协议是无状态的协议,对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。cookie的出现就是为了解决这个问题。
- 第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。就相当于给客户端们颁发一个通行证,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
如何创建Cookie
cookie的主要内容
名字,值,过期时间,路径和域,路径与域一起构成cookie的作用范围。
生命周期:
表示当前cookie的生命周期为浏览器会话期间,关闭浏览器则cookie消失。
Cookie什么时候产生 ?
- Cookie的使用一先要看需求。因为浏览器可以禁用Cookie,同时服务端也可以不Set-Cookie。
- 客户端向服务器端发送一个请求的时,服务端向客户端发送一个Cookie然后浏览器将Cookie保存。
- Cookie有两种保存方式,一种是浏览器会将Cookie保存在内存中,还有一种是保存在客户端的硬盘中,之后每次HTTP请求浏览器都会将Cookie发送给服务器端。
session
什么叫web中的会话?
用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
Session的定义
在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息,一般存在服务器用来存放用户数据的类HashTable结构。
Session什么时候产生 ?
当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
服务器会向客户浏览器发送一个每个用户特有的会话编号sessionID,让他进入到cookie里。
服务器同时也把sessionID和对应的用户信息、用户操作记录在服务器上,这些记录就是session。再次访问时会带入会发送cookie给服务器,其中就包含sessionID
服务器从cookie里找到sessionID,再根据sessionID找到以前记录的用户信息就可以知道他之前操控些、访问过哪里。
会话跟踪技术
对同一个用户对服务器的连续的请求和接收响应的监视
为什么需要会话跟踪技术?
浏览器与服务器之间的通信是通过HTTP协议进行通信的,而HTTP协议是“无状态”的协议(早期主要用于web端获取内容,浏览了就结束,没有考虑交互的场景,所以服务器不会保留与用户交易的任何状态),客户端与服务器之间的联系是离散的、非连续的。多次请求,无法根据前后的请求来判断是否是同一个用户,面对越来越多的交互场景,会话跟踪技术应运而生
种类
从原理上分析,一次请求和响应主要参与的有服务器、客户端,以及通信的HTTP协议,多以分别从这三方面考虑,会话跟踪技术主要有以下四种:
- Cookie
- url重写
- 隐藏表单域
- Session
隐藏表单域
隐藏表单域是利用 HTML 中的隐藏域,在网页表单内隐藏某些客户端的信息。在提交表单时,要将指定的名称和值自动包括在请求实体中,这些信息会随客户端的请求信息一起传送给服务器,服务器通过获取的这些信息来进行会话跟踪。
这些识别信息是隐藏的,所以不会在客户端的浏览器页面上显示,但是,如果查看 HTML 的源文件,是可以看到这些隐藏字段的,这样很可能会导致用户资料的泄露。显然,这是使用隐藏域方式的一个缺陷
<form name="testform" action="/xxx">
//隐藏域
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
URL重写
客户程序在每个URL的尾部添加一些额外数据(以键值对的形式传递),这些数据标识当前的会话,服务器将这个标识符与它存储的用户相关数据关联起来。通常是添加 sessionID作为会话信息的标识
http://172.23.22.58:8081/jjyhf;jsessionid=123456789
四种会话跟踪技术对比分析
Session的生命周期 ?
一般情况下,服务器会在一定时间内(默认30分钟)保存这个 Session,过了时间限制,就会销毁这个Session。
举个例子,你登录一个服务器,服务器返回给你一个sessionID,登录成功之后的半小时之内没有对该服务器进行任何HTTP请求,半小时后你进行一次HTTP请求,会提示你重新登录。
工作原理图:
若禁用了cookie那么session能不能使用?
能使用。 经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
session和cookie的异同
相同点:
两者都是一种记录用户状态的机制,都是为了减少客户端和服务器端之间的传输的冗余数据,提高两者之间的数据传输速率。
不同点:
- Cookie可以存储在浏览器或者本地,Session只能存在服务器
- session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象
- Session比Cookie更具有安全性(Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击)
- Session占用服务器性能,Session过多,增加服务器压力
- 单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie,Session是没有大小限制,只和服务器的内存大小有关。
session和cookie的结合使用
web开发发展至今,cookie和session的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:
- 储存在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。
- 将session数据加密,然后储存在cookie中:这种专业术语叫做client side session。flask采用的就是这种方式,但是也可以替换成其他形式。
Filter
拦截请求,过滤响应
在你的 web 工程下,有一个 admin 目录。这个 admin 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必 须是用户登录之后才允许访问。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是登录页面login.jsp
<form action="http://localhost:8099/jsp/login" method="get">
用户名:<input type="text" name="username"> <br/>
密 码:<input type="password" name="password"> <br/>
<input type="submit">
</form>
</body>
</html>
public class LoginServlet extends HttpServlet {
//登录跳转之后执行的操作
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码
resp.setContentType("text/html;charset=UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
if ("admin".equals(username) && "123".equals(password)) {
req.getSession().setAttribute("user", username);
//将用户存入session之后在输出提示
resp.getWriter().write("登录成功!!");
} else {
//重定向可以让地址保持不变,地址还是显示在servlet配置程序页面地址
req.getRequestDispatcher("/error.jsp").forward(req,resp);;
}
}
}
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
/**
* 专门用于拦截请求,可以做权限检查
*
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
if (user == null) { //如果没有获取到用户
servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest, servletResponse);
return;
}else{
//让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>alva.server.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<!--filter标签用于配置一个Filter过滤器-->
<filter>
<!--给filter起一个别名-->
<filter-name>LoginFilter</filter-name>
<!--配置全类名-->
<filter-class>alva.server.LoginFilter</filter-class>
</filter>
<!--filter-mapping配置Filter过滤器的拦截路径-->
<filter-mapping>
<!--filter-name表示当前的拦截路径给哪个Filter使用-->
<filter-name>LoginFilter</filter-name>
<!--
url-pattern配置拦截路径
/ 表示请求地址为:http://ip.port/工程路径/ 映射到IDEA的web目录
/admin/* 表示请求地址为:http://ip.port/工程路径/*
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
现在进行测试,直接访问admin下面的hello页面
会让你先登录,再测试登录之后再去访问
Filter的工作流程图
Filter过滤器的使用步骤:
- 编写一个类去实现Filter接口
- 实现过滤方法doFilter()
- 到web.xml中去配置Filter的拦截路径
Filter生命周期
1、构造器方法
2、init 初始化方法
第 1,2 步,在 web 工程启动的时候执行(Filter 已经创建)
3、doFilter 过滤方法
第 3 步,每次拦截到请求,就会执行(在xml中配置的,只要有该请求就进行拦截判断)
4、destroy 销毁
第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)
FilterConfig类
FilterConfig 类见名知义,它是 Filter 过滤器的配置文件类。 Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息。
FilterConfig 类的作用是获取 filter 过滤器的配置内容
- 获取 Filter 的名称 filter-name 的内容
- 获取在 web.xml 中配置的 init-param 初始化参数
- 获取 ServletContext 对象
web.xml中AdminFilter的初始化参数
<!--filter标签用于配置一个Filter过滤器-->
<filter>
<!--给filter起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置全类名-->
<filter-class>filter.AdminFilter</filter-class>
<!--配置初始化参数-->
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:13306/test</param-value>
</init-param>
</filter>
<!--filter-mapping配置Filter过滤器的拦截路径-->
<filter-mapping>
<!--filter-name表示当前的拦截路径给哪个Filter使用-->
<filter-name>AdminFilter</filter-name>
<!--
url-pattern配置拦截路径
/ 表示请求地址为:http://ip.port/工程路径/ 映射到IDEA的web目录
/admin/* 表示请求地址为:http://ip.port/工程路径/admin/*
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init(FilterConfig filterConfig)方法");
//1、获取 Filter 的名称 filter-name 的内容
System.out.println("filter-name :" + filterConfig.getFilterName());
//2、获取在 wen.xml 中配置的 init-param 初始化参数
System.out.println("初始化参数username的值是:" + filterConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是:" + filterConfig.getInitParameter("url"));
//3、获取 ServletContext 对象
System.out.println("ServletContext的值是:" + filterConfig.getServletContext());
}
Filter的拦截路径
精确匹配
<url-pattern>/target.jsp</url-pattern> 表示请求地址为:http://ip:port/工程路径/target.jsp
目录匹配
<url-pattern>/admin/*</url-pattern> 表示请求地址必须为:http://ip:port/工程路径/admin/*
后缀名匹配
<url-pattern>*.html</url-pattern> 表示请求地址必须以.html结尾才会拦截到
注意:
① 后缀名可以自己设定,例如:<url-pattern>*.abc</url-pattern>
② 后缀名不要以斜杠 / 开头,若以斜杠开头会报错
java.lang.IllegalArgumentException: 过滤器映射中的<url-pattern> [/*.abc] 无效
③ Filter过滤器值关心请求的地址受否匹配,不关心请求的资源是否存在
ThreadLocal
它可以解决多线程的数据安全问题。
ThreadLocal 它可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)
特点:
- ThreadLocal 可以为当前线程关联一个数据。(它可以像 Map 一样存取数据,key 为当前线程)
- 每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例。
- 每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型
- ThreadLocal 中保存数据,在线程销毁后。会由 JVM 虚拟自动释放。
JSON&Ajax详解
练习题
在jsp页面中输出九九乘法口诀表
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>a</title>
</head>
<body>
<h1>九九乘法表</h1>
<table>
<%
for (int i = 1; i <= 9; i++) { %>
<%-- 外层循环遍历行 --%>
<tr>
<%-- 外层循环遍历单元格 --%>
<% for (int j = 1; j <= i; j++) { %>
<td><%= j + "x" + i + "=" + (i * j)%>
</td>
<% } %>
</tr>
<% }
%>
</table>
</body>
</html>
jsp输出一个表格,里面有10个学生信息
创建student实体类
public class Student {
private Integer id;
private String name;
private Integer age;
private String phone;
public Student() {
}
public Student(Integer id, String name, Integer age, String phone) {
this.id = id;
this.name = name;
this.age = age;
this.phone = phone;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", phone='" + phone + '\'' +
'}';
}
}
StudentSearchServlet程序
public class StudentSearchServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数
//发 sql 语句查询学生信息
//使用for循环生成查询到的结果做模拟
List<Student> students = new ArrayList<Student>();
for (int i = 0; i < 10; i++) {
int t = i + 1;
students.add(new Student(t, "name" + t, 18 + t, "phone" + t));
}
//保存查询到的结果 到 request 域中
req.setAttribute("studentList",students);
//请求转发 到 showStudent.jsp 页面
req.getRequestDispatcher("/a.jsp").forward(req,resp);
}
}
web.xml
<servlet>
<servlet-name>StudentSearchServlet</servlet-name>
<servlet-class>alva.servlet.StudentSearchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentSearchServlet</servlet-name>
<url-pattern>/student</url-pattern>
</servlet-mapping>
先运行b.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>test2</title>
</head>
<body>
<a href="http://localhost:8099/server/student">搜索</a>
</body>
</html>
a.jsp展示表格
<%@ page import="alva.pojo.Student" %>
<%@ page import="java.util.List" %>
<%--
Created by IntelliJ IDEA.
User: ASUS9
Date: 2022/11/24
Time: 18:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生信息</title>
<style type="text/css">
table{
border: 1px blue solid;
width: 600px;
border-collapse: collapse;
}
td,tr,th{
border: 1px blue solid;
}
</style>
</head>
<body>
<%
List<Student> students = (List<Student>) request.getAttribute("studentList");
%>
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>电话</th>
<th>操作</th>
</tr>
<%for (Student student : students) {%>
<tr align="center">
<td><%=student.getId()%></td>
<td><%=student.getName()%></td>
<td><%=student.getAge()%></td>
<td><%=student.getPhone()%></td>
<td>
<a href="">删除</a>
<a href="">修改</a>
</td>
</tr>
<% } %>
</table>
</body>
</html>
遍历List集合---list中存放Student类,有属性:编号,用户名,密码,年龄,电话信息
student类
public class Student{
//4.编号,用户名,密码,年龄,电话信息
private Integer id;
private String username;
private String password;
private Integer age;
private String phone;
}
<%--4.遍历List集合---list中存放Student类,有属性:编号,用户名,密码,年龄,电话信息--%>
<%
List<Student> studentList = new ArrayList<Student>();
for(inti=1;i<=10;i++){
studentList.add(new Student(i,"username"+i,"pass"+i,18+i,"phone"+i));
}
request.setAttribute("stus",studentList);
%>
<table>
<tr>
<th>编号</th>
<th>用户名</th>
<th>密码</th>
<th>年龄</th>
<th>电话</th>
<th>操作</th>
</tr>
<%--items表示遍历的集合var表示遍历到的数据begin表示遍历的开始索引值end表示结束的索引值step属性表示遍历的步长值varStatus属性表示当前遍历到的数据的状态for(inti=1;i<10;i+=2)--%>
<c:forEach begin="2" end="7" step="2" varStatus="status" items="${requestScope.stus}" var="stu">
<tr>
<td>${stu.id}</td>
<td>${stu.username}</td>
<td>${stu.password}</td>
<td>${stu.age}</td>
<td>${stu.phone}</td>
<td>${status.step}</td>
</tr>
</c:forEach>
</table>
编写JSP程序,在当前web应用目录下创建文件夹abc,并在该文件夹下创建文本文件”cba.txt”
<%@ page language="java" contentType="text/html; charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>创建文件和文件夹</title>
</head>
<body>
<%
String path = request.getRealPath("/");
String abc_path = path+"abc";
File fp1 = new File(abc_path);
fp1.mkdir();
File fp2 = new File(abc_path,"cba.txt");
fp2.createNewFile();
%>
<center>
创建了文件夹abc:<br>
并在该文件夹下创建了文件cba.txt<br>
</center>
</body>
</html>
习题(错题分享)
选择
1. web是动态的,而非静态
2. JSP中的不是隐式注释为( A )
- A.<!—注释内容-->
- B.<%--注释内容--%>
- C. // 注释内容
- D. /* 注释内容 */
-
Html注释,该注释可以通过查看源代码看到
3. 在inc.jsp中包含数行代码与一张图片,现在要创建一个home.jsp,每次浏览home.jsp时都能够以最快的速度显示inc.jsp中的所有内容以及home.jsp自身要显示的内容,应该在home.jsp中使用的语句是( c )
- A.<% @ include page = “inc.jsp”%>
- B.<jsp:forward page = “inc.jsp”/>
- C.<% @ include file = “inc.jsp”%>
- D.<jsp:include file = “inc.jsp”flush = “false”>
Jsp:include 里面的是page,@include里面的才是file
4. 对于预定义<%!预定义%>的说法错误的是( D )
- A.在预定义中声明的变量将在JSP页面初始化时初始化
- B.一次可声明多个变量和方法,只要以“;”结尾就行
- C.一个声明仅在一个页面中有效
- D.声明的变量将作为局部变量
5. 在JSP中,只有一行代码:<%=’A’+’B’%>,运行将输出( A )
- A. 131
- B.A+B
- C.错误信息,因为表达式是错误的
- D.AB
-
单引号是ASCII 双引号是字符
-
6. “java”是当前唯一可用的JSP语言
7. 下面哪一个不是JSP本身已加载的基本类?( )
- A.java.lang.*
- B.javax.servlet.*
- C.java.io.*
- D.javax.servlet.jsp.*
8. 对该段代码描述错误的有<% int i = Integer. parseInt(requrst.getParemeter(“value”)) %( A)
- A.不会有错
- B.当value与int 类型不匹配时会报错
- C.为了安全起见应该将该段代码放在try{}和catch(){}之间
- D.当value=""时会报错
9. 以下的代码执行过程描述正确的是(C)
out.println("<script>");
out.println("alert('good')");
out.println("</script>");
System.out.println("the servlet info");
out.close();
- A.执行到2的时候会在客户端页面弹出一个对话框,当客户响应过后继续执行下面的代码
- B.执行到2的时候会在客户端页面弹出一个对话框,但是会继续执行下面的代码
- C.执行完上面的所有代码后,客户端才会得到服务器的响应,然后才弹出对话框
- D.以上都不对
10. WEB应用中,常用的会话跟踪方法不包括( C )
- A.隐藏表单域
- B.Cookie
- C.有状态HTTP协议
- D.URL重写
11. pageContext对象创建和初始化都是由容器来完成的
12. 隐藏域在Cookie被禁用或者根本不支持的情况下依旧能够工作
13. servlet 的生命周期又一系列事件组成,把这些事件按照先后顺序排序,以下正确的是(C )
- A.加载类,初始化,实例化,请求处理,销毁
- B.加载类,实例化,请求处理,初始化,销毁
- C.加载类,实例化,初始化,请求处理,销毁
- D.实例化,加载类,初始化,请求处理,销毁
14. 下面哪一项对Servlet描述错误?( C )
- A:Servlet是一个特殊的Java类,它必须直接或间接实现Servlet接口
- B:Servlet接口定义了Servlet的生命周期方法
- C:当多个客户请求一个Servlet时,服务器为每一个客户启动一个进程
- D:Servlet客户线程调用service方法响应客户的请求
Servlet为每个用户启动的是线程,而不是进程
15. 下述选项中不属于JDBC基本功能的是( B )
- A.处理查询结果
- B.数据库维护管理
- C.提交SQL语句
- D.与数据库建立连接
16. DriverManager类的getConnection(String url,String user,String password)方法中,参数url的格式为jdbc:<子协议>:<子名称>,下列哪个url是不正确的?(B )
- A:"jdbc:mysql://localhost:3306/数据库名"
- B:"jdbc:odbc:数据源"
- C:"jdbc:oracle:thin@host:端口号:数据库名"
- D:"jdbc:sqlserver://172.0.0.1:1443;DatabaseName=数据库名"
URL的通常格式为:jdbc:(哪种数据库)://数据库地址:数据库端口号/数据库名字?编码格式
17. 一个taglib指令必须有那些属性( C )
- A.value prefix
- B.uri loaction
- C.uri prefix
- D.uri value
填空
1.用java实现的动态网页,要在tomcat下发布可以直接发布在默认的(_ webapps/ROOT_)目录下。但是我们一般都愿意发布在自己的目录里,这样的目录我们是需要在tomcat里配置的,配置虚拟目录的文件夹是(__conf__)。在这个目录里的(_server.xml_)文里可以配置,在tomcat5.0以后一般都配置在单个的.xml里。这样的.xml里指定虚拟目录的名字的属性是(_path_)
2. 设置错误处理页面:_<%@ page isErrorPage= “true” %>_ 如果当前JSP页面出现异常时需要转到一个异常页,需要设置page 指令_errorPage_属性
3. 当用户请求jsp页面时,JSP引擎就会执行该页面的字节码文件响应客户的请求,执行字节码文件的结果是(_发送一个HTML页面到客户端_)
4. web 容器处理JSP 请求需要经历三个阶段(_翻译_),(_编译_),(_执行_)
5. session对象的(_session.setMaxInactiveInterval(30)_)方法用于设置会话的超时时间
6. 释放session对象时,使用session对象的( _invalidate()_)方法
7. session对象getId方法的作用是(__得客户端在服务器唯一的标识)
8. 理论上,GET是(_用于获取服务器信息并将其作为响应返回给客户端_),POST是 (__用于客户端把数据传送到服务器_)。
9. 在JSP页面中,(__response_)等效于HttpServletResponse
10. 一个Bean由三部分组成:(_实现java.io.serializable接口_)、(_提供无参数的构造方法_)、(_提供getter()和setter()方法访问它的属性_)
11. 在JSP中使用JavaBean的标签是(_<jsp:useBean class=BeanName id=Bean实例>_),其中id的用途是(_实例化一个Bean对象 __) 。
12. Servlet的生命周期分三个时期:(_装载Servlet_)(_创建一个Servlet实例_)(__销毁_)
13. JSP开发网站的两种模式分为(_jsp+javabean_)和(_jsp+javabean+servlet_)。
简答
1. 在jsp 页面输出 hello world 至少三种方式。
- <%=hello world %>
- out.println("hello world ")
- hello world
2. JSP中动态include与静态include的区别?
- 动态包含是在实际用到被包含页面的时候才去加载被包含的页面,包含和被包含页面被编译为2个servlet文件,会检查所含文件中的变化。
- 静态包含是直接把包含的页面信息添加到自己页面,只被编译成一个jsp页面,被包含的页面被编译到包含它的页面中,不会检查所含文件的变化
3. JSP和servlet的异同
相同点:
(1)两者都是基于Java的技术,所以都继承了Java的所有特性(跨平台、多线程等 ),都可以使用Java强大的API。
(2)两者工作方式相似:JSP代码先被JSP容器转换为Servlet代码再编译为类。
(3)两者在J2EE体系结构中的工作层次相同,都负责与客户端的连接。
不同点:
- (1)编程方式不同。Servlet是一些运行于Web服务器端的Java小程序;而JSP是脚本,编写起来更简单容易。
- (2)应用目的不同。Servlet主要用于从客户端接收请求信息,而JSP主要负责将服务器端信息传送 到客户端
4. 数据连接池的工作机制
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接