本篇文章是通过实现三个功能来学习HTTP协议
- 学习GET提交方式和POST提交方式的区别
- 通过控制哪些源可以访问相关链接,来实现防止盗链
- 实现压缩流的传输数据
首先是一个项目中的主页 index.jsp文件,代码如下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>HTTP协议演示</title>
</head>
<body>
<a href="/httpWebDemo/get_post?name=poop&pwd=qwer">所有超链接都是GET方式的请求</a> <br/>
<h3>表单的默认提交方式是:GET</h3>
<form action="get_post">
Name:<input type="text" name="name" /> <br/>
Pwd:<input type="password" name="pwd" /> <br/>
<input type="submit" value="提交"/>
</form>
<hr/>
<h3>如果要让表单以POST方式提交,得设置method属性</h3>
<form action="get_post" method="post">
Name:<input type="text" name="name" /> <br/>
Pwd:<input type="password" name="pwd" /> <br/>
<input type="submit" value="提交"/>
</form>
<hr/>
<a href="show" >看美女图</a>
<hr/>
<a href="gzip" >页面内容压缩输出演示---http协议中的gzip</a>
</body>
</html>
配置文件web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>cn.hncu.servlets.HelloServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>show</servlet-name>
<servlet-class>cn.hncu.servlets.ShowImgServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>GzipServlet</servlet-name>
<servlet-class>cn.hncu.servlets.GzipServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/get_post</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>show</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GzipServlet</servlet-name>
<url-pattern>/gzip</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
实现真正服务的JAVA实现类
学习GET提交方式和POST提交方式的区别
简单来说:就是通过req.getMethod();拿到提交方式 ,在进行其他的具体操作,因为我们使用的是Tomcat服务器,所以存在中文乱码问题(数据经过欧洲编码成的字符),两种方式解决不同,get方式解决是通过 把name(数据) 再经过一次欧洲编码还原成byte数据,然后重新用我们习惯的编码(支持中文)来解决。Post方式 有专门写好的方法。代码如下
package cn.hncu.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
System.out.println(method);
if(method.equals("GET")){
System.out.println("GET方式的请求");
//req.setCharacterEncoding("UTF-8");//GET方式下这样设置是乱码
String name = req.getParameter("name");
//下面两句解决name的中文乱码
byte b[] = name.getBytes("iso8859-1");
name = new String(b,"utf-8");
String pwd = req.getParameter("pwd");
System.out.println(name+","+pwd);
}
if(method.equals("POST")){
System.out.println("POST方式的请求");
//下面一句可以解决POST方式下所有参数的中文乱码 ---注意,参数编码要和前端页面的编码相同,如页面设置“pageEncoding="GBK"”,则此处得用"GBK"
req.setCharacterEncoding("UTF-8");//只有POST方式下才有用
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
System.out.println(name+","+pwd);
}
//resp.getWriter().println(method);
}
}
2. 通过控制哪些源可以访问相关链接,来实现防止盗链
通过`
req.getHeader("Referer");//读取浏览器发过来的请求头 ---其它协议头的读取方式类似
拿到访问源信息,再来进行判断,是否允许继续访问图片。
时刻注意中文乱码问题
package cn.hncu.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
※※玩转http协议:
req.getHeader("请求头-key","请求头-value");
resp.setHeader("响应头-key","响应头-value");
※至于请求头或响应头的key和value值,如果是常用的可以直接从浏览器的监控工具看到,复杂的请查看相关文档
*/
public class ShowImgServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String referer = req.getHeader("Referer");//读取浏览器发过来的请求头 ---其它协议头的读取方式类似
//System.out.println(referer);
String str="";
if(referer==null){
str="请访问主页!---请先看广告";
}else{
if(referer.contains("192.168.31.168") || referer.contains("www.hncu.cn")){//正版页面标识大家可以自己根据实际项目需求进行变化
str="<img src='imgs/back.gif'></img><br/>";
str +="<img src='imgs/3.gif'></img><br/>";
str +="<img src='imgs/1.jpg'></img><br/>";
str +="<img src='imgs/2.jpg'></img><br/>";
}else{
str="你是盗链,请尊重版权!";
}
}
//输出
//设置输入页面的编码,否则乱码 ---利用http协议的响应头设置来实现
//resp.setHeader("Content-Type","text/html;charset=utf-8" );
resp.setContentType("text/html;charset=utf-8");//本质上和上面一行一样
PrintWriter pw = resp.getWriter();
pw.println(str);
}
}
3. 实现压缩流的传输数据
内存流 内部包一个 压缩流 GZIPOutputStream 然后 再把数据写进压缩流,再从内存流读出来,时刻注意中文乱码问题!!!!
我画了个图,我是这样理解
代码如下
package cn.hncu.servlets;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String str="马上要下课,大家又解放了....马上要下课,大家又解放了....马上要下课,大家又解放了....啦拉啦!!!";
byte src[] = str.getBytes("utf-8");//把要输出的信息存入src[]字节数组中
ByteArrayOutputStream bout = new ByteArrayOutputStream();//内存流
GZIPOutputStream gout = new GZIPOutputStream(bout);
gout.write(src);//把src[]中的数据压缩输出到gout,由于是流套接因此实际上是输出到bout中
gout.close();//注意,这里要关流(刷缓存),否则数据不一定完整写出去
System.out.println("压缩前的数据长度:"+src.length);
byte dest[] = bout.toByteArray(); //把内存流bout中的数据取出来---压缩后的数据
System.out.println("压缩后的数据长度:"+dest.length);
resp.setContentType("text/html;charset=utf-8");//设置输出页面的编码
//设置响应头---利用http协议头告诉浏览器现在发送的是gzip格式的数据
resp.setHeader("Content-Encoding", "gzip");
//把dest[]输出到前端页面
OutputStream out = resp.getOutputStream();//字节流
out.write(dest);
}
}