一. Tomcat
1.JavaWeb 的概念
a)什么是 JavaWeb
-
JavaWeb 是指,所有通过 Java 语言编写可以通过浏览器访问的程序的总称,叫 JavaWeb。
-
JavaWeb 是基于请求和响应来开发的。
b)什么是请求
- 请求是指客户端给服务器发送数据,叫请求 Request
c)什么叫向响应?
- 响应是指服务器给客户端回传数据,叫响应 Response。
d) 请求和响应的关系
请求和响应是成对出现的,有请求就有响应。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZkqaXYq-1658127148122)(D:\photo\10.jpg)]
2.Web资源的分类
web 资源按实现的技术和呈现的效果的不同,又分为静态资源和动态资源两种。
-
静态资源: html、css、js、txt、mp4 视频 , jpg 图片
-
动态资源: jsp 页面、Servlet 程序
3. 常用的 Web 服务器
-
Tomcat:由 Apache 组织提供的一种 Web 服务器,提供对 jsp 和 Servlet 的支持。它是一种轻量级的 javaWeb 容器(服务器),也是当前应用最广的 JavaWeb 服务器(免费)。
-
Jboss:是一个遵从 JavaEE 规范的、开放源代码的、纯 Java 的 EJB 服务器,它支持所有的 JavaEE 规范(免费)。
-
GlassFish:由 Oracle 公司开发的一款 JavaWeb 服务器,是一款强健的商业服务器,达到产品级质量(应用很少)。
-
Resin:是 CAUCHO 公司的产品,是一个非常流行的服务器,对 servlet 和 JSP 提供了良好的支持,性能也比较优良,resin 自身采用 JAVA 语言开发(收费,应用比较多)。
-
WebLogic:是 Oracle 公司的产品,是目前应用最广泛的 Web 服务器,支持 JavaEE 规范,而且不断的完善以适应新的开发要求,适合大型项目(收费,用的不多,适合大公司)。
二.Servlet技术
1.什么是Servlet?
- Servlet就是JavaEE规范之一,规范就是接口。
- Servlet就是JavaWeb三大组件之一。三大组件分别是:Servlet程序,Filter过滤器,Listener监听器。
- Servlet就是运行在服务器上的一个java小程序,它可以接收客户端发来的请求,并响应数据给客户端。
2.手动实现Servlet程序
- 编写一个类去实现 Servlet 接口
- 实现 service 方法,处理请求,并响应数据
- 到 web.xml 中去配置 servlet 程序的访问地址
Servlet 程序的示例代码:
public class HelloServlet implements Servlet {
/**
* service 方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse)throwsServletException, IOException {
System.out.println("Hello Servlet 被访问了");
}
}
3.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>com.atguigu.servlet.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>
4.url到到Servlet程序的访问
5.Servlet的生命周期
- 第一步、执行Servlet构造器方法
- 第二步、执行Servlet的init方法
- 第一、二步,是在第一次访问,的时候创建 Servlet 程序会调用。
- 第三步、执行 service 方法
- 第三步,每次访问都会调用。
- 第四步、执行 destroy 销毁方法
- 第四步,在 web 工程停止的时候调用。
6.通过继承 HttpServlet 实现 Servlet 程序
一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。
- 编写一个类去继承 HttpServlet 类
- 根据业务需要重写 doGet 或 doPost 方法
- 到 web.xml 中的配置 Servlet 程序的访问地址 Servlet 类的代码:
public class HelloServlet2 extends HttpServlet {
/**
* doGet()在get请求的时候调用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/ @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
System.out.println("HelloServlet2 的doGet方法");
}
/**
* doPost()在post请求的时候调用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/ @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
System.out.println("HelloServlet2 的doPost方法");
}
}
web.xml 中的配置:
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
7. Servlet 类的继承体系
三. ServletContext 类
-
ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。
-
Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。
-
Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象。
1.ServletConfig类的三大作用
- 可以获取 Servlet 程序的别名 servlet-name 的值
- 获取初始化参数 init-param
- 获取 ServletContext 对象 web.xml 中的配置
2. ServletContext 类
**a)**什么是 ServletContext?
-
ServletContext 是一个接口,它表示 Servlet 上下文对象
-
一个 web 工程,只有一个 ServletContext 对象实例。
-
ServletContext 对象是一个域对象。
-
ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。
b)什么是域对象?
域对象,是可以像 Map 一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围,整个 web 工程。
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute(); |
c)servletContext 类的四个作用
1、获取 web.xml 中配置的上下文参数 context-param
2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像 Map 一样存取数据
3.HTTP 协议
a) 什么是 HTTP 协议
什么是协议?
- 协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
- 所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。
- HTTP 协议中的数据又叫报文
**b)**请求的 HTTP 协议格式
-
客户端给服务器发送数据叫请求。服务器给客户端回传数据叫响应。
-
请求又分为 GET 请求,和 POST 请求两种
i、 GET请求
1、请求行
(1) 请求的方式 GET
(2) 请求的资源路径[+?+请求参数]
(3) 请求的协议的版本号 HTTP/1.1
2、请求头 key : value 组成 不同的键值对,表示不同的含义。
ii. POST 请求
1、请求行
(1) 请求的方式 POST
(2) 请求的资源路径[+?+请求参数]
(3) 请求的协议的版本号 HTTP/1.1
2、请求头
- key : value 不同的请求头,有不同的含义空行
3、请求体 ===>>> 就是发送给服务器的数据
iii. 常用请求头的说明
Accept: 表示客户端可以接收的数据类型
Accpet-Languege: 表示客户端可以接收的语言类型
User-Agent: 表示客户端浏览器的信息 Host:表示请求时的服务器 ip 和端口号
iii. 哪些是 GET 请求,哪些是 POST 请求
GET 请求有哪些:
- form 标签 method=get
- a 标签
- link 标签引入 css
- Script 标签引入 js 文件
- img 标签引入图片
- iframe 引入 html 页面
- 在浏览器地址栏中输入地址后敲回车
POST 请求有哪些:
- form 标签 method=post
c)**响应的 **HTTP协议格式
1、响应行
(1) 响应的协议和版本号
(2) 响应状态码
(3) 响应状态描述符
2、响应头
(1) key : value 不同的响应头,有其不同含义空行
3、响应体 ---->>> 就是回传给客户端的数据
d)常用的响应码说明
-
200 表示请求成功
-
302 表示请求重定向
-
404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
-
500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
四.HttpServletRequest 类
1.HttpServletRequest 类有什么作用。
每次只要有请求进入 服务器,服务器就会把请求过来的 协议信息解析好封装到 对象中。然后传递到 方法(和 )中给我们使用。我们可以通过 对象,获取到所有请求的信息。
2. HttpServletRequest 类的常用方法
getRequestURI() | 获取请求的资源路径 |
---|---|
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
i getRemoteHost() | 获取客户端的ip地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数(多个值的时候使用) |
getMethod() | 获取请求的方式GET或POST |
setAttribute(key, value); | 设置域数据 |
getAttribute(key); | 获取域数据 |
getRequestDispatcher() | 获取请求转发对象 |
常用api实例代码
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// i.getRequestURI() 获取请求的资源路径
System.out.println("URI => " + req.getRequestURI());
// ii.getRequestURL() 获取请求的统一资源定位符(绝对路径)
System.out.println("URL => " + req.getRequestURL());
// iii.getRemoteHost() 获取客户端的ip地址
/**
<br/>
<br/>
* 在IDEA中,使用localhost访问时,得到的客户端ip 地址是===>>> 127.0.0.1
* 在IDEA中,使用127.0.0.1访问时,得到的客户端ip 地址是===>>> 127.0.0.1
<br/>
* 在IDEA中,使用真实ip 访问时,得到的客户端ip 地址是===>>> 真实的客户端ip 地址
*/
System.out.println("客户端 ip地址 => " + req.getRemoteHost());
// iv.getHeader() 获取请求头
System.out.println("请求头User-Agent ==>> " + req.getHeader("User-Agent"));
//
}
} vii.getMethod() 获取请求的方式GET或POST
System.out.println( "请求的方式 ==>> " + req.getMethod() );
3. 如何获取请求参数表单:
<body>
form action="http://localhost:8080/07_servlet/parameterServlet" 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>
<
</
</body>
java代码
public class ParameterServlet 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));
}
}
4doGet请求中的乱码解决问题
// 获取请求参数
String username = req.getParameter("username");
//1 先以iso8859-1进行编码
//2 再以utf-8进行解码
username = new String(username.getBytes("iso-8859-1"), "UTF-8");
doPost请求中的中文乱码问题
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题
req.setCharacterEncoding("UTF-8");
System.out.println("-------------doPost------------");
// 获取请求参数
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));
}
5.请求的转发
什么是请求的转发? 请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。
Sevlet1代码
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料):" + username);
// 给材料盖一个章,并传递到Servlet2(柜台2)去查看
req.setAttribute("key1","柜台1的章");
// 问路:Servlet2(柜台2)怎么走
/**
请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA代码的web目录
**/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
// 走向Sevlet2(柜台2)
requestDispatcher.forward(req,resp);
}
}
Sevlet2代码
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料):" + username);
// 查看柜台1 是否有盖章
Object key1 = req.getAttribute("key1");
System.out.println("柜台1是否有章:" + key1);
// 处理自己的业务
System.out.println("Servlet2 处理自己的业务 "); }
}
6.base标签的作用
7.Web 中的相对路径和绝对路径
-
在 javaWeb 中,路径分为相对路径和绝对路径两种:
- 相对路径是:
. 表示当前目录 表示当前目录 … 表示上一级目录 表示上一级目录 资源名 表示当前目录/资源名 表示当前目录/资源名 - 绝对路径:
http://ip:port/工程路径/资源路径
-
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。
1、 绝对路径 2、 base+相对
8. web 中 / 斜杠的不同意义
在 web 中 / 斜杠是一种绝对路径。
/ 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
<a href="/">斜杠</a>
/ 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
例如:<url-pattern>/servlet1</url-pattern>
servletContext.getRealPath(“/”);
request.getRequestDispatcher(“/”);
特殊情况: response.sendRediect(“/”);
把斜杠发送给浏览器解析。得到http://ip:port/
五. HttpServletResponse 类
1.HttpServletResponse 类的作用
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置
2. 两个输出流的说明。
字节流 | getOutputStream(); |
---|---|
字符流 | getWriter(); |
- 两个流同时只能使用一个
- 使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
3. 如何往客户端回传数据要求:往客户端回传字符串数据。
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 要求:往客户端回传字符串数据。
PrintWriter writer = resp.getWriter();
writer.write("response's content!!!");
}
}
4. 响应的乱码解决 :
解决响应中文乱码方案一(不推荐使用):
// 设置服务器字符集为UTF-8
resp.setCharacterEncoding("UTF-8");
// 通过响应头,设置浏览器也使用UTF-8字符集
resp.setHeader("Content-Type", "text/html; charset=UTF-8");
解决响应中文乱码方案二(推荐):
// 它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html; charset=UTF-8");
5. 请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)。
请求重定向的第一种方案:
// 设置响应状态码302 ,表示重定向,(已搬迁)
resp.setStatus(302);
// 设置响应头,说明新的地址在哪里
resp.setHeader("Location", "http://localhost:8080");
请求重定向的第二种方案(推荐使用):
resp.sendRedirect("http://localhost:8080");
六.JavaEE的三层架构
- 分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
七.文件的上传和下载
文件的上传和下载,是非常常见的功能。很多的系统中,或者软件中都经常使用文件的上传和下载。
-
比如:QQ 头像,就使用了上传。
-
邮箱中也有附件的上传和下载功能。
-
OA 系统中审批有附件材料的上传。
1.文件的上传介绍
- 要有一个form标签,method=post请求
- form标签的encType属性值必须为multipart/form-data值、
- 在form标签中使用input type=file添加上传的文件
- 编写服务器代码(Servlet程序)接收,处理上传的数据。
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器
1.1、 文件上传,HTTP 协议的说明。
1.2** commons-fileupload.jar 常用 API 介绍说明
commons-fileupload.jar 需要依赖 commons-io.jar 这个包,所以两个包我们都要引入。
- 第一步,就是需要导入两个 jar 包: commons-fileupload-1.2.1.jar commons-io-1.4.jar
- commons-fileupload.jar** 和 commons-io.jar 包中,我们常用的类有哪些?
public List parseRequest(HttpServletRequest request) | 解析上传的数据 |
---|---|
boolean FileItem.isFormField() 判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。 | true 表示普通类型的表单项 false 表示上传的文件类型 |
String FileItem.getFieldName() | 获取表单项的name属性值 |
String FileItem.getString() | 获取当前表单项的值。 |
String FileItem.getName() | 获取上传的文件名 |
void FileItem.write( file ) | 将上传的文件写到参数file 所指向抽硬盘位置。 |
ServletFileUpload类 | ,用于解析上传的数据。 |
FileItem 类 | ,表示每一个表单项。 |
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request); | 判断当前上传的数据格式是否是多段的格式。 |
1.3、fileupload 类库的使用:
<form action="http://192.168.31.74:8080/09_EL_JSTL/uploadServlet" method="post"
enctype="multipart/form-data">
用户名:<input type="text" name="username" />
头像: <input type="file" name="photo" >
<input type="submit" value="上传">
</form>
解析上传的数据的代码:
/**
* 用来处理上传的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/ @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
//1 先判断上传的数据是否多段数据(只有是多段的数据,才是文件上传的)
if (ServletFileUpload.isMultipartContent(req)) {
// 创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
// 创建用于解析上传数据的工具类ServletFileUpload类
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
try {
// 解析上传的数据,得到每一个表单项FileItem
List<FileItem> list = servletFileUpload.parseRequest(req);
// 循环判断,每一个表单项,是普通类型,还是上传的文件
for (FileItem fileItem : list) {
if (fileItem.isFormField()) {
// 普通表单项
System.out.println("表单项的name属性值:" + fileItem.getFieldName());
// 参数UTF-8.解决乱码问题
System.out.println("表单项的value属性值:" + fileItem.getString("UTF-8"));
} else {
// 上传的文件
System.out.println("表单项的name属性值:" + fileItem.getFieldName()); System.out.println("上传 的文件名:" + fileItem.getName());
fileItem.write(new File("e:\\" + fileItem.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. 文件下载
如果客户端浏览器是IE浏览器或者是谷歌浏览器。我们需要使用URLEncoder类先对中文名进行UTF-8的编码
操作。因为IE浏览器和谷歌浏览器收到含有编码后的字符串后会以UTF-8字符集进行解码显示。
// UTF-8
String str = "attachment; fileName=" + URLEncoder.*encode*("中文.jpg", "UTF-8");
// 然后把编码后的字符串设置到响应头中
response.setHeader("Content-Disposition", str);
BASE64编解码操作:
因为火狐使用的是BASE64的编解码方式还原响应中的汉字。所以需要使用BASE64Encoder类进行编码操作。
// 使用下面的格式进行BASE64编码后
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
// 设置到响应头中
response.setHeader("Content-Disposition", str);
那么我们如何解决上面两种不同编解码方式呢。我们只需要通过判断请求头中User-Agent这个请求头携带过来的
浏览器信息即可判断出是什么浏览器。
如下:
String ua = request.getHeader("User-Agent");
// 判断是否是火狐浏览器
if (ua.contains("Firefox")) {
// 使用下面的格式进行BASE64编码后
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
// 设置到响应头中
response.setHeader("Content-Disposition", str);
} else {
// 把中文名进行UTF-8编码操作。
String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
// 然后把编码后的字符串设置到响应头中
response.setHeader("Content-Disposition", str);
}
八.cokkie
1.什么是 Cookie?
-
Cookie 翻译过来是饼干的意思。
-
Cookie 是服务器通知客户端保存键值对的一种技术。
-
客户端有了 Cookie 后,每次请求都发送给服务器。
-
每个 的大小不能超过 4kb
protectedvoidcreateCookie(HttpServletRequestreq,HttpServletResponseresp)throwsServletException, IOException {
//1 创建Cookie对象
Cookie cookie = new Cookie("key4", "value4");
//2 通知客户端保存Cookie
resp.addCookie(cookie);
//1 创建Cookie对象
Cookie cookie1 = new Cookie("key5", "value5");
//2 通知客户端保存Cookie
resp.addCookie(cookie1);
resp.getWriter().write("Cookie创建成功");
}
2.服务器如何获取 Cookie
- 服务器获取客户端的 Cookie 只需要一行代码:req.getCookies():Cookie[]
Cookie 的工具类:
public class CookieUtils {
/**
* 查找指定名称的Cookie对象
* @param name
* @param cookies
* @return
*/ public static Cookie findCookie(String name , Cookie[] cookies){ if (name == null || cookies == null || cookies.length == 0) { return null;
}
for (Cookie cookie : cookies) { if (name.equals(cookie.getName())) { return cookie;
} }
return null;
}
}
Servlet 程序中的代码:
protectedvoidgetCookie(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,
IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
// getName方法返回Cookie的key(名) // getValue方法返回Cookie的value值
resp.getWriter().write("Cookie["+cookie.getName()+"="+cookie.getValue()+"]<br/>");
}
Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
// for (Cookie cookie : cookies) {
// if ("key2".equals(cookie.getName())) {
// iWantCookie = cookie;
// break;
// }
// }
// 如果不等于null,说明赋过值,也就是找到了需要的Cookie
if (iWantCookie != null) { resp.getWriter().write("找到了需要的Cookie"); }
}
3. Cookie 值的修改
// 方案一:
// 1、先创建一个要修改的同名的Cookie对象
// 2、在构造器,同时赋于新的Cookie值。
Cookie cookie = new Cookie("key1","newValue1");
// 3、调用response.addCookie( Cookie ); 通知客户端保存修改 resp.addCookie(cookie);
// 方案二:
// 1、先查找到需要修改的Cookie对象
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies()); if (cookie != null) {
// 2、调用setValue()方法赋于新的Cookie值。
cookie.setValue("newValue2");
// 3、调用response.addCookie()通知客户端保存修改 resp.addCookie(cookie);
}
4. Cookie 生命控制
-
Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)
-
setMaxAge()
-
正数,表示在指定的秒数后过期
-
负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)零,表示马上删除 Cookie
-
/** * 设置存活1个小时的Cooie * @param req * @param resp * @throws ServletException * @throws IOException */ protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie("life3600", "life3600"); cookie.setMaxAge(60 * 60); // 设置Cookie一小时之后被删除。无效 resp.addCookie(cookie); resp.getWriter().write("已经创建了一个存活一小时的Cookie"); } /** * 马上删除一个Cookie * @param req * @param resp * @throws ServletException * @throws IOException */ protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 先找到你要删除的Cookie对象 Cookie cookie = CookieUtils.findCookie("key4", req.getCookies()); if (cookie != null) { // 调用setMaxAge(0); cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭 // 调用response.addCookie(cookie); resp.addCookie(cookie); resp.getWriter().write("key4的Cookie已经被删除"); } } /** * 默认的会话级别的Cookie * @param req * @param resp * @throws ServletException * @throws IOException */ protectedvoiddefaultLife(HttpServletRequestreq,HttpServletResponseresp)throwsServletException, IOException { Cookie cookie = new Cookie("defalutLife","defaultLife"); cookie.setMaxAge(-1);//设置存活时间 resp.addCookie(cookie); }
5. Cookie 有效路径 Path 的设置
-
Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器。哪些不发。
- path 属性是通过请求的地址来进行有效的过滤。
- CookieA path=/工程路径 CookieB path=/工程路径/abc
-
请求地址如下:
-
http://ip:port/工程路径/a.html
- CookieA 发送
- CookieB 不发送
-
http://ip:port/工程路径/abc/a.html
- CookieA 发送
- CookieB 发送
protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie("path1", "path1"); // getContextPath() ===>>>> 得到工程路径 cookie.setPath( req.getContextPath() + "/abc" ); // ===>>>> resp.addCookie(cookie); resp.getWriter().write("创建了一个带有Path路径的Cookie"); } /工程路径/abc
-
-
九. Session 会话
1. 什么是 Session 会话**?**
- Session 就一个接口(HttpSession)。
- Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。
- 每个客户端都有自己的一个 Session 会话。
- Session 会话中,我们经常用来保存用户登录之后的信息。
2. 如何创建 Session 和获取(id 号,是否为新)
如何创建和获取 Session。它们的 API 是一样的。
- request.getSession()
第一次调用是:创建 Session 会话之后调用都是:获取前面创建好的 Session 会话对象。
- isNew(); 判断到底是不是刚创建出来的(新的) true 表示刚创建,false 表示获取之前创建。
每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。
- getId() 得到 Session 的会话 id 值。
3. Session 域数据的存取
/**
* 往Session中保存数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/ protectedvoidsetAttribute(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,
IOException { req.getSession().setAttribute("key1", "value1"); resp.getWriter().write("已经往Session中保存了数据");
}
/**
* 获取Session域中的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/ protectedvoidgetAttribute(HttpServletRequestreq,HttpServletResponseresp)throwsServletException, IOException {
Object attribute = req.getSession().getAttribute("key1"); resp.getWriter().write("从Session中获取出key1的数据是:" + attribute); }
4.Session 生命周期控制
public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁。
-
值为正数的时候,设定 Session 的超时时长。负数表示永不超时(极少使用)
-
public int getMaxInactiveInterval()获取 Session 的超时时间
-
public void invalidate() 让当前 Session 会话马上超时无效。
Session 默认的超时时长是多少!
- Session 默认的超时时间长为 30 分钟。因为在 Tomcat 服务器的配置文件 web.xml 中默认有以下的配置,它就表示配置了当前 Tomcat 服务器下所有的 Session
超时配置默认时长为:30 分钟。
超时配置默认时长为:30 分钟。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
如果说。你希望你的 web 工程,默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做
以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长。
<session-config>
<session-timeout>20</session-timeout>
</session-config>
如果你想只修改个别 Session 的超时时长。就可以使用上面的 API。setMaxInactiveInterval(int interval)来进行单独的设置。 session.setMaxInactiveInterval(int interval)单独设置超时时长。
Session 超时的概念介绍:
示例代码:
protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 先获取Session对象
HttpSession session = req.getSession();
// 设置当前Session3秒后超时
session.setMaxInactiveInterval(3);
resp.getWriter().write("当前Session已经设置为3秒后超时");
}
Session 马上被超时示例:
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 先获取Session对象
HttpSession session = req.getSession();
// 让Session会话马上超时
session.invalidate();
resp.getWriter().write("Session已经设置为超时(无效)"); }
5. 浏览器和 Session 之间关联的技术内幕
Session 技术,底层其实是基于 Cookie 技术来实现的
十 -Filter 过滤器
1、Filter 什么是过滤器
- Filter 过滤器它是 JavaWeb 的三大组件之一。三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器
- Filter 过滤器它是 JavaEE 的规范。也就是接口
- Filter 过滤器它的作用是:拦截请求,过滤响应。
拦截请求常见的应用场景有:
1、权限检查
2、日记操作
3、事务管理
…等等
2. Filter
要求:在你的 web 工程下,有一个 admin 目录。这个 admin 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必须是用户登录之后才允许访问。
思考:根据之前我们学过内容。我们知道,用户登录之后都会把用户登录的信息保存到 Session 域中。所以要检查用户是否登录,可以判断 Session 中否包含有用户登录的信息即可!!!
Filter 的工作流程图:
Filter 的代码:
public class AdminFilter implements Filter {
/**
* doFilter方法,专门用于拦截请求。可以做权限检查
*/ @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");
// 如果等于null,说明还没有登录
if (user == null) {
servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse); return;
} else {
// 让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
}
Filter 过滤器的使用步骤:
- 编写一个类去实现 Filter 接口
- 实现过滤方法 doFilter()
- 到 web.xml 中去配置 Filter 的拦截路径
3. Filter 的生命周期
Filter 的生命周期包含几个方法
1、构造器方法
2、init 初始化方法
第 1,2 步,在 web 工程启动的时候执行(Filter 已经创建)
3、doFilter 过滤方法
第 3 步,每次拦截到请求,就会执行
4、destroy 销毁
第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)
4. FilterConfig 类
FilterConfig 类见名知义,它是 Filter 过滤器的配置文件类。
Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息。
FilterConfig 类的作用是获取 filter 过滤器的配置内容
- 获取 Filter 的名称 filter-name 的内容
- 获取在 Filter 中配置的 init-param 初始化参数
- 获取 ServletContext 对象
java 代码:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("2.Filter的init(FilterConfig filterConfig)初始化");
// 1、获取Filter的名称filter-name的内容
System.out.println("filter-name的值是:" + filterConfig.getFilterName());
// 2、获取在web.xml中配置的init-param初始化参数
System.out.println("初始化参数username的值是:"+filterConfig.getInitParameter("username")); System.out.println("初始化参数url的值是:" + filterConfig.getInitParameter("url"));
// 3、获取ServletContext对象
System.out.println(filterConfig.getServletContext()); }
5. FilterChain 过滤器链
- Filter 过滤器
- Chain 链,链条
FilterChain 就是过滤器链(多个过滤器如何一起工作)
6、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>*.do</url-pattern>
以上配置的路径,表示请求地址必须以.do 结尾才会拦截到
<url-pattern>*.action</url-pattern>
以上配置的路径,表示请求地址必须以.action 结尾才会拦截到
- Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!
十一. json在javaScript中的使用
1.什么是json
- JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C, C++, C#, Java, JavaScript,Perl,Python等)。 这样就使得 JSON 成为理想的数据交换格式。
- json 是一种轻量级的数据交换格式。
- 轻量级指的是跟 xml 做比较。
- 数据交换指的是客户端和服务器之间业务数据的传递格式。
1.1、JSON 在 JavaScript 中的使用
1.1.1、json 的定义
json 是由键值对组成,并且由花括号(大括号)包围。每个键由引号引起来,键和值之间使用冒号进行分隔,多组键值对之间进行逗号进行分隔。
json 定义示例:
var jsonObj = {
"key1":12,
"key2":"abc",
"key3":true,
"key4":[11,"arr",false],
"key5":{
"key5_1" : 551,
"key5_2" : "key5_2_value"
},
"key6":[{
"key6_1_1":6611,
"key6_1_2":"key6_1_2_value"
},{
"key6_2_1":6621,
"key6_2_2":"key6_2_2_value"
}]
};
1.1.2、json 的访问
json 本身是一个对象。
json 中的 key 我们可以理解为是对象中的一个属性。
json 中的 key 访问就跟访问对象的属性一样: json 对象.key
json 访问示例:
alert(typeof(jsonObj));// object json 就是一个对象
alert(jsonObj.key1); //12
alert(jsonObj.key2); // abc
alert(jsonObj.key3); // true
alert(jsonObj.key4);// 得到数组[11,"arr",false]
// json 中 数组值的遍历
for(var i = 0; i < jsonObj.key4.length; i++) {
alert(jsonObj.key4[i]);
}
alert(jsonObj.key5.key5_1);//551
alert(jsonObj.key5.key5_2);//key5_2_value
alert( jsonObj.key6 );// 得到 json 数组
// 取出来每一个元素都是 json 对象
var jsonItem = jsonObj.key6[0];
// alert( jsonItem.key6_1_1 ); //6611
alert( jsonItem.key6_1_2 ); //key6_1_2_value
1.1.3、json 的两个常用方法 json 的存在有两种形式。
- 一种是:对象的形式存在,我们叫它 json 对象。
- 一种是:字符串的形式存在,我们叫它 json 字符串。
- 一般我们要操作 json 中的数据的时候,需要 json 对象的格式。
- 一般我们要在客户端和服务器之间进行数据交换的时候,使用 json 字符串。
- JSON.stringify() 把 json 对象转换成为 json 字符串 JSON.parse() 把 json 字符串转换成为 json 对象
示例代码:
// 把 json 对象转换成为 json 字符串
var jsonObjString = JSON.stringify(jsonObj); // 特别像 Java 中对象的 toString
alert(jsonObjString)
// 把 json 字符串。转换成为 json 对象
var jsonObj2 = JSON.parse(jsonObjString);
alert(jsonObj2.key1);// 12
alert(jsonObj2.key2);// abc
1.2、JSON 在 java 中的使用
1.2.1、javaBean 和 json 的互转
@Test
public void test1(){
Person person = new Person(1,"国哥好帅!");
// 创建 Gson 对象实例
Gson gson = new Gson();
// toJson 方法可以把 java 对象转换成为 json 字符串
String personJsonString = gson.toJson(person);
System.out.println(personJsonString);
// fromJson 把 json 字符串转换回 Java 对象
// 第一个参数是 json 字符串
// 第二个参数是转换回去的 Java 对象类型
Person person1 = gson.fromJson(personJsonString, Person.class);
System.out.println(person1);
}
1.2.2、List 和 json 的互转
// 1.2.2、List 和 json 的互转
@Test
public void test2() {
List<Person> personList = new ArrayList<>();
personList.add(new Person(1, "国哥"));
personList.add(new Person(2, "康师傅"));
Gson gson = new Gson();
// 把 List 转换为 json 字符串
String personListJsonString = gson.toJson(personList);
System.out.println(personListJsonString);
List<Person> list = gson.fromJson(personListJsonString, new PersonListType().getType());System.out.println(list);
Person person = list.get(0);
System.out.println(person);
}
1.2.3、map 和 json 的互转
// 1.2.3、map 和 json 的互转
@Test
public void test3(){
Map<Integer,Person> personMap = new HashMap<>();
personMap.put(1, new Person(1, "国哥好帅"));
personMap.put(2, new Person(2, "康师傅也好帅"));
Gson gson = new Gson();
// 把 map 集合转换成为 json 字符串
String personMapJsonString = gson.toJson(personMap);
System.out.println(personMapJsonString);
// Map<Integer,Person> personMap2 = gson.fromJson(personMapJsonString, new
PersonMapType().getType());
Map<Integer,Person> personMap2 = gson.fromJson(personMapJsonString, new
TypeToken<HashMap<Integer,Person>>(){}.getType());
System.out.println(personMap2);
Person p = personMap2.get(1);
System.out.println(p);
}
十二 .AJAX 请求
1、什么是 AJAX 请求
AJAX 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
- ajax 是一种浏览器通过 js 异步发起请求,局部更新页面的技术。
- Ajax 请求的局部更新,浏览器地址栏不会发生变化 局部更新不会舍弃原来页面的内容
2. 原生 AJAX 请求的示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
// 在这里使用 javaScript 语言发起 Ajax 请求,访问服务器 AjaxServlet 中javaScriptAjaxfunction ajaxRequest() {
// 1、我们首先要创建 XMLHttpRequest
var xmlhttprequest = new XMLHttpRequest();
// 2、调用 open 方法设置请求参数
xmlhttprequest.open("GET","http://localhost:8080/16_json_ajax_i18n/ajaxServlet?action=javaScriptAjax",true)
// 4、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。xmlhttprequest.onreadystatechange = function(){
if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200)
{var jsonObj = JSON.parse(xmlhttprequest.responseText);
// 把响应的数据显示在页面上
document.getElementById("div01").innerHTML = "编号:" + jsonObj.id+",姓名:"+jsonObj.name;
}
}
// 3、调用 send 方法发送请求
xmlhttprequest.send();
}
</script>
</head>
<body>
<button onclick="ajaxRequest()">ajax request</button>
<div id="div01">
</div>
</body>
</html>
ipt 和 XML),是指一种创建交互式网页应用的网页开发技术。
- ajax 是一种浏览器通过 js 异步发起请求,局部更新页面的技术。
- Ajax 请求的局部更新,浏览器地址栏不会发生变化 局部更新不会舍弃原来页面的内容
2. 原生 AJAX 请求的示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
// 在这里使用 javaScript 语言发起 Ajax 请求,访问服务器 AjaxServlet 中javaScriptAjaxfunction ajaxRequest() {
// 1、我们首先要创建 XMLHttpRequest
var xmlhttprequest = new XMLHttpRequest();
// 2、调用 open 方法设置请求参数
xmlhttprequest.open("GET","http://localhost:8080/16_json_ajax_i18n/ajaxServlet?action=javaScriptAjax",true)
// 4、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。xmlhttprequest.onreadystatechange = function(){
if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200)
{var jsonObj = JSON.parse(xmlhttprequest.responseText);
// 把响应的数据显示在页面上
document.getElementById("div01").innerHTML = "编号:" + jsonObj.id+",姓名:"+jsonObj.name;
}
}
// 3、调用 send 方法发送请求
xmlhttprequest.send();
}
</script>
</head>
<body>
<button onclick="ajaxRequest()">ajax request</button>
<div id="div01">
</div>
</body>
</html>