Jetty莫名其妙地吃掉了POST参数

Jetty莫名其妙地吃掉了POST参数,jetty,embedded-jetty,Jetty,Embedded Jetty,我正在运行一个嵌入式Jetty(9.1.0.v20131115)设置,并设置了几个处理程序来处理不同上下文中的请求 其中一个处理程序在用户提交表单时执行登录功能。它的设置如下所示: ContextHandler loginContext = new ContextHandler("/login"); loginContext.setHandler(new LoginHandler()); // Other handlers go here... contexts.setHandlers(ne

我正在运行一个嵌入式Jetty(9.1.0.v20131115)设置,并设置了几个处理程序来处理不同上下文中的请求

其中一个处理程序在用户提交表单时执行登录功能。它的设置如下所示:

ContextHandler loginContext = new ContextHandler("/login");
loginContext.setHandler(new LoginHandler());

// Other handlers go here...

contexts.setHandlers(new Handler[]{rootContext, logoutContext, loginContext, resourceHandler});
server.setHandler(contexts);
这应该是相当标准的,没有什么特别的。让我困惑的是,当我通过调试器运行LoginHandler时,HttpServletRequest对象没有参数,即使表单显然有两个表单输入元素

这是我通过netcat捕获的请求副本:

POST /login HTTP/1.1
Host: localhost:52520
Connection: keep-alive
Content-Length: 31
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:52520
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:52520/dashboard/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

username=myuser&password=mypass
最重要的是,如果我将表单操作更改为GET而不是POST,那么参数就会显示得很好


要让处理程序接受POST参数,必须做些什么特别的事情吗?

似乎工作得很好

包装码头;
导入静态org.hamcrest.CoreMatchers.*;
导入静态org.junit.Assert.*;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.io.PrintWriter;
导入java.io.StringReader;
导入java.io.StringWriter;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入javax.servlet.ServletException;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入org.eclipse.jetty.server.Request;
导入org.eclipse.jetty.server.server;
导入org.eclipse.jetty.server.ServerConnector;
导入org.eclipse.jetty.server.handler.ContextHandler;
导入org.eclipse.jetty.server.handler.DefaultHandler;
导入org.eclipse.jetty.server.handler.HandlerCollection;
导入org.eclipse.jetty.server.handler.HandlerWrapper;
导入org.eclipse.jetty.util.IO;
导入org.junit.AfterClass;
导入org.junit.BeforeClass;
导入org.junit.Test;
公共类JettyPostTest
{
公共静态类LoginHandler扩展HandlerWrapper
{
@凌驾
公共无效句柄(字符串目标、请求baseRequest、HttpServletRequest、HttpServletResponse响应)引发IOException、ServletException
{
PrintWriter out=response.getWriter();
response.setContentType(“文本/普通”);
out.printf(“用户名=%s\n”,request.getParameter(“用户名”);
out.printf(“密码=%s\n”,request.getParameter(“密码”);
baseRequest.setHandled(true);
}
}
专用静态服务器;
专用静态int端口;
@课前
公共静态void startServer()引发异常
{
服务器=新服务器();
ServerConnector连接器=新的ServerConnector(服务器);
连接器。设置端口(0);
addConnector(连接器);
//处理程序的集合
HandlerCollection handlers=新的HandlerCollection();
setHandler(处理程序);
//登录上下文
ContextHandler loginContext=新的ContextHandler(“/login”);
setHandler(新的LoginHandler());
addHandler(loginContext);
//默认处理程序
addHandler(新的DefaultHandler());
//启动服务器
server.start();
//抓斗
port=connector.getLocalPort();
}
@下课
公共静态void stopServer()引发异常
{
server.stop();
}
@试验
public void testPostParameters()引发IOException
{
StringBuilder req=新的StringBuilder();
请求追加(“POST/login/HTTP/1.1\r\n”);
req.append(“主机:本地主机:”).append(端口).append(“\r\n”);
请求追加(“连接:关闭\r\n”);
请求追加(“内容长度:31\r\n”);
请求追加(“缓存控制:最大年龄=0\r\n”);
请求追加(“接受:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n”);
请求追加(“来源:http://localhost:“”.append(端口).append(“\r\n”);
请求追加(“用户代理:Mozilla/5.0(Macintosh;英特尔Mac OS X 10_9_0)AppleWebKit/537.36(KHTML,如Gecko)Chrome/31.0.1650.63 Safari/537.36\r\n”);
请求追加(“内容类型:application/x-www-form-urlencoded\r\n”);
请求追加(“参考:http://localhost:“”.append(端口).append(“/dashboard/\r\n”);
追加请求(“接受编码:gzip,deflate,sdch\r\n”);
请求追加(“接受语言:en-US,en;q=0.8\r\n”);
请求追加(“\r\n”);
req.append(“username=myuser&password=mypass\r\n”);
try(套接字=新套接字())
{
connect(新的InetSocketAddress(“localhost”,port));
//写请求
try(OutputStream out=socket.getOutputStream();
OutputStreamWriter writer=新的OutputStreamWriter(输出);
InputStream in=socket.getInputStream();
InputStreamReader reader=新的InputStreamReader(in))
{
StringReader reqStream=新的StringReader(req.toString());
IO.副本(请求流、编写器);
writer.flush();
out.flush();
StringWriter respStream=新StringWriter();
IO.副本(读卡器、响应流);
System.out.println(respStream.toString());
字符串expected=“username=myuser\npassword=mypass\n”;
断言(“响应”,respStream.toString(),包含字符串(预期));
}
}
}
}
输出结果:

2013-12-18 13:23:08.856:INFO:oejs.Server:main: jetty-9.1.0.v20131115
2013-12-18 13:23:08.888:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@49ada86{/login,null,AVAILABLE}
2013-12-18 13:23:08.897:INFO:oejs.ServerConnector:main: Started ServerConnector@3f14b553{HTTP/1.1}{0.0.0.0:34456}
HTTP/1.1 200 OK
Content-Type: text/plain; charset=ISO-8859-1
Connection: close
Server: Jetty(9.1.0.v20131115)

username = myuser
password = mypass

2013-12-18 13:23:08.994:INFO:oejs.ServerConnector:main: Stopped ServerConnector@3f14b553{HTTP/1.1}{0.0.0.0:0}
2013-12-18 13:23:08.995:INFO:oejsh.ContextHandler:main: Stopped o.e.j.s.h.ContextHandler@49ada86{/login,null,UNAVAILABLE}
我根据您的请求所做的唯一更改是将
Connection:keep alive
更改为
Connection:close
,让jetty关闭连接。此更改很小,仅允许快速执行测试,使用原始值不会更改测试结果


你的问题中缺少了一些信息。

的确,你是对的。运行单元测试时,我看到了相同的结果。我正在经历这些不同…Joakim,你做了另一个改变