当前位置:

首页 > 编程开发 > Java怎么通过httpclient比较重定向和请求转发

Java怎么通过httpclient比较重定向和请求转发

这里介绍一下:HttpClient4.x版本,get请求方法会自动进行重定向,而post请求方法不会自动进行重定向,这是要注意的地方。我上次发生错误,就是使用post提交表单登录,当时没有自动重定向。请求转发和重定向的区别1、重定向是两次请求,转发是一次请求,因此转发的速度要快于重定向。2、重定向之后地址栏上的地址会发生变化,变化成第二次请求的地址,转发之后地址栏上的地址不会变化,还是第一次请求的地址。3、转发是服务器行为,重定向是客户端行为。重定向时浏览器上的网址改变,转发是浏览器上的网址不变。4、重定

本文目录

    这里介绍一下: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"%>
    
    
    
    
    请求转发
    
    
    

    请求转发

    redirect.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    
    
    
    
    重定向
    
    
    

    重定向

    启动项目测试

    我这里的目的主要是请求转发和重定向的访问区别,并不是比较它们二者的其它区别,所以示例很简单。

    测试请求地址:http://localhost:8080/study/TestServlet?key=1

    注意:请求地址无变化。

    Java怎么通过httpclient比较重定向和请求转发

    测试请求地址:http://localhost:8080/study/TestServlet?key=2 注意:请求地址发生了变化。

    Java怎么通过httpclient比较重定向和请求转发

    这样的话,是看不出来二者在访问上有什么区别的,但是看不到,不代表它们没有区别,下面通过代码来查看二者在访问方式上的区别。

    使用 HttpClient

    • 301 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。

    测试结果:

    Java怎么通过httpclient比较重定向和请求转发

    当我们访问路径为:http://localhost:8080/study/TestServlet?key=2,服务器会要求客户端进行重定向(即要求客户端请求另一个地址),这时会先收到状态码 302,当再次访问成功时状态码为 200(当然了,也许重定向不止一次,但是浏览器会对重定向次数有限制)。

    如果发生了重定向,我们需要获取响应头中的 Location 字段,这里面是重定向的地址。

    //读取新的 URL 地址
    Header header = response.getFirstHeader("location");
    String newUrl = header.getValue();

    注意:重定向是可以访问服务器外的地址的,服务器内部的地址一般是相对地址,需要拼接 URL,服务器外就是绝对 URL 了。

    测试结果:

    Java怎么通过httpclient比较重定向和请求转发

    完整测试代码

    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"));
    								}
    							}
    						}
    					}
    				}
    			} 
    		}
    	}
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java httpclient
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。