HTTP(HyperText Transfer Protocol)超文本传输协议,是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
请求:客户端发送给服务器端的数据
响应:服务器端发送给客户端的数据
一个完整的由客户端发送给服务器的HTTP请求中包含以下的完整数据:
1.请求行:请求方式、资源路径、使用的协议以及版本号GET/monkey.html HTTP/1.1
2.多个请求头:对客户端环境描述、客户端请求的主机地址等信息
Accept - - 浏览器可接收的MIME类型,即文件内容类型
Accept-Charset - - 告知服务器客户端支持的字符集
Accept-Encoding - - 浏览器能够进行解码的数据编码方式
Accept-Language - - 浏览器支持的语言
Connection - - 是否需要持久连接
Cookie - - 会话相关
Referer - - 当前页面从哪个页面访问过来的
3.请求空行:空行,分隔
4.请求体:内容正文(GET没有请求体,POST有请求体)
状态码 | 英文名称 | 描述 |
---|---|---|
200 | OK | 请求成功 |
400 | Bad Request | 客户端请求的语法错误,服务器无法解析 |
404 | Not Found | 服务器无法根据客户端的请求找到资源 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
http://localhost:8080/monkey.html?username=monkey&password=111
http://localhost:8080/monkey.html
客户端向服务器发送请求,服务器应当做出响应,将数据返回给客户端
一个完整的由服务器发送给客户端的HTTP响应中包含以下的完整数据:
1.响应行:HTTP协议版本、状态码、状态英文名 如HTTP/1.1 200 OK
2.多个响应头:对服务器的描述、对返回数据的描述(以下只举例部分)
Location - -
Server - - 服务器名称
Content-Encoding - - web服务器支持返回内容压缩编码类型
Content-Type - - 服务器告诉客户端本次响应体数据格式以及编码格式,text/html;charset=UTF-8
Transfer-Encoding - - 文件传输编码
Refresh - - 定时刷新
Set-Cookie - - 设置HTTP Cookie
3.响应空行:空行
4.响应体:传输的数据
状态码 | 描述 |
---|---|
1** | 信息,服务器收到请求,需要客户端继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
参考文档:HTTP状态码参考文档
ServletRequest接口 - - 请求对象,封装了获取所有请求信息,如请求行、请求头、请求实体
HttpServletRequest接口 - - 继承了 ServletRequest接口,用于处理HTTP协议请求的方法
获取请求行数据 GET /MyItems/demo2?username=monkey HTTP/1.1
获取请求头
获取请求体数据(注:只有POST请求方式才有请求体)
1.先获取流对象
2.再从流对象中取数据
例如,从登陆表单中获取数据,返回username=monkey&password=111
/*POST or GET*/
BufferedReader br = request.getReader();
String line = null;
while((line = br.readLine())!= null){
System.out.println(line);
}
获取请求参数(GET和POST都能使用)
//设置流的编码
request.setCharacterEncoding("utf-8");
案例:获取用户提交的内容
<body>
<form action="/demo6" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:<input type="checkbox" name="hobby" value="逛街">逛街
<input type="checkbox" name="hobby" value="蹦迪">蹦迪
<input type="checkbox" name="hobby" value="购物">购物
<input type="checkbox" name="hobby" value="游戏">游戏
<br>
<input type="submit" value="注册">
form>
body>
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String name = request.getParameter("username");
String password = request.getParameter("password");
String[] hobbies = request.getParameterValues("hobby");
System.out.println("用户名:"+name);
System.out.println("密码:"+password);
System.out.print("爱好:");
for(int i = 0;i < hobbies.length;i++){
System.out.print(hobbies[i]+" ");
}
System.out.println();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
一种在服务器内部的资源跳转方式,从Servlet1请求转发到Servlet2,Servlet完成一部分功能再跳转到Servlet2继续完成Servlet1不能完成的功能
request.getRequestDispatcher(String Path).forward(request,response);
//
参数:
Path - - 表示跳转的目标资源路径,不能是当前服务器以外的资源路径,如百度,csdn等等
/*浏览器这里是GET请求,但是我在GET里面调用POST封装请求和响应对象,最终是由POST输出*/
/*从RequestDemo1请求转发到RequestDemo2*/
@WebServlet("/demo7")
public class RequestDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这里是request的POST demo7");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
@WebServlet("/demo6")
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo6这里执行了");
request.getRequestDispatcher("/demo7").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
转发特点 - - forward
域对象 - - 一个有作用范围的对象,可以在范围内共享数据
request域 - - 代表一次请求的范围
作用域对象如何共享数据?
/*RequestDemo1和RequestDemo2 设置和获取 共享数据 */
/*输出obj的结果为monkey*/
@WebServlet("/demo7")
public class RequestDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object obj = req.getAttribute("v");
System.out.println(obj);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
@WebServlet("/demo6")
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("v","monkey");
request.getRequestDispatcher("/demo7").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
ServletResponse接口
- - 响应对象,封装了获取所有响应消息(状态行,响应头,请求实体)的方法
HttpServletResponse接口
- - 继承了ServletResponse接口,处理HTTP协议响应的方法
设置响应消息—普通方法
设置响应体
获取输出流(字符输出流or字节输出流)->使用输出流,将数据输出到客户端浏览器
①字符输出流 - - PrintWriter getWriter()
该方法获取的字符输出流对象为PrintWriter类型,可直接输出字符文本内容,若想要输出内容全为字符文本的网页文档,可使用getWriter()方法
②字节输出流 - - ServletOutputStream getOutputStream()
该方法获取的字节输出流对象为ServletOutputStream类型,是OutputStream的子类,可以直接输出字节数组中的二进制数据。若想要输出二进制格式的响应正文,就使用getOutputStream()方法,如文件下载
/*使用字节输出流来输出纯文本数据*/
resp.setContentType("text/html;charset=utf-8");
ServletOutputStream sos = resp.getOutputStream();//获取字节输出流
sos.write("头发没了哦".getBytes("utf-8"));//输出纯文本数据
③注意不能同时使用PrintWriter和OutputStream,比如如下代码会报错
OutputStream os = response.getOutputStream();
os.write("monkey".getBytes());
PrintWriter out = response.getWriter();
out.println("cat");
④中文乱码问题解决
/*方式一
resp.setCharacterEncoding("utf-8");//获取流对象之前,设置流的默认编码:ISO-8859-1 设置为其他的编码格式
resp.setHeader("content-type","text/html;charset=utf-8"); //告知浏览器服务器发送消息体数据的编码,建议浏览器使用该编码解码
PrintWriter pw = resp.getWriter();//获取字符输出流
pw.write("monkey");
pw.write("头发没了哦");
*/
//方式二
resp.setContentType("text/html;charset=utf-8");
方法一:设置状态码+设置路径
@WebServlet("/resDemo1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo1执行了哦");
resp.setStatus(302); //设置状态码
resp.setHeader("location","/resDemo2"); //设置路径
}
}
@WebServlet("/resDemo2")
public class ResponseDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("访问demo1,自动跳转到这里的demo2");
}
}
方法二:使用直接的方法设置路径
resp.sendRedirect("/resDemo2");
重定向的特点 - - redirect
ServletContext接口代表整个web应用,是Servlet中最大的接口,呈现了Web应用的Servlet视图,获得方法
ServletContext context1 = request.getServletContext();
ServletContext context2 = this.getServletContext();
1.获取MIME类型:在互联网通信过程中定义的一种文件数据类型,如text/html、image/jpeg
String getMimeType(String file)
- - 获取MIME类型
2.多个Servlet之间共享数据(域对象)
setAttribute(String name,Object object)
- - 向ServletContext中存数据
getAttribute(String name)
- - 从ServletContext中获取数据
removeAttribute(String name)
- - 从ServletContext中移除数据
/*两类之间共享context变量*/
@WebServlet("/resDemo1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
context.setAttribute("v","monkey");
}
}
@WebServlet("/resDemo2")
public class ResponseDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
Object obj = context.getAttribute("v");
System.out.println(obj);
}
}
3.获取当前WEB项目中指定的资源文件
getRealPath(String str)
- - 获取资源绝对路径
//获取ServletContext对象
ServletContext context = this.getServletContext();
/*
'/'代表E:\JavaWeb\out\artifacts\JavaWeb_war_exploded下的文件
如果想要访问WEB-INF下的文件,则路径写'/WEB-INF/other.html'
若要访问src下的文件,则路径写'/WEB-INF/classes/other.txt'
*/
//读取web项目文件下的文件
String realPath = context.getRealPath("/monkey.txt");
System.out.println(realPath);//E:\JavaWeb\out\artifacts\JavaWeb_war_exploded\monkey.txt
//读取该文件的内容
BufferedReader br = new BufferedReader(new FileReader(realPath));
String MyContext = br.readLine();
System.out.println(MyContext);