HTTP协议简介
http(Hypertext transfer protocol)超文本传输协议,通过浏览器和服务器进行数据交互,进行超文本(文本、图片、视频等)传输的规定。也就是说,http协议规定了超文本传输所要遵守的规则。但HTTP协议的本质是一段在网络环境中传输的文本,这段文本包含特定的格式。这些格式包括请求行,请求头,请求体等等。
在http请求中比较常用的请求方法是get请求与post请求。
在java web中:
如果是get请求,参数需要拼接在URL的查询字符串中才能被服务器端接收。
如果是post请求,在请求体与URL中的查询字符串中携带的参数都可以被服务器端接收。
在发送get请求时,客户端向服务器端传递的参数一般是通过URL中的查询字符(querystring)串携带的,在请求体中的参数服务器端是接收不到的。在发送post请求时 ,查询字符串与请求体中的参数都可以被接收到,我们写一个Servlet来验证一下tomcat是如何获取get与post请求中的参数的。
get请求实验
servlet代码:
package com.haojie.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String queryString = req.getQueryString();
System.out.println("queryString="+queryString);
System.out.println("username="+req.getParameter("username"));
System.out.println("password="+req.getParameter("password"));
System.out.println("age="+req.getParameter("age"));
System.out.println("address="+req.getParameter("address"));
}
}
postman发送get请求
如上图所示,用postman发送一个get请求,在查询字符串中传递username与password这两个参数,在请求体中携带age与address这两个参数
servlet中 接收get请求参数结果
运行结果如上图所示,在servlet中没有获取到请求体中传递的参数
通过socket接收get请求
我们通过自己写的socket程序来接收postman发送的http请求,看看打印的http协议是怎么样的。
package com.haojie.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpListener {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
Socket clntSock = serverSocket.accept();
InputStream input = clntSock.getInputStream();
OutputStream output= clntSock.getOutputStream();
StringBuffer request = new StringBuffer(2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
} catch (IOException e) {
e.printStackTrace();
i = -1;
}
for (int j = 0; j < i; j++) {
request.append((char) buffer[j]);
}
// 打印http协议内容
System.out.println(request);
// file not found
String errorMessage = "HTTP/1.1 200 success
" +
"Content-Type: text/html
" +
"Content-Length: 23
" +
"
" +
"<h1>success</h1>";
output.write(errorMessage.getBytes());
clntSock.close();
}
}
运行结果如下:
从上图中我们可以看到,postman发送的http get请求,这个请求中的请求体与查询参数传递的值传递到了服务器端。由此可以知道,http 协议的get请求的请求体也可以携带参数,只是tomcat在遇到get请求时没有从请求体中取参数。
post请求实验
代码:
package com.haojie.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String queryString = req.getQueryString();
System.out.println("queryString="+queryString);
System.out.println("username="+req.getParameter("username"));
System.out.println("password="+req.getParameter("password"));
System.out.println("age="+req.getParameter("age"));
System.out.println("address="+req.getParameter("address"));
}
}
postman发送post请求
如上图所示,通过postman发送post请求,在查询字符串与请求体中都传参
接收post请求结果
可以看到,在servlet中,通过查询参数与请求体中传递的参数都可以接收到。
通过socket接收post请求
代码:
package com.haojie.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpListener {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
Socket clntSock = serverSocket.accept();
InputStream input = clntSock.getInputStream();
OutputStream output= clntSock.getOutputStream();
StringBuffer request = new StringBuffer(2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
} catch (IOException e) {
e.printStackTrace();
i = -1;
}
for (int j = 0; j < i; j++) {
request.append((char) buffer[j]);
}
// 打印http协议内容
System.out.println(request);
// file not found
String errorMessage = "HTTP/1.1 200 success
" +
"Content-Type: text/html
" +
"Content-Length: 23
" +
"
" +
"<h1>success</h1>";
output.write(errorMessage.getBytes());
clntSock.close();
}
}
socket接收post请求结果图:
总结
在http协议中,get请求与post请求都可以在URL与请求体中携带参数,如果是tomcat来接收http协议,tomcat在遇到get请求时,不会去请求体中获取请求参数,因此在tomcat环境中,不能在get请求的请求体中传递参数,而在post请求时,URL与请求体都可以传递参数。