servlet 怎么获取http post 的body

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了servlet 怎么获取http post 的body相关的知识,希望对你有一定的参考价值。

头部信息已经封装到了request对象中,可以直接获龋 String value = request.getHeader("HTTP头中key值"); Enumeration e = request.getHeaderNames(); //获取所有的key 容器会将信息封装到request,并且做了合理的拆分和处理,给你省了不少事追问

我问的是怎么拿http post请求的request body块 不是请求头的信息

参考技术A 1.服务器认证(Server Authentication)
HttpClient处理服务器认证几乎是透明的,仅需要开发人员提供登录信息(login credentials)。登录信息保存在HttpState类的实例中,可以通过 setCredentials(String realm, Credentials cred)和getCredentials(String realm)来获取或设置。
HttpClient内建的自动认证,可以通过HttpMethod类的setDoAuthentication(boolean doAuthentication)方法关闭,而且这次关闭只影响HttpMethod当前的实例。

2.代理认证(proxy authentication)
除了登录信息需单独存放以外,代理认证与服务器认证几乎一致。用 setProxyCredentials(String realm, Credentials cred)和 getProxyCredentials(String realm)设、取登录信息。

3.认证方案(authentication schemes)
是HTTP中规定最早的也是最兼容的方案,遗憾的是也是最不安全的一个方案,因为它以明码传送用户名和密码。它要求一个UsernamePasswordCredentials实例,可以指定服务器端的访问空间或采用默认的登录信息。

Servlet --- [HTTP协议,HTTP请求]



HTTP协议


超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议(服务器传输超文本到本地浏览器的传送协议),它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。
用于定义客户端浏览器和服务器之间交换数据的过程。
HTTP是基于TCP/IP通信协议来传递数据.
HTTP是属于应用层的协议,由于简捷快速,适用于分布式超媒体信息系统.

HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程
(1)客户与服务器建立连接;
(2)客户向服务器提出请求;
(3)服务器接受请求,并根据请求返回相应的文件作为应答;
(4)客户与服务器关闭连接。


HTTP请求


客户端连上服务器后,向服务器请求某个web资源(网页 或 servlet),称之为客户端向服务器发送了http请求。


请求包括:请求行,请求头,请求体


请求行

请求行包含http请求方式,请求资源名称,http版本 (例如post test.jsp HTTP/1.1)

请求方法注释
GET请求指定的页面信息,并返回实体主体。
HEAD类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
PUT从客户端向服务器传送的数据取代指定的文档的内容。
DELETE请求服务器删除指定的页面。
CONNECTHTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS允许客户端查看服务器的性能。
TRACE回显服务器收到的请求,主要用于测试或诊断。
PATCH是对 PUT 方法的补充,用来对已知资源进行局部更新 。

请求头

请求头包含主机地址,以及客户端的一些环境信息,以键值对的形式传递.

Host: 127.0.0.1:8088 请求的主机地址
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 浏览器能够处理的内容类型
Accept-Encoding: gzip, deflate, br 浏览器能够处理的压缩编码
Accept-Language: zh-CN,zh;q=0.9 浏览器当前设置的语言
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 使用的浏览器和操作平台信息
Connection: keep-alive 浏览器与服务器之间连接的类型


请求体


请求体代表着浏览器在post请求方式中传递给服务器的参数,请求体中参数以键值形式传递, 多个用&链接,服务器接收到后再解析.


案例:启动Tomcat服务器,运行之前写的登录jsp;链接

在页面输入数据后,点击登录,地址栏链接出现账号密码的参数

打开F12调试,点击Network,点击Name下的;

注意到,这里默认的请求方式是GET方式


现在去jsp文件,把表单提交的请求方式改为POST方式.

启动浏览器,输入数据,点击登录.地址栏链接没有出现提交的参数信息

然后再进行F12的网络调试Network

还出现了Form Data一栏,展示输入的数据;即请求体


关于超链接访问

在页面写入超链接,提交到的配置servlet也是login;对应到映射文件处.

运行服务器后,点击页面上的超链接;打开F12调试,发现请求方式为默认的GET

超链接,提交表单都是http请求

请求包含,请求行,请求头,请求体(位于表单的post提交方式)


关于HTTP的请求方式GET 与POST 的区别


将http请求分为 get,post请求;

get:

  • 超链接访问方式;
  • 在地址栏直接输入地址进行访问的方式;
  • js中;浏览器对象,window.open(url) ; location.replace(url) ;location.assign(url)
  • 提交表单时不指定method方式; method=" get ";即默认为get方式

post:

  • 提交表单时,method=“post”

两种方式的区别

get
主要是从服务器端获取数据;
也可以向服务器端发送数据(数据在地址栏URL中传递,会在地址栏中显示,但是长度有限制)

post
主要是向服务器端发送数据;(提交数据在请求体中,不会在URL显示出来; 没有长度限制;可以提交文件); 数据相对安全.


分别在LoginServlet类中重写doGet( ) 方法与 doPost( )方法

public class LoginServlet extends HttpServlet {
    //无参构造的实例化方式,默认存在;
    //初始化方法 init ,默认调用父类的;
    //service方法,可调用父类中的; 在父类中会判断请求方式 ; get对应doGet方法; post对应doPost 方法.
    //销毁方法  destory 默认调用父类的;
     //分别查看doGet与doPost的区别.
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet方法");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost方法");
    }
}

启动Tomcat,点击网页上的超链接时;doGet方法被调用;

点击登录按钮时,表单为Post请求方式;doPost方法被调用;

虽然没有重写serviceff;实际上在源码中,service方法会对请求方式进行判断,然后调用对应的方法.


注意到方法的参数类型为HttpServletRequest(代表客户端(浏览器)的请求信息 )HttpServletResponse( 封装 HTTP 响应消息的) ;

首先看看HttpServletRequest


HttpServletRequest


  • HttpServletRequest是ServletRequest的子接口 ; 封装了请求的信息
  • HttpServletRequest相比ServletRequest,增添了针对Http协议的方法。
  • 请求和响应是Web交互最基本的模式,HttpServletRequest表示请求

在重写doGet方法时,打印HttpServletRequest类型参数

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet方法 " +req);
    }

运行服务器,点击超链接,控制台出现打印结果;在调用时来自接口的实现类.

doGet方法 org.apache.catalina.connector.RequestFacade@18e2ddef

request获取请求参数


方法注释
getParameter( )返回类型为String ;获得单个值
==getParameterValues( ) ==返回类型为String[] 获得多个值

在post请求方式调用时,输入的中文传递时会出现乱码;所以就需要在doPost()中进行字符的过滤

使用 setCharacterEncoding(编码格式)
注意,字符过滤一定要在接收数据之前.


  • 案例1:在LoginServlet中的doGet方法中定义变量;使用getParameter(name)方法
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收请求中传递的数据(提交的数据)
        String name=req.getParameter("name");
        String age=req.getParameter("age");
        String phone=req.getParameter("phone");
        System.out.println("姓名="+name+" 年龄="+age+" 电话="+phone);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   }
}

在index.jsp前端页面的超链接地址栏输入参数

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>初识JavaWeb</title>
  </head>
  <body>
  <a href="login?name=阿杰&age=12&phone=11112345678">超链接</a>
  <form action="login" method="post">
    账号:<input type="text" name="account"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit" value="登录"/>
  </form>
  </body>
</html>

启动服务器,点击超链接;控制台打印出信息;


  • 案例2:在LoginServlet中的doPost方法中定义变量;使用getParameter(name)方法
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收请求中传递的数据(提交的数据)
        String account = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println("账号=>" + account + "  密码=> " + password);
    }
}

启动服务器,输入账号为中文,输入密码;登录;然后在控制台打印的信息发现;中文出现了乱码

而之前的get请求方式并没有出现中文乱码;所以对于这个post请求方式出现的数据中文乱码;
首先要进行字符编码的过滤.
在LoginServlet中的doPost方法中;

  @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置数据解码格式;(字符过滤)
        req.setCharacterEncoding("utf-8");
        //接收请求中传递的数据(提交的数据)
        String account = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println("账号=>" + account + "  密码=> " + password);
    }

启动服务器,输入中文账号;查看控制台;中文乱码问题已解决


那么,接收多个数值该怎么办呢,比如说前端网页有个复选框;这时就得需要方法
getParameterValues( ) 返回类型为String[ ] 数组;可以获得多个值

案例3:在提交表单时,涉及到单选按钮,下拉框,复选框时,怎么接收到这些数据
首先,编写jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>初识JavaWeb</title>
  </head>
  <body>
  <a href="login?name=阿杰&age=12&phone=11112345678">超链接</a>

  <form action="login" method="post">
    账号:<input type="text" name="account"/><br/>
    密码:<input type="password" name="password"/><br/>
    角色:<input type="radio"name="charactar" value="人类">人类
        <input type="radio" name="charactar" value="魔兽">魔兽
        <input type="radio" name="charactar" value="上神">上神<br/>
    <!--下拉框,所有的option选项共用一个name-->
    职业:<select name="profession">
         <option value="炼药师">炼药师</option>
         <option value="武者"  >武者  </option>
         <option value="文将"  >文将  </option>
         <option value="铸造师">铸造师</option>
         </select><br/>
    <!--注意:checkbox;复选框,name相同为一组-->
    品阶:<input type="checkbox" name="step" value="凡品">凡品
        <input type="checkbox" name="step" value="神品">神品
        <input type="checkbox" name="step" value="魔品">魔品<br/>
    <input type="submit" value="登录"/>
  </form>
  </body>
</html>

在LoginServlet类中的doPost方法中对接收数据结果进行定义;在控制台打印;

public class LoginServlet extends HttpServlet {
    //无参构造的实例化方式,默认存在;
    //初始化方法 init ,默认调用父类的;
    //service方法,可调用父类中的; 在父类中会判断请求方式 ; get对应doGet方法; post对应doPost 方法.
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置数据解码格式;(字符过滤)
        req.setCharacterEncoding("utf-8");
        //接收请求中传递的数据(提交的数据)
        String account = req.getParameter("account");
        String password = req.getParameter("password");
        String charactar=req.getParameter("charactar");
        String profession=req.getParameter("profession");
        String[] step=req.getParameterValues("step");
        System.out.println("账号=>" + account + "  密码=> " + password);
        System.out.println("角色=>"+charactar+ "  职业=>"+profession);
        System.out.println("品阶=>"+ Arrays.toString(step));
    }
    //销毁方法  destory 默认调用父类的;
}

启动服务器;在网页输入数据后点击登录;

在控制台出现打印的接收数据信息


以上是关于servlet 怎么获取http post 的body的主要内容,如果未能解决你的问题,请参考以下文章

servlet 从java中获取参数

jmeter 怎么测试https

js怎么获取servlet传过来的值

net webapi controller 怎么获取post body里面的数据

AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式

AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式