您好,欢迎访问一九零五行业门户网

如何使用Java中的httpclient进行重定向和请求转发的比较

这里介绍一下:httpclient 4.x 版本,get请求方法会自动进行重定向,而post请求方法不会自动进行重定向,这是要注意的地方。我上次发生错误,就是使用post提交表单登录,当时没有自动重定向。
请求转发和重定向的区别1、重定向是两次请求,转发是一次请求,因此转发的速度要快于重定向。
2、重定向之后地址栏上的地址会发生变化,变化成第二次请求的地址,转发之后地址栏上的地址不会变化,还是第一次请求的地址。
3、转发是服务器行为,重定向是客户端行为。重定向时浏览器上的网址改变 ,转发是浏览器上的网址不变。
4、重定向是两次request,转发只有一次请求。
5、重定向时的网址可以是任何网址,转发的网址必须是本站点的网址。
这里重点看第三条和第四条。
http报文包含响应码、响应头和响应体。 这里只说 200 和 302. 响应码:2xx(一般是200)。表示请求成功,然后就可以接受响应的数据。 响应码:3xx(一般为302)。表示重定向,服务器会要求客户端重新发送一个请求,服务器会发送一个响应头 location,它指定了新请求的 url 地址。(这里很重要!客户端需要通过 location 头,获取重定向的地址。)
这里并没有提及请求转发,因为请求转发是一种服务器端的操作,它是在服务器内部进行操作的,所以就是一次请求(在客户端看和普通的请求没有区别)。而重定向不同,它是客户端的操作,因为服务器要求客户端重新发送一次请求,所以重定向是两次请求。这也解释了为什么重定向后请求参数会丢失,因为根本不是一次请求。我这里说客户端,并不说浏览器,因为我们有时不一定会使用浏览器作为客户端,比如爬虫也是是一个客户端了。
但是,对于刚开始学习的时候,或者对于普通用户来说,似乎感觉不出来二者的区别,最多是可以发现浏览器地址是否改变。请求转发浏览器地址不变,而重定向浏览器地址会变化为新的地址。(但是在这个过程中并未体现重定向的两次请求,这是因为浏览器自动帮我们进行了重定向。)
下面以java编程来看看二者的区别:上面的第三条和第四条。
java web 部分testservlet 类提供一个简单的 servlet 类,它的功能和简单,它会携带一个 key 参数,如果该参数存在且值为 “1”,那么就进行请求转发到 “/dispatcher.jsp” 页面;否则,就重定向到 “redirect.jsp” 页面。
package com.study;import java.io.ioexception;import javax.servlet.servletexception;import javax.servlet.annotation.webservlet;import javax.servlet.http.httpservlet;import javax.servlet.http.httpservletrequest;import javax.servlet.http.httpservletresponse;@webservlet("/testservlet")public class testservlet extends httpservlet { private static final long serialversionuid = 1l; protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { request.setcharacterencoding("utf-8"); string key = request.getparameter("key"); if((key != null && key.equals("1"))) { system.out.println("请求转发:key " + key); //请求转发 request.getrequestdispatcher("/dispatcher.jsp").forward(request,response); }else { //重定向 response.sendredirect("redirect.jsp"); system.out.println("重定向:key " + key); } } protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { doget(request, response); }}
dispacher.jsp
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%><!doctype html><html><head><meta charset="utf-8"><title>请求转发</title></head><body><h2>请求转发</h2></body></html>
redirect.jsp
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%><!doctype html><html><head><meta charset="utf-8"><title>重定向</title></head><body><h2>重定向</h2></body></html>
启动项目测试我这里的目的主要是请求转发和重定向的访问区别,并不是比较它们二者的其它区别,所以示例很简单。
测试请求地址:http://localhost:8080/study/testservlet?key=1
注意:请求地址无变化。
测试请求地址:http://localhost:8080/study/testservlet?key=2 注意:请求地址发生了变化。
这样的话,是看不出来二者在访问上有什么区别的,但是看不到,不代表它们没有区别,下面通过代码来查看二者在访问方式上的区别。
使用 httpclient301 moved permanently(永久移动)
302 found(发现)
303 see other(查看其他)
307 temporary redirect(临时重定向)
由于 httpclient 4.x 版本会自动重定向,所以我们必须关闭自动重定向,才能跟踪重定向的过程。
在 requestconfig 里面设置,并设置超时时间(三个)。
//httpclient4.3中默认允许自动重定向,导致程序中不能跟踪跳转情况。int timeout = 10*1000;requestconfig config = requestconfig.custom() .setsockettimeout(timeout) .setconnecttimeout(timeout) .setconnectionrequesttimeout(timeout) .setredirectsenabled(false) //关闭自动重定向,默认值为true。 .build();
然后发送请求时,设置并允许自动重定向。
//创建get请求对象httpget getmethod = new httpget(url);//设置请求方法关闭自动重定向getmethod.setconfig(config); //配置信息
这样当我们访问路径为:http://localhost:8080/study/testservlet?key=1
服务器会进行请求转发,但是这是服务器行为,与客户端没有关系,所以我们不用关心,在请求正确的情况下,响应码为 200。
测试结果:
当我们访问路径为:http://localhost:8080/study/testservlet?key=2,服务器会要求客户端进行重定向(即要求客户端请求另一个地址),这时会先收到状态码 302,当再次访问成功时状态码为 200(当然了,也许重定向不止一次,但是浏览器会对重定向次数有限制)。
如果发生了重定向,我们需要获取响应头中的 location 字段,这里面是重定向的地址。
//读取新的 url 地址header header = response.getfirstheader("location");string newurl = header.getvalue();
注意:重定向是可以访问服务器外的地址的,服务器内部的地址一般是相对地址,需要拼接 url,服务器外就是绝对 url 了。
测试结果:
完整测试代码package com.learn;import java.io.ioexception;import org.apache.http.header;import org.apache.http.httpentity;import org.apache.http.httpstatus;import org.apache.http.parseexception;import org.apache.http.client.config.requestconfig;import org.apache.http.client.methods.closeablehttpresponse;import org.apache.http.client.methods.httpget;import org.apache.http.impl.client.closeablehttpclient;import org.apache.http.impl.client.httpclients;import org.apache.http.util.entityutils;public class testredirect { /** * 重定向是客户端操作,而请求转发是服务端操作 。 * 但是通常用户使用浏览器,并不注意二者的区别, * 这是因为浏览器自动帮我们重定向了。(当然了, * 编程还是需要注意的)。 * @throws ioexception * @throws parseexception * */ public static void main(string[] args) throws parseexception, ioexception { string root = "http://localhost:8080/study/"; //网站的根路径,因为重定向得到的是相对路径(服务器内部的路径) //httpclient4.3中默认允许自动重定向,导致程序中不能跟踪跳转情况。 int timeout = 10*1000; requestconfig config = requestconfig.custom() .setsockettimeout(timeout) .setconnecttimeout(timeout) .setconnectionrequesttimeout(timeout) .setredirectsenabled(false) //关闭自动重定向,默认值为true。 .build(); string url = "http://localhost:8080/study/testservlet?key=1"; //请求转发。 //创建 httpclient 对象 closeablehttpclient httpclient = httpclients.createdefault(); //创建get请求对象 httpget getmethod = new httpget(url); getmethod.setconfig(config); //配置信息 //执行请求,得到响应信息 try (closeablehttpresponse response = httpclient.execute(getmethod)) { httpentity entity = null; int statuscode = response.getstatusline().getstatuscode(); system.out.println("返回值状态码:" + statuscode); if (statuscode == httpstatus.sc_ok) { //获取请求转发的实体信息 entity = response.getentity(); if (entity != null) { system.out.println(entityutils.tostring(entity, "utf-8")); } } else if (statuscode == httpstatus.sc_moved_temporarily) { //读取新的 url 地址 header header = response.getfirstheader("location"); system.out.println(header); if (header != null) { string newurl = header.getvalue(); if (newurl != null && !newurl.equals("")) { //使用get方法转向。 httpget redirectget = new httpget(root+newurl); system.out.println("重定向到新的地址:" + redirectget.geturi()); redirectget.setconfig(config); //发送请求,做进一步处理。。。 try (closeablehttpresponse redirectres = httpclient.execute(redirectget)) { statuscode = redirectres.getstatusline().getstatuscode(); system.out.println("返回值状态码:" + statuscode); if (statuscode == httpstatus.sc_ok) { //获取请求转发的实体信息 entity = redirectres.getentity(); if (entity != null) { system.out.println(entityutils.tostring(entity, "utf-8")); } } } } } } } }}
以上就是如何使用java中的httpclient进行重定向和请求转发的比较的详细内容。
其它类似信息

推荐信息