前言:
想了解 HTTP协议内容的可以参考:
https://blog.csdn.net/qq_38409944/article/details/80628723
URL: 统一资源定位符。http://localhost:8080/day09/testImg.html。只能定位互联网资源。是URI的子集。
URI: 统一资源标记符。/day09/hello。用于标记任何资源。可以是本地文件系统,局域网的资源(//192.168.14.10/myweb/index.html),可以是互联网。
首先看一下Get和Post之间的差异:
注意:当页面刷新的时候,数据会自动重新提交,但是没有提醒
Get:
GET提交参数数据有限制,不超过1KB。
GET方式不适合提交敏感密码。
浏览器直接访问的请求,默认提交方式是GET方式
地址栏(URI)会跟上参数数据。以?开头,多个参数之间以&分割。
POST:
POST提交的参数数据没有限制。
POST方式提交敏感数据。
参数不会跟着URI后面。参数而是跟在请求的实体内容中。
没有?开头,多个参数之间以&分割。
表单的话 一般都是POST提交。
GET提交的话 账号密码都会显示在URL中,如:
http://localhost:8080/haha/zz?name=11&password=d
而POST提交的话,账号密码不会显示,而是放在HTTP协议中的实体内容中
看一下前后台交互的原理图:
核心的API:
请求行:
request.getMethod(); 请求方式 GET 还是POST
request.getRequetURI() 请求资源的URI位置
// request.getRequetURL() 请求资源的URL位置
request.getProtocol() 请求http协议版本
请求头:
request.getHeader("名称") 根据请求头获取请求值
request.getHeaderNames() 获取所有的请求头名称
实体内容:
request.getInputStream()
获取实体内容数据 主要是POST获取账号密码。
首先创建表单:
<body>
<form action="/haha/zz" method="get">
<input type="text" name="name"/>
<input type="password" name="password" />
<input type="submit" value="tijiao" />
</form>
<form action="/haha/zz" method="post">
<input type="text" name="name"/>
<input type="password" name="password" />
<input type="submit" value="tijiao" />
</form>
</body>
注意:
action="/haha/zz"中 haha
是项目名字 zz
是在src中创建的servlet文件
其实action填的是你要传递的URI位置。
如:
http://localhost:8080/haha/zz
/haha/zz取得就是8080后面的URI位置。
Servlet:
HttpServletRequest对象接受前台 Http请求,包括请求行,请求头(多个key-value对象),可选)实体内容。 Http请求数据被包装在 HttpServletRequest对象中。
package a;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
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("/zz")
public class zz extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
t1(request);
t2(request);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
t1(request);
t2(request);
t3(request);
}
private void t3(HttpServletRequest request) throws IOException {
InputStream inputStream=request.getInputStream();
byte[] buffer=new byte[1024];
int len=0;
while((len=inputStream.read(buffer))!=-1) {
String string=new String(buffer, 0, len);
System.out.println(string);
}
}
private void t2(HttpServletRequest request) {
Enumeration<String> enumeration=request.getHeaderNames();
while(enumeration.hasMoreElements()) {
String name=enumeration.nextElement();
String content=request.getHeader(name);
System.out.println(name+" "+content);
}
}
private void t1(HttpServletRequest request) {
System.out.println(request.getMethod());
System.out.println(request.getRequestURI());
System.out.println(request.getRequestURL());
System.out.println(request.getProtocol());
}
}
输出请求行函数:
private void t1(HttpServletRequest request) {
System.out.println(request.getMethod());
System.out.println(request.getRequestURI());
System.out.println(request.getRequestURL());
System.out.println(request.getProtocol());
}
请求头:
private void t2(HttpServletRequest request) {
Enumeration<String> enumeration=request.getHeaderNames();
while(enumeration.hasMoreElements()) {
String name=enumeration.nextElement();
String content=request.getHeader(name);
System.out.println(name+" "+content);
}
}
实体内容函数:
private void t3(HttpServletRequest request)
throws IOException {
InputStream inputStream=request.getInputStream();
byte[] buffer=new byte[1024];
int len=0;
while((len=inputStream.read(buffer))!=-1) {
String string=new String(buffer, 0, len);
System.out.println(string);
}
}
总结:
1. POST实体内容即t3得到的是输入的账号和密码。
而GET实体内容一般无内容 因为账号和密码会显示在URL框内了
2. 如果修改了表单或者Servlet,只要直接ctrl+S保存就行,
然后等待Tomcat自动更新下即可。
3. doGet(HttpServletRequest request,
HttpServletResponse response)是GET格式,调用服务器的方法。
doPost(HttpServletRequest request,
HttpServletResponse resp)是POST格式,调用服务器的方法
4. 浏览器默认是GET格式,所以当你启动servlet的时候,
默认是调用doGet方法
5. 当你点击提交按钮的时候,页面会跳转到servlet页面,
然后根据Get还是Post来选择调用doGet还是doPost方法。
servlet中的service()方法重写与不重写:
在servlet中默认情况下,无论你是get还是post 提交过来 都会经过service()方法来处理,然后转向到doGet或是doPost方法
从上面可以看出 这里的service是用来转向的,但是如果你在自己的servlet类中覆盖了service方法,比如说你的service是这样的:
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.getOutputStream().print(
"image is <img src='images/downcoin.gif'></img><br>");
}
那么这时service就不是用来转向的,而是用来处理业务的,现在不论你的客户端是用pos还是get来请求此servlet
都会执行service方法也只能执行servlet方法,不会去执行doPost或是doGet方法。
要是你以后写servlet,最好不要重写service方法啊
为什么不应该重写service方法,似乎是为了保留HttpServlet默认实现的缓存协商的机制;其实还有另外一个原因:就是禁用你没有在servlet中重写的方法,例如post、head等,这样就从一定程度上提高了安全性。
参考:
https://my.oschina.net/dtkking/blog/89443