无法从 HttpServletRequest 获取数据
Posted
技术标签:
【中文标题】无法从 HttpServletRequest 获取数据【英文标题】:Not able to get data from HttpServletRequest 【发布时间】:2020-11-04 07:31:03 【问题描述】:我看过很多关于这个问题的旧帖子,但我没有成功。
我创建了一个带有多个处理程序的码头服务器:https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java。我有一个用于 http 的处理程序和另一个用于 https 的处理程序。处理程序扩展了 AbstractHandler 并且只实现了 handle() 方法。
我能够使用 Postman 访问两个处理程序(我可以通过日志记录看到)发送请求和数据,但我有 2 个问题。
-
无论我使用 POST、PUT 还是 GET,HttpServletRequest.getMethod() 总是返回“GET”。
我不知道如何通过 POST 获取数据。即使 HttpServletRequest.getReader() 不为空,我只是没有得到任何数据。
我在这里添加了一堆登录以查看发生了什么。希望这会有所帮助,因为它对我没有帮助。
public class MyHandler extends AbstractHandler
private static Logger logger = new L4Logger(MyHandler.class);
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
logger.info("MyHandler", "handle request " + request.getMethod() + " for path " + request.getContextPath());
logger.info("MyHandler", "content length " + request.getContentLength());
Enumeration<String> e = request.getParameterNames();
Collections.list(e).forEach(s -> logger.info("MyHandler", "handle e " + s););
Enumeration<String> a = request.getAttributeNames();
Collections.list(a).forEach(s -> logger.info("MyHandler", "handle a " + s););
if (request.getReader() == null)
logger.info("MyHandler", "handle request request.getReader() == null");
else
logger.info("MyHandler", "handle request request.getReader() != null");
if (request.getContextPath().equalsIgnoreCase("/run"))
logger.info("MyHandler", "handle request run");
String cmdString = getBody(request);
logger.info("MyHandler", "handle run data " + cmdString);
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
private String getBody(HttpServletRequest request) throws IOException
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null)
buffer.append(line);
return buffer.toString();
用一些 json 数据发布我的服务器,日志输出如下所示:
[handle request GET for path /run]
[content length -1]
[handle a javax.servlet.request.key_size]
[handle a org.eclipse.jetty.servlet.request.ssl_session]
[handle a javax.servlet.request.X509Certificate]
[handle a javax.servlet.request.cipher_suite]
[handle a javax.servlet.request.ssl_session_id]
[handle request request.getReader() != null]
[handle request run]
[handle run data ]
最后,这是从 Postman 导出的 cURL 命令:
curl --location --request POST 'https://localhost:7777/run' --header 'Content-Type: application/json' --header 'Cookie: ssoLang=en' --data-raw '["cmd":"ls","args":"/proc"]'
【问题讨论】:
将详细输出添加到 curl 行curl -vvvv ...
,再次运行它,然后使用它产生的输出编辑您的问题。它可以揭示一些有用的东西。 (就像它没有通过 POST 请求正确地跟随重定向)。
经过多次反复试验和挫折后,我放弃了这种方法并使用此处描述的 RESTful 解决方案:***.com/questions/38206312/…。这个解决方案足以满足我的需要,我在几个小时内就完成了工作,因此我放弃了最初的方法。
【参考方案1】:
-1 的Content-Length
是正在发生的事情的潜在迹象。
Content-Type
标头还可以很好地控制此处的行为。
转储/记录所有请求标头,查找Content-Length
、Transfer-Encoding
、Content-Encoding
等...几乎所有控制请求正文内容处置的相关标头。
示例:验证您的请求标头实际上是Content-Type: application/json
。
您可以使用curl -vvvv
执行此操作,以便在命令行上转储请求/响应标头。
您可以在服务器端使用 ...
logger.info("MyHandler", "request content-type: " + request.getHeader("Content-Type"));
如果不是您所期望的,那么很可能是标准 Servlet 行为。
当您使用以下任何一种方法时...
HttpServletRequest.getParameter(String name) HttpServletRequest.getParameterMap() HttpServletRequest.getParameterNames() HttpServletRequest.getParameterValues(String name) HttpServletRequest.getParts() HttpServletRequest.getPart(String name)并且请求使用POST
方法和特殊的Content-Type
值...
application/x-www-form-urlencoded
。
multipart/form-data
(以及定义了 javax.servlet.MultipartConfigElement
的端点)。
那么你也在阅读正文内容。
在这些方法调用之后,请求中没有数据可供读取。
【讨论】:
这快把我逼疯了。我使用您建议的调试从 cygwin 运行 curl,现在我看到:~~~ [Content-Type, application/json] [request content-type: application/json length -1] [method POST] [handle run data] ~~~ 虽然我没有得到数据,但方法是POST,内容是JSON。我从邮递员那里重新运行了同样的事情,它又回到了 GET 并且内容类型为空。 ~~~ [请求内容类型:空长度-1] [方法GET] [处理运行数据] ~~~以上是关于无法从 HttpServletRequest 获取数据的主要内容,如果未能解决你的问题,请参考以下文章
如何从 HttpServletRequest 获取完整的 url? [复制]
从 HttpServletRequest 获取 AsyncContext
从 HttpServletRequest 获取 XML 并用于端点
如何从 HttpServletRequest 获取请求 url [重复]
Java拦截器HandlerInterceptor重写preHandle方法时HttpServletRequest无法获取自定义请求头参数问题
Java拦截器HandlerInterceptor重写preHandle方法时HttpServletRequest无法获取自定义请求头参数问题