http状态码 ,rpc远程调用 ,静态资源防缓存,防盗链 ,重定向原理及使用,https 和http的区别

本文深入探讨HTTP与HTTPS协议的区别,包括请求与响应流程、状态码解释、资源加载优化、防盗链策略、重定向原理及HTTPS的安全机制。同时,提供实用的HTTP工具与调试技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http抓包工具 – fiddler、wireshark
http 请求工具 – Postmen(谷歌插件)、RestClient

1、HTTP状态码

200        请求成功
301        重定向,永久移动
302        重定向,临时移动
304        表示读取的缓存数据
401        无权访问
403        拒绝访问
404        找不到页面
405        请求方法不对
500        服务器异常/ 多为代码报错了

更多查看:http://tools.jb51.net/table/http_status_code

2.1、rpc远程调用,httpclient请求方式一(推荐)

pom.xml 依赖,按需添加
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!--  alibaba - fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.38</version>
        </dependency>
        
        <!-- json Obj -->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        
        <!-- httpclient  +  httpcore-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
发起请求

青云机器人接口说明:发不同的内容会不同的消息,类似于自动聊天功能
方法一,发起的get请求,参数直接放到了 url 上
方法二,发起的post请求,参数使用body 传递(传递参数为json串,这个不用理会),模拟了请求头 header 传递token 参数
**注意:**返回数据按需处理,我这返回的是json数据,使用转为了json

header 一般存放加密串,然后服务器解析加密串,通过验证才允许访问改接口内容


@SuppressWarnings("ALL")
public class qyRobot implements Serializable {

    public static void main(String[] args) {
        //get 请求测试
        String msg = httpGet("你好呀");
        System.out.println(msg);

        //post 请求测试
        Object obj = httpPost("你好呀");
        System.out.println(msg.toString());
    }

    /**
     * httpGet 请求,调用青云机器人接口
     *
     * @return 回复消息json串示例({"result":0,"content":"哟~ 都好都好"})
     * @Param 发送消息:msg
     */
    public static String httpGet(String msg) {
        String url = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=" + msg;
        //参数一,请求参数 new JSONObject() | 参数二,请求头参数 new HttpHeaders(),这里为空
        HttpEntity<String> httpEntity = new HttpEntity<String>(null, null);
        //发起请求
        ResponseEntity<String> responseEntity = new RestTemplate().exchange(url, HttpMethod.GET, httpEntity, String.class);
        Map<String, String> mapResponse = JSON.parseObject(responseEntity.getBody(), HashMap.class);
        //获得返回的json串
        String data = "";
        if (MapUtils.isNotEmpty(mapResponse)) {
            //获得数据
            data = JSON.toJSON(mapResponse).toString();
        }
        return data;
    }


    /**
     *  httpPost 请求
     * @param content
     * @return
     */
    public static Object httpPost(String content) {
        String url = "http://api.qingyunke.com/api.php?key=free&appid=0";
        //请求参数
        JSONObject params = new JSONObject();
        params.put("msg",content);
        //参数转json串
        String json = JSON.toJSONString(params);

        //请求头参数
        HttpHeaders headers = new HttpHeaders();
        headers.add("token","123456");

        //放入参数
        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> httpEntity = new HttpEntity<String>(json, headers);

        //发起请求获得回调Body参数,mapResponse
        ResponseEntity<String> responseEntity =
                restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        Map<String, String> mapResponse = JSON.parseObject(responseEntity.getBody(), HashMap.class);

        //参数不为空
        Object data = "";
        if (MapUtils.isNotEmpty(mapResponse)) {
            //返回的参数为Json串
            data = JSON.toJSON(mapResponse);
        }
        return data;
    }

}

main 方法测试结果
在这里插入图片描述

2.2、rpc远程调用,httpclient请求方式二

此请求方式代码比较乱,要用此方式的自己优化一下了,都和请求方式一大同小异,只不过api 不一样

maven 依赖
   <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>
测试代码
  • 要传的参数集
    params
  • 特殊字符需要转码
    URLEncoder.encode
  • post 请求
    HttpPost url = new HttpPost()
  • get请求(可把post改为get)
    HttpGet url = new HttpGet()
  • 返回值
    responseEntity
@Test
	public void doPostTestTwo() {

			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
			// 参数,字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
			StringBuffer params = new StringBuffer();
			try {
				params.append("uid=" + URLEncoder.encode("6548686156", "utf-8"));
				params.append("&&serverId="+1);
				params.append("&&steps="+112);
				params.append("&&msg="+"备注");
				params.append("&&emsg="+"英文提示备注");
				params.append("&&key=202cb962ac59075b964b07152d234b70");
			} catch (UnsupportedEncodingException e1) {
				e1.printStackTrace();
			}
			HttpPost url = new HttpPost("http://192.168.103.7:88/web/wastageRate/sava"+"?"+params);
			url.setHeader("Content-Type", "application/text;charset=utf8");
			// 响应模型
			CloseableHttpResponse response = null;
			try {
				// 由客户端执行(发送)Post请求
				response = httpClient.execute(url);
				HttpEntity responseEntity = response.getEntity();
				System.out.println("响应状态为:" + response.getStatusLine());
				if (responseEntity != null) {
					System.out.println("响应内容长度为:" + responseEntity.getContentLength());
					System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
				}
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (httpClient != null) {
						httpClient.close();
					}
					if (response != null) {
						response.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
	}

3、http静态资源防缓存(时间戳)

加载css/js 静态资源一般浏览器都有缓存的
我们修改了 css/js 文件并不会生效,而要清空缓存才会生效
这时我们可以添加时间戳
这样每次请求浏览器都会默认会是新的地址,重新读取静态资源数据
注意事项:
1、静态文件加载应该定义公共方法,写一个页面单独加载
2、每次重新加载会增大资源开销,应避免改问题
3、公共方法目的为可设置是否添加时间戳/ 是否使用缓存,不需要的时候方便关闭,或不需要使用的静态文件不添加时间戳

----thymeleaf 模板添加时间戳写法

原写法
<link rel="stylesheet" href="../layuiadmin/layui/css/layui.css?time=1" media="all">
现写法
<link rel="stylesheet" th:href="@{../layuiadmin/layui/css/layui.css(time=${new java.util.Date().getTime()})}" media="all">

每次刷新页面时间戳都会改变
在这里插入图片描述
其他框架/ 模板什么的,像VUE/ jsp 什么的添加时间戳写法百度找看看

4、http防盗链(防止静态资源被盗用)

防盗链就是盗用其他网站的静态资源,如图片等,自己网站的资源也可能被盗用
解决办法
添加过滤器
获取请求来源, 判断来源
在这里插入图片描述

添加过滤器

1)过滤器(Filter)说明
它依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等

2、拦截器(Interceptor)说明
拦截器的配置一般在SpringMVC的配置文件中,使用Interceptors标签
拦截器(Interceptor):它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理

public class ImgFilter implements Filter {

	public void destroy() {
		// TODO Auto-generated method stub

	}

   /**
   *过滤器
   */
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
			
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;
		
		//获得url 来源
		String referer = request.getHeader("referer");
		System.out.println("refer is" + "" + referer);
		
		//request.getServerName() 
		//相当于当前服务器来源,ip 或 请求地址
		if (referer == null || !referer.contains(request.getServerName())) {
		     //不是当前当前服务器获取资源,被非法盗用,重定向到静态资源/ 提示图片告诉对方不要盗用
			request.getRequestDispatcher("/static/error.png").forward(request, response);
		} else {
		    //放行
			filterChain.doFilter(request, response);
		}
	}


	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

}

5、重定向原理及使用

重定向一般为外部服务器使用
转发一般在内部服务器使用

在这里插入图片描述


//转发=页面跳转  -->  http://localhost:8080/reqresp_demo/dir1/1.html
request.getRequestDispatcher("/dir1/1.html").forward(request, response);	

//重定向,又叫客户端的跳转,显著特征是地址栏发生变化 -->response.sendRedirect("/reqresp_demo5/1.html");
response.sendRedirect("http://www.baidu.com");
	
		/**
		 * forward(转发) 和 redirect (重定向)的区别
		 * forward: 是服务器端的跳转,地址栏不发生变化
		 * redirect: 客户端的跳转,地址栏发生变化
		 */
		 
springboot 重定向 || 转发
@RequestMapping("/deleteId")
	public String deleteId(Integer id) throws ServletException, IOException {
	
	 	//重定向本服务器  -->   /user/user 接口
		//return "redirect:/user/user";   
		
		//重定向外服务器        
		//return "redirect:https://www.baidu.com";
	
		//转发 
		return "forward:/user/user";
	}

响应体说明

Location: http://www.it315.org/index.jsp  --表示重定向的地址,该头和302的状态码一起使用。
Server:apache tomcat                      --表示服务器的类型
Content-Encoding: gzip                    -- 表示服务器发送给浏览器的数据压缩类型
Content-Length: 80                        --表示服务器发送给浏览器的数据长度
Content-Language: zh-cn                   --表示服务器支持的语言
Content-Type: text/html; charset=GB2312   --表示服务器发送给浏览器的数据类型及内容编码
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT      --表示服务器资源的最后修改时间
Refresh: 1;url=http://www.it315.org               --表示定时刷新
Content-Disposition: attachment; filename=aaa.zip --表示告诉浏览器以下载方式打开资源(下载文件时用到)
Transfer-Encoding: chunked
Set-Cookie:SS=Q0=5Lb_nQ; path=/search   --表示服务器发送给浏览器的cookie信息(会话管理用到)
Expires: -1                             --表示通知浏览器不进行缓存
Cache-Control: no-cache
Pragma: no-cache
Connection: close/Keep-Alive            --表示服务器和浏览器的连接状态。close:关闭连接 keep-alive:保存连接

6、https 和http的区别

https 请求过程
在这里插入图片描述

https 和 http 比较
  1、https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。
 2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
 3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
 4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
https工作原理
我们都知道 HTTPS 能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用 HTTPS 协议。
客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤,如图所示。
  (1)客户使用 https 的 URL 访问 Web 服务器,要求与 Web 服务器建立 SSL 连接。
  (2)Web 服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
  (3)客户端的浏览器与 Web 服务器开始协商 SSL 连接的安全等级,也就是信息加密的等级。
  (4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
  (5)Web 服务器利用自己的私钥解密出会话密钥。
  (6)Web 服务器利用会话密钥加密与客户端之间的通信。

https优缺点
 虽然说 HTTPS 有很大的优势,但其相对来说,还是存在不足之处的:
  (1)HTTPS 协议握手阶段比较费时,会使页面的加载时间延长近 50%,增加 10% 到 20% 的耗电;
  (2)HTTPS 连接缓存不如 HTTP 高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
  (3)SSL 证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
   (4)SSL 证书通常需要绑定 IP,不能在同一 IP 上绑定多个域名,IPv4 资源不可能支撑这个消耗。
  (5)HTTPS 协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值