【发布时间】:2017-11-04 19:42:41
【问题描述】:
使用嵌入式 Jetty (9.4.5.v20170502),使用 servlet 处理程序和 URL:
http://localhost:8081/?para=%u65E5
(当流量被嗅探到另一个生产服务器时,此 URL 由 Chrome 发送)。
我需要有一个使用 Jetty 的场景的测试用例。
有一个错误:
org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query
at org.eclipse.jetty.server.Request.getParameters(Request.java:388)
at org.eclipse.jetty.server.Request.getParameterNames(Request.java:1036)
at MyServlet.service(MyServlet.java:15)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)
源自:
java.lang.IllegalArgumentException: Not valid encoding '%u6'
at org.eclipse.jetty.util.UrlEncoded.decodeHexByte(UrlEncoded.java:889)
at org.eclipse.jetty.util.UrlEncoded.decodeUtf8To(UrlEncoded.java:354)
at org.eclipse.jetty.util.UrlEncoded.decodeUtf8To(UrlEncoded.java:296)
at org.eclipse.jetty.http.HttpURI.decodeQueryTo(HttpURI.java:615)
at org.eclipse.jetty.server.Request.extractQueryParameters(Request.java:420)
at org.eclipse.jetty.server.Request.getParameters(Request.java:384)
at org.eclipse.jetty.server.Request.getParameterNames(Request.java:1036)
at MyServlet.service(MyServlet.java:15)
但是,当使用HelloWorld Handler时,调用request.getParameterNames()时相同的URL不会出错。
主类:
public class JettyTest {
public static void main(String[] args) throws Exception {
final Server server = new Server(8081);
// doesn't work
server.setHandler(getServletHandler());
// works
// server.setHandler(new HelloHandler());
server.start();
}
private static Handler getServletHandler() throws IOException {
final WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setResourceBase(".");
final String pathSpec = "/*";
final Class<? extends Servlet> servlet = MyServlet.class;
context.addServlet(servlet, pathSpec);
final WebAppClassLoader loader = new WebAppClassLoader(context);
context.setClassLoader(loader);
return context;
}
}
MyServlet:
public class MyServlet extends HttpServlet {
@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
for (final Enumeration<String> paramNames = request.getParameterNames();
paramNames.hasMoreElements();) {
final String name = paramNames.nextElement();
final String[] values = request.getParameterValues(name);
for (final String value : values) {
System.out.println(name + " " + value);
}
}
response.getWriter().write("something");
}
}
HelloHandler:
public class HelloHandler extends AbstractHandler {
final String greeting;
final String body;
public HelloHandler() {
this("Hello World");
}
public HelloHandler(String greeting) {
this(greeting, null);
}
public HelloHandler(String greeting, String body) {
this.greeting = greeting;
this.body = body;
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html; charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
for (Enumeration<String> en = request.getParameterNames(); en.hasMoreElements();) {
System.out.println("name " + en.nextElement());
}
PrintWriter out = response.getWriter();
out.println("<h1>" + greeting + "</h1>");
if (body != null) {
out.println(body);
}
baseRequest.setHandled(true);
}
}
【问题讨论】:
-
您的网址未经过属性编码。试试这个网址
http://localhost:8081/?para=%25u65E5 -
Chrome按原样发送参数值,其他生产服务器不报错。