HTTP请求的结构

  • HTTP请求包含三部分:请求行、请求头、请求体
    image-20220421160256593

  • 请求行:说明请求方法,请求的Url,HTTP的版本信息

  • 请求头:包含了很多辅助性的信息,可以为程序处理提供额外的数据支持

    请求头中的内容 作用
    Accept-Language:zh-CN 当前浏览器所设置的语言
    User-Agent:Mozilla/4.0(compatible;MSIE 8.0;Windows NT 6.1) 说明浏览器和操作系统的环境
    Content-Length:112 代表内容的长度
    Cache-Control:no-cache 缓存的设置
    Cookie:………… Cookie的设置
  • 请求体:参数:get没有请求体,需要注意的是get请求,把参数放在URL中,其实是没有请求体的;只有Post请求才有请求体

HTTP的Get请求

在Tomcat中编写get请求的简单案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Servlet文件
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "RequestServlet", value = "/RequestServlet")
public class RequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is get method");//得到Get请求后,响应后,在页面输出
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is post method");//得到Post请求后,响应后,在页面输出
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="RequestServlet" method="get"><!--链接RequestServlet文件,发送get请求-->
<input name="username">
<input name="password" type="password">
<input type="submit">
</form>
</body>
</html>

Query String是Get传参的标志

image-20220421185615265

HTTP的Post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Servlet文件
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "RequestServlet", value = "/RequestServlet")
public class RequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is get method");//得到Get请求后,响应后,在页面输出
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is post method");//得到Post请求后,响应后,在页面输出
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="RequestServlet" method="post"><!--链接RequestServlet文件,发送get请求-->
<input name="username">
<input name="password" type="password">
<input type="submit">
</form>
</body>
</html>

Form Data是Post请求的标志

image-20220421185950250

利用请求头开发多端应用

情况展示:

平时,同一个网站,在电脑上和手机上显示效果完全不同,这背后的本质就是程序通过读取请求头(User-Agent)来判断是手机还是电脑

img

发现不同版本上的显示效果不同,然后请求头中的User-Agent也不同

img

img

img

获取当前请求头中的User-Agent信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "UserAgeServlet", value = "/UserAgeServlet")
public class UserAgeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userAgent =request.getHeader("User-Agent");//获取请求头中的“User-Agent”的值
response.setContentType("text/html;charset=utf-8");//设置响应,让其支持中文
response.getWriter().println(userAgent);//响应输出页面的值
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

img

img

img

根据User-Agent信息,判断是PC端还是移动端

判断出是PC端还是移动端,方便后续区别处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "UserAgeServlet", value = "/UserAgeServlet")
public class UserAgeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userAgent =request.getHeader("User-Agent");//获取请求头中的“User-Agent”的值
response.setContentType("text/html;charset=utf-8");//设置响应,让其支持中文
response.getWriter().println(userAgent);//响应输出页面的值,这里的值为userAgent的值
String output="";
if (userAgent.indexOf("Windows NT")!=-1){//indexof查找字符串,找到字符串返回的是大于0的数字,所以当不等于-1的时候一定是找到了这个值
output="<h1>这是PC端首页</h1>";
}else if (userAgent.indexOf("iPhone")!=-1 || userAgent.indexOf("Android")!=-1){
output="<h1>这是移动端首页</h1>";
}
response.getWriter().println(output);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

img

img

服务器的响应的结构

请求是浏览器向服务器发送的请求,而响应则是服务器返回给浏览器的显示结果

  • HTTP响应包含三部分:响应行、响应头、响应体
    image-20220421204608353

  • Content-Type:text/html表示,把响应体中内容当成text/html去解释;浏览器会按照text/html的方式去解释响应体中的内容

  • HTTP常见状态码
    如url网址输错的时候,会报404;如果Java的代码出了错误,会报500等;浏览器可以根据响应返回状态码,来知道服务器是处理成功还是出现了问题

    image-20220421210137173

  • 网页中的响应内容与响应体
    img
    img
    img

  • 常见状态码演示
    404:例如这里我少输出了文件名字
    image-20220421212129141

    500:服务器的内部错误,去寻找java源代码中的错误
    image-20220421213310953

ContentType的作用

  • ContentType决定浏览器采用何种方式对响应体进行处理
    image-20220421214309570
  • 浏览器可以理解成是一个解释器(解释器响应体中的内容,并体现在浏览器页面上);Content-Type属性值,就是浏览器对响应体内容采取何种方式;其默认是text/html

ContentType的示例

Content-Type设置为”text/html”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "ContentTypeServlet", value = "/ContentTypeServlet")
public class ContentTypeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String output="<h1><a href='http://www.baidu.com'><span>百度</span></a></h1>";
response.setContentType("text/html;charset=utf-8");//设置ContentType的值为text/html
response.getWriter().println(output);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

img

Content-Type设置为”text/plain”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "ContentTypeServlet", value = "/ContentTypeServlet")
public class ContentTypeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String output="<h1><a href='http://www.baidu.com'><span>百度</span></a></h1>";
response.setContentType("text/plain;charset=utf-8");//设置ContentType的值为text/plain
response.getWriter().println(output);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

img

Content-Type设置为”text/xml”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "ContentTypeServlet", value = "/ContentTypeServlet")
public class ContentTypeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String output="<h1><a href='http://www.baidu.com'><span>百度</span></a></h1>";
response.setContentType("text/xml;charset=utf-8");//设置ContentType的值为text/xml
response.getWriter().println(output);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

img

Content-Type设置为”application/x-msdownload”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "ContentTypeServlet", value = "/ContentTypeServlet")
public class ContentTypeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String output="<h1><a href='http://www.baidu.com'><span>百度</span></a></h1>";
response.setContentType("text/xml;charset=utf-8");//设置ContentType的值为application/x-msdownload
response.getWriter().println(output);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

img

请求转发与重定向

以前接触的都是一个Servlet内处理;而实际情况中,是需要多个Servlet之间跳转的,而Servlet之间的跳转方式为:请求转发和响应重定向

  • 多个Servlet(JSP)之间跳转有两种方式
  • request.getRequestDispatcher().forward() - 请求转发
  • response.sendRedirect() - 响应重定向

Servlet请求转发的原理

  • 请求转发是服务器内部跳转,只会产生一次请求
  • 请求转发的语句是:request.getRequestDispatcher().forward
    image-20220423220425705

Servlet请求转发案例

案例分析:例如在登录这个功能上,在登录界面,输入用户名和密码后并点击登录后;其会跳转到登录成功后的那个界面。这个案例主要是为了说明在实际开发中,Servlet是需要在不同页面上跳转显示的

img

img

请求转发的设置

img

请求转发的效果

可以看到地址栏的url没有改变

img

分析:输入http://localhost:8080/servlet_advanced/direct/check后,会先进入CheckLoginServlet这个Servlet,并打印"用户登录成功

image-20220423172143698

然后请求转发到IndexServlet的这个Servlet上,并触发了IndexServlet中的输出语句:This is index page!

image-20220423185815451

Servlet响应重定向的原理

  • 重定向则是浏览器端跳转,会产生两次请求
  • 响应重定向语句是:response.sendRedirect()
    1933

设置请求自定义属性

  • 请求允许创建自定义属性
  • 设置请求属性:request.setAttribute(属性名,属性值)
  • 获取请求属性:Object attr = request.getAttribute(属性名)

请求转发的情况下,获取自定义属性示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.java.servlet.direction;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "CheckLoginServlet", value = "/direct/check")//文件名CheckLoginServlet,路径/direct/check
public class CheckLoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
request.setAttribute("username","admin");//请求转发的情况下设置属性名和属性值
//request.getRequestDispatcher()方法相当于是一个请求分发器
//实现了请求转发的功能,/direct/check会跳转到/direct/index下
request.getRequestDispatcher("/direct/index").forward(request,response);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.java.servlet.direction;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "IndexServlet", value = "/direct/index")//文件名IndexServlet,路径/direct/index
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is index page!"+name);
String username= (String) request.getAttribute("username");
}

效果:

img

响应重定向的情况下,获取自定义属性示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.java.servlet.direction;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "CheckLoginServlet", value = "/direct/check")//文件名CheckLoginServlet,路径/direct/check
public class CheckLoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
request.setAttribute("username","admin");//请求转发的情况下设置属性名和属性值
response.sendRedirect("/servlet/direct/index");//响应重定向需要增加contextPath(即上下文路径)

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.java.servlet.direction;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "IndexServlet", value = "/direct/index")//文件名IndexServlet,路径/direct/index
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is index page!"+name);
String username= (String) request.getAttribute("username");
}

效果:

img