想了解 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之间的差异: 注意:当页面刷新的时候,数据会自动重新提交,但是没有提醒
表单的话 一般都是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中默认情况下,无论你是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