HttpGET请求 与 HttpPOST请求的区别:
GET请求:
- 请求的参数 ,以键值对的形式 存储在网址中 ,在网址中, 编写在?后, 由1个或多个键值对组成, 键与值之间使用等号连接, 多个键值对之间使用&分割.
- 只能传输字符串类型的参数.
- 网址的最大长度为4kb 通常支持的文字 2048 个文字
- 数据传输不安全
tomcat8+版本 : GET请求不会乱码
POST请求:
- 请求的数据, 以键值对的形式存储在请求体中,
- 请求体是一个单独的数据包 , 较GET请求而言, 安全.
- 可以传输任意类型的数据
- 数据的大小 ,理论上是无上限的.
tomcat8+版本 : Post请求默认编码为 ISO-8859-1 (不支持中文)什么样的请求是GET
以我们目前所学习的技术来说 , 除了表单提交时method="POST" ,其他的访问方式都是GET请求
例如:
- 点击超链接 访问
- 通过js: window.location.href='' 访问
- 浏览器中输入网址 + 回车
- 表单提交时 ,method="GET" 或 默认
- ajax的get请求
- Java代码的URL类的GET请求.什么样的请求时PSOT
1. 表单提交时method="POST"
2. ajax的post请求
3. Java代码的URL类的POST请求.请求的乱码问题
解决乱码的两种格式:
格式1.
可用于tomcat8版本之前的GET请求乱码 以及 所有版本的POST请求乱码:
解决方案: 将乱码的文字, 按照乱码的编码ISO-8859-1转换为字节数组, 再按照正常的编码UTF-8组装为 文字;
案例:
//1. 接收用户传递的参数
String username = request.getParameter("username");
//解决乱码
{
//1. 将乱码的文字, 通过ISO-8859-1编码 打碎成字节数组
byte[] bytes = username.getBytes("ISO-8859-1");
//2. 通过UTF-8编码, 将字节数组 重新组装为 正常文字
username = new String(bytes, "UTF-8");
}
格式2.
格式1 解决乱码适用于参数较少的情况, 如果参数过多, 解决起来极其麻烦.
tomcat为我们提供了 设置请求体编码的方式:
格式: request.setCharacterEncoding("UTF-8");
注意: 只有POST请求 ,才有请求体!
解决请求乱码的代码, 必须运行在获取参数之前 响应的乱码问题
方式1.
设置网页的内容类型, 以及 网页的编码格式:
response.setContentType("text/html;charset=utf-8");
方式2.
设置网页的编码格式 (因为没有设置网页内容类型为html , 所以浏览器解析时也是乱码)
response.setCharacterEncoding("UTF-8");
注意:
设置响应乱码的两种方式, 都必须写在 响应内容之前 !线程安全问题 :
Servlet的service方法, 每次被请求时, 调用.
这个调用很特殊 , 是在新的子线程中调用的 , 当service方法执行完毕, 子线程死亡了.
可以简单的理解为: service方法每次执行都是一个新的线程.
@WebServlet("/s1.do")
public class Servlet1 extends HttpServlet {
//剩余票数
private int count = 10;
Object o = new Object();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
synchronized (o) {
if(count>0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("恭喜你, 有票, 正在出票...");
count--;
System.out.println("出票完成, 剩余票数:"+count);
}else {
System.out.println("很遗憾, 无票");
}
}
}
}请求的 转发
概念: 一个web组件 将未处理完毕的请求, 通过tomcat转交给另一个web组件处理.
步骤:
1. 获取请求转发器
RequestDispatcher rd = request.getRequestDispatcher("转发的地址");
2. 通过转发器 发起转发
rd.forward(request,response);
简写步骤:
request.getRequestDispatcher("转发的地址").forward(request,response);
转发流程:
步骤1. 当浏览器访问服务器中tomcat时
步骤2. tomcat将请求信息, 与响应工具进行封装, 传递给我们的Servlet的service方法进行处理
步骤3. 我们在service方法中, 得到请求转发器, 通过请求转发器 告知 tomcat , 请求转发的地址.
步骤4. tomcat接收到请求转发需求, 会重新封装请求信息, 将请求对象 与 响应对象 传递给 转发地址的Servlet的service方法进行处理
特点:
1. 转发过程中, 多个Servlet之间共享一份请求信息, 共享一个响应对象.
2. 转发只能发生在同一个服务器中. (转发无法实现跨域)
3. 无论转发发生多少次 ,对于浏览器来说! 只发起过一次请求 , 并且只接到了一次响应.
4. 相对于重定向来说, 效率更高.请求的 重定向
概念: 响应时 , 告知浏览器新的请求地址, 浏览器接收到 自动请求新的地址 !
步骤:
response.sendRedirect("重定向地址");
重定向流程:
步骤1. 当浏览器访问服务时, 服务器对浏览器响应一个302的状态码, 以及一个location的地址
步骤2. HTTP协议约定 , 当浏览器接收到302状态码时 ,会自动寻找location地址, 并发起新的请求.
(相当于 控制用户浏览器 自动完成页面的跳转操作.)
特点
1. 重定向会产生新的请求 和 新的响应.
2. 使用重定向, 可以在多个服务器之间发生( 可以实现跨域操作 )
3. 浏览器地址栏的内容 会发生改变.
4. 相对于请求转发而言, 效率较低.注意:
1. 在一次用户的操作中, 可以无限制的进行转发和重定向, 但是记住: 一定要存在出口.
2. 当servlet中的请求已经被转发 / 重定向后, 在此servlet后续的代码中不能再进行响应 !HttpServletRequest 类常用操作:
1. 获取访问的客户端ip地址
String ip = request.getRemoteAddr();
2. 获取客户端访问的地址 (有可能因为服务器映射了多个域名, 多个用户的访问地址 不同)
request.getRequestURI();
3. 获取服务器的名称 (通常获取的是ip)
request.getServerName();
4. 获取端口号
request.getServerPort();
5. 获取请求的方式
String method = request.getMethod();
6. 获取get请求的参数列表 (网址中?后面的部分)
String params = request.getQueryString();
三个将请求对象 作为数据容器使用的方法:
1. 存储数据
request.setAttribute(String key,Object value);
2. 获取数据
Object value = request.getAttribute(String key);
3. 删除数据
request.removeAttribute(String key);ServletContext 上下文
每一个Servlet都是一个独立的用于处理请求的 对象.
为了便于多个Servlet之间的数据交流 . javaWeb提供了一个上下文对象ServletContext !
我们在任何的Servlet代码中, 都可以获得这个ServletContext对象 , 且每一个Servlet获取的都是同一份ServletContext对象.
上下文对象, 类似于我们SE所学习的MAP集合, 是一个键值对的容器.
作用: ServletContext是Servlet之间通信的桥梁, 用于多个Servlet之间信息的共享.如何从Servlet中得到上下文对象
格式:
ServletContext context = getServletContext();ServletContext的常用方法
1. 存储数据
context.setAttribute(String key,Object value);
2. 获取数据
Object value = context.getAttribute(String key);
3. 删除数据
context.removeAttribute(String key);
4. 获取项目运行时的 文件夹 绝对路径
String path = context.getRealPath("/");
//因为一个项目 只有一个ServletContext对象, 且在项目启动时创建了,项目销毁时销毁.
//所以我们在一次项目启动的过程中, 一个Servlet存储的数据, 任何Servlet都可以获取到.
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!