JAVAEE
文章目录
1.学习路线
2.Servlet的实现
2.3Servlet的工作流程
. 通过请求头获取浏览器访问的是哪一个主机
. 再通过请求行获取访问的是哪个一个web应用
. 再通过请求行中的请求路径获知访问的是哪个资源
. 通过获取的资源路径在配置中匹配到真实的路径
.服务器会创建servlet对象,(如果是第一次访问时,创建servlet实例,并调用init方法进行初始化操作)
.调用service (request,response)方法来处理请求和响应的操作
.调用service完毕后返回服务器由服务器将response缓冲区的数据取出,以http响应的格式发送给浏览器
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;
/**
*
* Servlet的实现
* 1.新建包,并新建普通的calss类
* 2.继承HttpServlet 类 (实现Servlet规范)
* 3.重写HttpServlet 类中的service()方法(sercvice方法在servlet类被访问时候,自动调用,作用:接受请求,响应结果)
* 4.在Servlet上添加注解@@WebServlet("/Servlet类的访问路径(资源的对外访问路径:浏览器通过访问该路径,从而到我们的Servlet类)")
* 注:
*
* 1.Service方法是由服务器自动调用(当Servlet 类被访问时)
* 2.设置Servlet 类的访问路径时。需要添加“/”!!!
* 3.在同一个项目下.Servlet类的对外访问路径值唯一(不能重复)
* 4.访问Servlet 时 ,路径格式如下
* http://localhost:端口/项目路径/资源路径?参数名=参数值
*
* 项目路径:站点名,项目对外访问路径,在Tomcat设置(Deployment属性中配置路径 Application context)
* 资源路径:servlet 对外访问路径,通过@WebServlet*/
@WebServlet("/ser01")
//@WebServlet(name = "Servlet01" ,value="/ser01")
// @WebServlet(name = "Servlet01",urlPatterns = "/ser01")
// 可以存放多个地址
//@WebServlet(value = {"/ser01","/ser02"})
//@WebServlet(urlPatterns = {"/ser01","/ser02"})
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hello Servlet!");
//响应数据
resp.getWriter().write("Hello");
}
// @Override
// protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp);
// }
//
// @Override
// protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
// }
}
2.4.Servlet的生命周期
. Servlet没有main()方法,不能独立运行,它的运行完全由Servlet引擎来控制和调度。所谓生命周期,指的是servlet容器何时创servlet实例、何时调用其方法进行请求的处理、何时并销毁其实例的整个过程。
·实例和初始化时机
当请求到达容器时,容器查找该servlet对象是否存在,如果不存在,则会创建实例并进行初始化。
·就绪/调用/服务阶段
有请求到达容器,容器调用servlet对象的service()方法,处理请求的方法在整个生命周期中可以被多次调用;HttpServlet的service()方法,会依据请求方式来调用doGet()或者doPost()方法。但是,这两个do方法默认情况下,会抛出异常,需要子类去override。
·销毁时机
当容器关闭时(应用程序停止时),会将程序中的Servlet 实例进行销毁。
上述的生命周期可以通过Servlet 中的生命周期方法来观察。在Servlet 中有三个生命周期方法,不由用户手动调用,而是在特定的时机有容器自动调用,观察这三个生命周期方法即可观察到Servlet的生命周期。
import javax.servlet.ServletConfig;
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;
/**
* Servlet的生命周期
* 1.初始化(init()方法) 系统方法,服务器自动调用,只会执行一次,
* 当第一次访问Servlet时触发
* 2.就绪/调用/service(), 系统方法,服务器自动调用,可以调用多次。
* 当有请求访问servlet时,service就会被调用
* 3.销毁destory()
* 系统方法,服务器自动调用,只会执行一次。
* 当服务关闭或者宕机时候触发。
* */
@WebServlet("/ser03")
public class Servlet03 extends HttpServlet
{
// 系统方法,服务器自动调用,只会执行一次,
// * 当第一次访问Servlet时触发
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("innt...");
}
// 系统方法,服务器自动调用,可以调用多次。
// * 当有请求访问servlet时,service就会被调用
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service...");
}
// 系统方法,服务器自动调用,只会执行一次。
// 当服务关闭或者宕机时候触发。
@Override
public void destroy() {
System.out.println("destroy...");
}
}
·步骤
Servlet的生命周期,简单的概括这就分为四步: servlet类加载–>实例化–>服务–>销毁。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5OCPn7z2-1650249183905)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220412104326547.png)]
-
Web Client向Servlet容器(Tomcat)发出Http请求
-
Servlet容器接收Web Client的请求
-
Servlet容器创建一个HttpServletRequest对象,将Web client请求的信息封装到这个对象中
-
Servlet容器创建一个HttpServletResponse对象
-
Servlet容器调HttpServlet对象service方法,把 Request 与Response 作为参数,传给HttpServlet.
-
HttpServlet调用HttpServletRequest对象的有关方法,获取Http请求信息
-
HttpServlet调用HttpServletResponse对象的有关方法,生成响应数据
-
Servlet容器把HttpServlet的响应结果传给web Client
3.HttpServletRequest对象
HttpServletRequest对象:主要作用是用来接收客户端发送过来的请求信息,例如:请求的参数,发送的头信息等都属于客户端发来的信息,service()方法中形参接收的是HttpServletRequest 接口的实例化对象,表示该对象主要应用在HTTP协议上,该对象是由Tomcat封装好传递过来。
HttpServletRequest是ServletRequest 的子接口,ServletRequest 只有一个子接口,就是HttpServletRequest。既然只有一个子接口为什么不将两个接口合并为一个?
从长远上讲:现在主要用的协议是HTTP协议,但以后可能出现更多新的协议。若以后想要支持这种新协议,只需要直接继承 ServletRequest接口就行了。
在HttpServletRequest接口中,定义的方法很多,但都是围绕接收客户端参数的。但是怎么拿到该对象呢?不需要,直接在Service方法中由容器传入过来,而我们需要做的就是取出对象中的数据,进行分析,处理
package com.shsxt.servlet;
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("/ser04")
public class Servlet04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.service(req, resp);
/* 常见的请求方式
* http://localhost:8080/zhongsheng/ser04?uname=zs&upwd=123
* */
//获取客户端请求的完整URL (从http 开始,到?前面结束)
String url = req.getRequestURL().toString();
System.out.println("获取客户端请求的完整URL "+url);
//获取客户端请求的完整URL (从http 开始,到?前面结束)
String uri = req.getRequestURI();
System.out.println("获取客户端请求的完整URi "+uri);
//获取请求中的参数部分
String queryString=req.getQueryString();
System.out.println("获取请求中的参数部分:"+queryString);
//获取客户端的请求方式
String method = req.getMethod();
System.out.println("获取客户端的请求方式:"+method);
//获取HTTP版本号
String protocol=req.getProtocol();
System.out.println("获取HTTP版本号:"+protocol);
//获取webapp名字(站点名)
String webapp =req.getContextPath();
System.out.println("获取webapp名字(站点名):"+webapp);
/**
*获取请求参数
* 1.通过参数名获取参数值, 返回字符串
* req.getParameter("参数名");
* 参数名:
* 1.表达元素name属性值
* 2.ajax的data属性值的键
* 3.超链接参数的键
* 2.通过参数名获取所有的参数值,返回数组
*
*
* */
//获取用户名
String uname = req.getParameter("unmae");
String upwd = req.getParameter("upwd");
System.out.println("姓名:"+uname+"密码"+upwd);
//通过参数名获取所有的参数值,返回数组
String[] hobby =req.getParameterValues("hobby");
System.out.println(hobby.length);
}
}
3.1.2
方法
getParameter(name)获取指定名称的参数
getParameterValues(String name) 获取指定名称参数的所有值java
/**
*获取请求参数
* 1.通过参数名获取参数值, 返回字符串
* req.getParameter("参数名");
* 参数名:
* 1.表达元素name属性值
* 2.ajax的data属性值的键
* 3.超链接参数的键
* 2.通过参数名获取所有的参数值,返回数组
*
*
* */
//获取用户名
String uname = req.getParameter("unmae");
String upwd = req.getParameter("upwd");
System.out.println("姓名:"+uname+"密码"+upwd);
//通过参数名获取所有的参数值,返回数组
String[] hobby =req.getParameterValues("hobby");
System.out.println(hobby.length);
3.2请求乱码问题
由于现在的request属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。要想解决这种乱码问题,需要设置request 中的编码方式,告诉服务器以何种方式来解析数据。或者在接收到乱码数据以后,再通过相应的编码格式还原。
* 请求乱码问题
* 乱码原因:request有默认的编码格式,默认编码是IOS-8859-1,这种编码不支持中文
* 乱码情况
* Tomcat7及以下版本:GET请求和POST请求都会乱码
* Tomcat8及以上版本,GET请求不会乱码,POST会乱码
* 方式一:设置请求的编码 只针对POST请求
* request.serCharaterEncoding("UTF-8");
* 针对所有
*
* 方式二:获取乱码内容后转码,通过new String()
* new String(req.getParameter("unmae"),getBytes("IOS-8859-1"),"UTF-8")
* 每出现一个你需要去处理一个
3.3请求转发
请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的URL地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。实现方式如下,达到多个资源协同响应的效果。
//请求转发跳转到首页
req.getRequestDispatcher("url").forward(req,resp);
3.4request作用域
通过该对象可以在一个请求中传递数据,作用范围:再一次请求中有效,即服务器跳转有效。(用来做前后台的一个数据传输)
* request作用域
* 只在一次请求中有效,只在请求转发中
* 设置作用域
* request.setAttribute("参数名",参数值)
* 获取作用域
* req.getAttribute("参数名")
* 移除作用域
* req.removeAttribute("参数名")
4.HttpServletRespose 对象
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。
request和response对象代表请求和响应︰获取客户端数据,需要通过request对象;向客户端输出数据,需要通过response对象。
HttpServletResponse的主要功能用于服务器对客户端的请求进行响应,将Web服务器处理后的结果返回给客户端。service()方法中形参接收的是HttpServletResponse 接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
4.1.响应数据
接收到客户端请求后,可以通过HttpServletResponse对象直接进行响应,响应时需要获取输出流。
有两种形式:
getWriter() 获取字符流(只能响应回字符)
getOutputStream() 获取字节流(能响应一切数据)
响应回的数据到客户端被浏览器解析。
4.2.响应乱码问题
在响应中,如果我们响应的内容中含有中文,则有可能出现乱码。这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
getWriter()的字符乱码
对于getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用ISO-8859-1格式的编码,该编码方式并不支持中文。
要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式比如我们通常用的"UTF-8"。
/**
* 响应数据乱码
* 乱码原因:
* 在响应中,如果我们响应的内容中含有中文,则有可能出现乱码。
* 这是因为服务器响应的数据也会经过网络传输,
* 服务器端有一种编码方式,在客户端也存在一种编码方式,
* 当两端使用的编码方式不同时则出现乱码。
* 乱码情况:
* 1.getWriter()字符输出流
* 对于getWriter()获取到的字符流,响应中文必定出乱码,
* 由于服务器端在进行编码时默认会使用ISO-8859-1格式的编码,
* 该编码方式并不支持中文。
* 2.getOutputStream()字节输出流
* 可能会出现乱码,响应中午时,由于本身就是传输的字节,所以此时可能出现乱码
*
* 乱码原因:
* 客户端和服务端的编码不一致,或者编码不支持中文
* 解决方案:
* 1.设置客户端和服务端的编码格式一致
* 2.设置客户端和服务端都支持中文
*
* 设置客户端的编码格式
* response.setHeader("conten-type","text/html;charset=UTF-8");
* 设置服务端的编码格式
* response.setCharacterEncoding("UTF-8");
*
* 或者
* 同时设置客户端和服务端的编码
* response.setContentType("text/html;charset=UTF-8")
* */
4.3.重定向
重定向是一种服务器指导,客户端的行为。客户端发出第一个请求,被服务器接收处理后,服务器会进行响应,在响应的同时,服务器会给客户端一个新的地址,
(下次请求的地址response.sendRedirect(url;),当客户端接收到响应后,会立刻、马上、自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。
从描述中可以看出重定向当中有两个请求存在,并且属于客户端行为。
a
/**
* 重定向
* 服务端指导,客户端行为的跳转方式
*
* 特点:
* 1.地址栏会发生改变
* 2.客户端跳转
* 3.客户端跳转有两次请求
* 4.request对象不共享
* */
@WebServlet("/ser12")
public class Servlet12 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收参数
System.out.println("姓名:"+req.getParameter("name"));
//设置作用域
req.setAttribute("admin","admin");
System.out.println("Servlet05...");
//重定向 跳转到首页
resp.sendRedirect("index.jsp");
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>Hello</h2>
<%
//接受参数
String name= request.getParameter("name");
out.print("姓名:"+name);
out.print("<br>");
//获取request作用域
String admin= (String) request.getAttribute("admin");
out.print("admin:"+admin);
%>
</body>
</html>
4.4请求转发与重定向的区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MyeqfrHp-1650249183906)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220413113604264.png)]
package com.shsxt.servlet;
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;
/**
*
* 重定向与请求转发
* 1.请求转发的地址栏不发生改变,重定向的地址会被改变
* 2.请求转发是服务端挑战,重定向是客户端跳转
* 3.请求转发是一次请求,重定向是两次请求
* 4.请求转发是request作用域可以共享,重定向是不可以共享
* 5.请求转发的地址是跳转到当前项目的资源,重定向可以跳转到任意资源
* */
@WebServlet("/ser13")
public class Servlet13 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet06...");
//设置作用域
req.setAttribute("admin","admin");
//请求转发(服务端)
// req.getRequestDispatcher("index.jsp").forward(req,resp);
//重定向 跳转到首页(服务端)
resp.sendRedirect("http://www.baidu.com");
//跳转到百度
}
}
5.Cookie对象
Cookie是浏览器提供的一种技木,通过服务器的程序能将一些只须保存在客户端,或者在客户端进行处理的数据,放在本地的计算机上,不需要通过网络传输,因而提高网页处理的效率,并且能够减少服务器的负载,但是由于Cookie是服务器端保存在客户端的信息,所以其安全性也是很差的。例如常见的记住密码则可以通过Cookie来实现。
有一个专门操作Cookie的类javax.servlet.http.Cookie。随着服务器端的响应发送给客户端,保存在浏览器。当下次再访问服务器时把cookie再带回服务器。
cookie 的格式:键值对用“=”链接,多个键值对间通过“;”隔开。
5.1.Cookie的创建和发送
cookie01
通过new Cookie(“key” “value”);来创建一个Cookie对象,要想将Cookie随响应发送到客户端,需要先添加到response对象中,response.addCookie(cookie);此时该cookie对象则随着响应发送至了客户端。在浏览器上可以看见。a
package com.shsxt.servlet.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Cookie
* 是浏览器技术
* Cookie对象的创建与发送
* */
@WebServlet("/cook01")
public class Cookie01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//得到Cookie对象
Cookie cookie =new Cookie("uname","admin");
//响应cookie对象
resp.addCookie(cookie);
//得到Cookie对象
Cookie cookie02 =new Cookie("uname","zs");
//响应cookie对象
resp.addCookie(cookie02);
}
}
cookie02
package com.shsxt.servlet.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Cookie的获取
* 获取所有的cookie的数组
* Cookie[] cookies=req.getCookies();
* */
@WebServlet("/cook02")
public class Cookie02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取所有的cookie的数组
Cookie[] cookies=req.getCookies();
//判断cookie是否存在,遍历获取值
if(cookies!=null&&cookies.length>0){
for (Cookie cookie:cookies) {
System.out.println("名称"+cookie.getName()+",值"+cookie.getValue());
//获取指定的cookie对象
if ("uname".equals(cookie.getName())){
System.out.println("指定值:" + cookie.getValue());
}
}
}
}
}
5.2cookie的获取
//得到Cookie对象
Cookie cookie =new Cookie("uname","admin");
//响应cookie对象
resp.addCookie(cookie);
5.3.Cookie设置到期时间
除了Cookie的名称和内容外,我们还需要关心一个信息,到期时间,到期时间用来指定该cookie何时失效。默认为当前浏览器关闭即失效。我们可以手动设定cookie的有效时间(通过到期时间计算),通过setMaxAge(inttime);方法设定cookie的最大有效时间,以秒为单位。
到期时间的取值
·负整数
若为负数,表示不存储该cookie。
cookie的 maxAge属性的默认值就是-1,表示只在浏览器内存中存活,一旦关闭浏览器窗口,那么cookie就会消失。
正整数
若大于o的整数,表示存储的秒数。
表示cookie对象可存活指定的秒数。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie 也会存活相应的时间。
零
若为0,表示删除该cookie。
cookie生命等于О是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。
cookie03
package com.shsxt.servlet.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Cookie的到期时间
* maxAge
* 设置Cookie对象失效的时间
* 正整数:
* cookie会春活指定秒数
* 负整数(默认 -1)
* cookie只在浏览器中存活,浏览器关闭即失效
* 0:
* 表示即可删除,删除cookie
* */
@WebServlet("/cook03")
public class Cookie03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
//获取cookie对象
Cookie cookie=new Cookie("uname03","lisi");
//cookie失效时间
cookie.setMaxAge(-1);//负整数默认关闭浏览器就失效
resp.addCookie(cookie);
//获取cookie对象
Cookie cookie02=new Cookie("uname04","wangwu");
//cookie失效时间
cookie02.setMaxAge(20);//正整数存活指定秒数
resp.addCookie(cookie02);
//获取cookie对象
Cookie cookie03=new Cookie("uname05","zhaosi");
//cookie失效时间
cookie03.setMaxAge(0);//表示删除
resp.addCookie(cookie03);
//如果cookie对象是存在的 删除cookie
Cookie cook =new Cookie("uname","null");
cook.setMaxAge(0);
resp.addCookie(cook);
}
}
5.4.Cookie的注意点
. Cookie保存在当前浏览器中。
在一般的站点中常常有记住用户名这样一个操作,该操作只是将信息保存在本机上,换电脑以后这些信息就无效了。而且cookie 还不能跨浏览器。
. Cookie存中文问题
Cookie 中不能出现中文,如果有中文则通过URLEncoder.encode()来进行编码
URLDecoder.decode()来讲行解码。
如果cookie存放了中文会
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vlGnjVag-1650249183906)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220414172802428.png)]
URLEncoder.encode()来进行编码
/*Cookie存中文*/
String name="姓名";
String value="张三";
//在设置时将中文使用URLEncode.encode()方法进行编码
name= URLEncoder.encode(name);
value=URLEncoder.encode(value);
Cookie cookie = new Cookie(name,value);
resp.addCookie(cookie);
URLDecoder.decode()来讲行解码。
//获取使用urlDecoder.decode()方法进行解码
String name= URLDecoder.decode(cookie.getName());
String value =URLDecoder.decode(cookie.getValue());
System.out.println("名称"+name+",值"+value);
5.5.Cookie的路径
Cookie的setPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些cookie。
package com.shsxt.servlet.Cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
/**
* Cookie的路径
* Cookie的setPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些cookie。
*
* 当前项目:站点名为:/zhongsheng
* 当前服务域名为:localhost:8080
* 设置路径:setpath(),默认当前项目的站点名
* setPath("/zhongsheng")
*
* 1.当前服务器下,任务项目的任意资源,都可获取Cookie对象
* serpath("/");
* 2.在当前项目下,可以获取cookie对象(默认)
* setPath(“/zhongsheng”)
* 3.在指定项目下,可获取cookie对象(指定项目站点名:/s05)
* setPath(“/s05”)
* 4.在指定项目的指定资源下,以获取cookie对象
* setPath(“/zhongsheng/ser12”);
* */
@WebServlet("/cook05")
public class Cookie05 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.当前服务器下,任务项目的任意资源,都可获取Cookie对象
Cookie cookie01=new Cookie("aa","AA");
cookie01.setPath("/");
resp.addCookie(cookie01);
// 2.在当前项目下,可以获取cookie对象(默认)
Cookie cookie02=new Cookie("bb","BB");
cookie02.setPath("/zhongsheng");
resp.addCookie(cookie02);
// 3.在指定项目下,可获取cookie对象(指定项目站点名:/s05)
Cookie cookie03=new Cookie("cc","CC");
cookie03.setPath("/ser05");
resp.addCookie(cookie03);
// 4.在指定项目的指定资源下,以获取cookie对象
Cookie cookie04=new Cookie("dd","DD");
cookie04.setPath("/zhongsheng/test");
resp.addCookie(cookie04);
}
}
6.HttpSesion对象
HttpSession*对象是javax.servlet.http.HttpSession的实例,该接口并不像HttpServletRequest或HttpServletResponse还存在一个父接口,该接口只是一个纯粹的接口。这因为session本身就属于HTTP协议的范畴。
对于服务器而言,每一个连接到它的客户端都是一个session,servlet容器使用此接口创建HTTP客户端和HTTP服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间。在整个session中,最重要的就是属性的操作。
session无论客户端还是服务器端都可以感知到,若重新打开一个新的浏览器,则无法取得之前设置的session,因为每一个session只保存在当前的浏览器当中,并在相关的页面取得。
Session的作用就是为了标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数据。我们可以通过request.getSession()方法,来获取当前会话的session对象。
//创建获取Session
HttpSession session =req.getSession();
//设置sessiony
6.1.标识符JSESSIONID
Session既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是sessionld。
每当一次请求到达服务器,如果开启了会话(访问了session),服务器第一步会查看是否从客户端回传一个名为JSESSIONID的cookie,如果没有则认为这是一次新的会话,会创建一个新的session对象,并用唯一的sessionld为此次会话做一个标志。如果有JESSIONID这个cookie回传,服务器则会根据JSESSIONID这个值去查看是否含有id为JSESSION值的session对象,如果没有则认为是一个新的会话,重新创建一个新的session对象,并标志此次会话;如果找到了相应的session对象,则认为是之前标志过的一次会话共享。
这里提到一个叫做JSESSIONID的cookie,这是一个比较特殊的cookie,当用户请求服务器时,如果访问了session,则服务器会创建一个名为JSESSIONID,值为获取到的session(无论是获取到的还是新创建的)的sessionld的cookie对象,并添加到response对象中,响应给客户端,有效时间为关闭浏览器。
所以Session的底层依赖Cookie来实现。
package com.shsxt.servlet.Session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Session的作用域
*
* 再一次会话中有效
* 通过setAttribute(name , value)方法向域对象中添加数据
* 通过getAttribute(name)从域对象中获取数据
* 通过removeArribute(name)从域对象移除数据
*
* request作用域
* 知在一次请求有效
* 只在请求转发跳转有效
* session作用域:
* 在一次会话中有效,会话中包含多次请求
* 在请求转发与重定向跳转后都有效
*
**/
@WebServlet("/ses02")
public class Session02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建获取Session
HttpSession session =req.getSession();
System.out.println("session02"+session.getId());
//request作用域
req.setAttribute("requestMsg","request的作用域");
//session作用域
session.setAttribute("sessionMsg","session的作用域");
//请求转发
// req.getRequestDispatcher("index.jsp").forward(req,resp);
//重定向
resp.sendRedirect("index.jsp");
}
}
6.2.session域对象
Session用来表示一次会话,在一次会话中数据是可以共享的,这时session作为域对象存在,可以通过setAttribute(name,value)方法向域对象中添加数据,通过getAttribute(name)从域对象中获取数据,通过removeAttribute(name)从域对象中移除数据。
6.3.session对象的销毁
6.3.1.默认时间到期
当客户端第一次请求servlet并且操作session时,session对象生成,Tomcat中session默认的存活时间为30min,即你不操作界面的时间,一旦有操作,session会重新计时。
那么session的默认时间**(30分钟**)可以改么?答案是肯定的。
可以在Tomcat 中的conf目录下的web.xml文件中进行修改。
- Session的作用域
- 1.默认到期时间:
-
默认最大活动时间,当指定时间内,没有做任何操作
-
tomcat服务器设置的session的最大不活动时间30分钟
-
可以手动修改服务器的时间(不建议)
-
在Tomcat安装包的conf目录中,对应web.xml文件
-
<session-config>
-
<session-tiemout>30</session-tiemout>
-
</session-config>
package com.shsxt.servlet.Session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Session的作用域
* 1.默认到期时间:
* 默认最大活动时间,当指定时间内,没有做任何操作
* tomcat服务器设置的session的最大不活动时间30分钟
* 可以手动修改服务器的时间(不建议)
* 在Tomcat安装包的conf目录中,对应web.xml文件
* <session-config>
* <session-tiemout>30</session-tiemout>
* </session-config>
* 2.手动设置最大不活动时间
* 设置最大不活动时间,单位秒
* session.setMaxInactiveInterval();
* 获取最大不活动时间
* session.getMaxInactiveInterval()
* 3.关闭浏览器
* session底层依赖cookie,cookie默认关闭浏览器失效
* 4.关闭服务器
* 服务器关闭,session对象就销毁了
* 5.手动销毁
* session.invalidate
*
*
*
**/
@WebServlet("/ses03")
public class Session03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建获取Session
HttpSession session =req.getSession();
System.out.println("session03"+session.getId());
//获取最大不活动时间
System.out.println("最大不活动时间"+session.getMaxInactiveInterval());
//设置最大不活动时间
session.setMaxInactiveInterval(20);
//手动销毁
session.invalidate();
}
}
7.ServletContext对象
每一个web应用都有且仅有一个ServletContext对象,又称Application对象,从名称中可知,该对象是与应用程序相关的。在WEB容器启动的时候,会为每一个WEB应用程序创建一个对应的ServletContext对象。
该对象有两大作用,第一、作为域对象用来共享数据,此时数据在整个应用程序中共享;第二、该对象中保存了当前应用程序相关信息。例如可以通过getServerInfo()方法获取当前服务器信息,getRealPath(String path)获取资源的真实路径等。
7.1.ServletContext对象的获取
// 1.ServletContext的获取
ServletContext servletContext= req.getServletContext();
//2.通过session对象的获取
ServletContext servletContext1=req.getSession().getServletContext();
// 3.通过servletComfig对象获取
ServletContext servletContext2=getServletConfig().getServletContext();
//4.在Servlet类中获取
ServletContext servletContext3=getServletContext();
7.2ServletContext对象常用方法
“获取在服务器中的真是路径”+servletContext.getRealPath("/")
" 获取当前服务器的版本信息"+servletContext.getServerInfo()
package com.shsxt.servlet.ServletContext;
import javax.servlet.ServletContext;
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;
/**
*ServletContext对象
* 每一个Web应用有且只有一个servletContext对象
* 1.ServletContext的获取
* 通过request对象获取
* 通过session对象的获取
* 通过servletComfig对象获取
* 在Servlet类中获取
* 2.常用方法
* 获取在服务器中的真是路径 getRealPath
* 获取当前服务器的版本信息 getServletInfo
* 3.ServletContext作用域
* 在整个应用程序中生效,服务关闭生效
* setAttribute();
* */
@WebServlet("/sr01")
public class ServletContext01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.ServletContext的获取
ServletContext servletContext= req.getServletContext();
//2.通过session对象的获取
ServletContext servletContext1=req.getSession().getServletContext();
// 3.通过servletComfig对象获取
ServletContext servletContext2=getServletConfig().getServletContext();
//4.在Servlet类中获取
ServletContext servletContext3=getServletContext();
System.out.println("获取在服务器中的真是路径"+servletContext.getRealPath("/"));
System.out.println(" 获取当前服务器的版本信息"+servletContext.getServerInfo());
}
}
8.文件上传和下载
在上网的时候我们常常遇到文件上传的情况,例如上传头像、上传资料等;当然除了上传,遇见下载的情况也很多,接下来看看我们servlet中怎么实现文件的上传和下载。
8.1.文件上传
文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件
后台接收并保存文件,这才是一
个完整的文件上传。
8.1.1.前台页面
在做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的请求方式为 **POST;**其次我们的form表单的enctype必须设为"multipart/form-data",即 enctype="multipart/form-data",意思是设置表单的类型为文件上传表单。默认情况下这个表单类型是"application/x-www-form-urlencoded",不能用于文件上传。只有使用了multipart/form-data才能完整地传递文件数据。
<!-- 文件上传表单(二进制表单)
1.表单类型
普通表单:application/x-www-form-urlencoded(默认)
二进制表单: enctype="multipart/form-data(文件上传,则需要设置)
2.提交方式:
GET请求与POST请求
文件上传需要设置为method=“POST”
3.表单元素:
、 文件域
<input type="file" name="myfile" />
4.提交路径
处理上次的文件的servlet的对外访问路径
-->
<form action="uploadServlet" enctype="multipart/form-data" method="post">
姓名:<input type="text" name="uname">
头像:<input type="file" name="myfile">
<button type="submit">提交</button>
</form>
upload
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 文件上传表单(二进制表单)
1.表单类型
普通表单:application/x-www-form-urlencoded(默认)
二进制表单: enctype="multipart/form-data(文件上传,则需要设置)
2.提交方式:
GET请求与POST请求
文件上传需要设置为method=“POST”
3.表单元素:
、 文件域
<input type="file" name="myfile" />
4.提交路径
处理上次的文件的servlet的对外访问路径
-->
<form action="/src/com/shsxt.servlet/uploadServlet" enctype="multipart/form-data" method="post">
姓名:<input type="text" name="uname">
头像:<input type="file" name="myfile">
<button type="submit">提交</button>
</form>
</body>
</html>
uploadServlet
package com.shsxt.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
/**
* 做文件上传
* 使用注解@MultipartConfig将一个Servlet标识作为支持文件上传
* Servlet将multipart/form-data的POST请求封装成Part,通过Part 对上传的文件进行操作/
* Part part = request,getPart(name)
* name代表的是表单元素(文件域)的name的属性值*/
@MultipartConfig //文件上传必须设置该注解,否所有参数都无法获取
@WebServlet("/uploadServlet")
public class uploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置文本请求的编码格式
req.setCharacterEncoding("UTF-8");
//获取普通文本框(getParmeter(name)方法获取)
String uname= req.getParameter("uname");
System.out.println("用户名"+uname);
//获取Part对象
Part part=req.getPart("myfile");
//得到上传文件的文件名
String filename = part.getSubmittedFileName();
//设置上传文件存放路径
String uploadPath=req.getServletContext().getRealPath("/upload/");
//上传文件
part.write(uploadPath+filename);
}
}
8.2.文件下载
文件下载,即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性来下载;第二种是通过代码下载。
8.2.1.超链接下载
当我们在HTML或JSP页面中使用a标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的资源时会自动下载;当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如txt、png、jpg等。当然我们也可以通过download 属性规定浏览器进行下载。但有些浏览器并不支持。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<!--超链接
a标签在遇到浏览器能够识别资源时,会直接打开资源,如果遇到浏览器不能够识别的资源,则就会进行下载
download属性
可以设置a标签的download属性,让超链接执行下载操作
如果设置了download属性值,则下载的文件名为对应的属性值,如果未设置则下载文件名为原本文件原本的名字
-->
<h3>超链接下载</h3>
<!--浏览器能够识别的资源-->
<a href="../test.txt">TXT文本</a>
<a href="../imgs/bg.png">图片</a>
<!--浏览器不能够识别的资源-->
<a href="../test.zip">压缩包</a>
<hr>
<!--指定download属性下载-->
<a href="../test.txt" download="">TXT文本</a>
<a href="../imgs/bg.png" download="test.png">图片</a>
</body>
</html>
8.2.2.后台实现下载
实现步骤
.需要通过response.setContentType方法设置Content-type头字段的值,为浏览器无法使用某种方式或激活某个程序来处理的MIME类型,例如"application/octet-stream"或"application/x-msdownload"等。
.需要通过response.setHeader方法设置Content-Dispose头的值为attachment;filename=“文件名”
读取下载文件,调用response.getOutputStream方法向客户端写入附件内容。
package com.shsxt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 文件下载
* 1..需要通过response.setContentType方法设置Content-type头字段的值,
* 为浏览器无法使用某种方式或激活某个程序来处理的MIME类型,
* 例如"application/octet-stream"或"application/x-msdownload"等。
* 2..需要通过response.setHeader方法设置Content-Dispose头的值为attachment;filename="文件名"
* 3.读取下载文件,调用response.getOutputStream方法向客户端写入附件内容
* 下载步骤
* 1.得到需要下载的文件名
* 2.得到下载的文件存放的路径
* 3.通过路径域文件名得到file对象(要下载的文件)
* 4.判断file对象是否存在,且是一个标准文件
* 5.设置响应类型浏览器无法使用某种方式或激活某个程序来处理的MIME类型
* 6.设置响应头(下载文件名之类)
* 7.得到要下载的文件的输入流
* 8.得到字节输出流
* 9.循环输出
* 10.关闭流*/
@WebServlet("/downservlet")
public class downservlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码
req.setCharacterEncoding("UTF-8");
//获取文件下载路径
String filepath=getServletContext().getRealPath("../imgs");
//获取下载的文件名
String filename=req.getParameter("filename");
//通过路径得到file对象
File file = new File(filepath+filename);
//判断file对象是否存在,是否是一个标准的文件
if (file.exists()&&file.isFile()){
//设置响应类型(浏览器无法使用某种方式或激活某个程序来处理的类型)
resp.setContentType("application/x-msdownload");
//设置头信息
resp.setHeader("content-Disposition","attachment;filename="+filename);
//得到输入流
InputStream is =new FileInputStream(file);
//得到输出流
ServletOutputStream os=resp.getOutputStream();
//定义byte数组
byte[] car=new byte[1024];
//定义长度
int len=0;
//循环输出
while ((len=is.read(car))!=-1){
os.write(car,0,len);
}
//关闭流,释放资源
os.close();
is.close();
}else {
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("<h2>要下载的文件不存在</h2>");
resp.getWriter().close();
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<!--超链接
a标签在遇到浏览器能够识别资源时,会直接打开资源,如果遇到浏览器不能够识别的资源,则就会进行下载
download属性
可以设置a标签的download属性,让超链接执行下载操作
如果设置了download属性值,则下载的文件名为对应的属性值,如果未设置则下载文件名为原本文件原本的名字
-->
<h3>超链接下载</h3>
<!--浏览器能够识别的资源-->
<a href="../test.txt">TXT文本</a>
<a href="../imgs/bg.png">图片</a>
<!--浏览器不能够识别的资源-->
<a href="../test.zip">压缩包</a>
<hr>
<!--download-->
<a href="../test.txt" download="">TXT文本</a>
<a href="../imgs/bg.png" download="test.png">图片</a>
<hr>
<form action="/zhongsheng/downservlet">
文件名:<input type="text" name="filename">
<button>下载</button>
</form>
</body>
</html>
ServletOutputStream os=resp.getOutputStream();
//定义byte数组
byte[] car=new byte[1024];
//定义长度
int len=0;
//循环输出
while ((len=is.read(car))!=-1){
os.write(car,0,len);
}
//关闭流,释放资源
os.close();
is.close();
}else {
resp.setContentType(“text/html;charset=UTF-8”);
resp.getWriter().write(“
要下载的文件不存在
”);resp.getWriter().close();
}
}
}
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<!--超链接
a标签在遇到浏览器能够识别资源时,会直接打开资源,如果遇到浏览器不能够识别的资源,则就会进行下载
download属性
可以设置a标签的download属性,让超链接执行下载操作
如果设置了download属性值,则下载的文件名为对应的属性值,如果未设置则下载文件名为原本文件原本的名字
-->
<h3>超链接下载</h3>
<!--浏览器能够识别的资源-->
<a href="../test.txt">TXT文本</a>
<a href="../imgs/bg.png">图片</a>
<!--浏览器不能够识别的资源-->
<a href="../test.zip">压缩包</a>
<hr>
<!--download-->
<a href="../test.txt" download="">TXT文本</a>
<a href="../imgs/bg.png" download="test.png">图片</a>
<hr>
<form action="/zhongsheng/downservlet">
文件名:<input type="text" name="filename">
<button>下载</button>
</form>
</body>
</html>
要源码的评论关注+私信