Jetty:java.lang.IllegalArgumentException:无效的编码

时间:2017-06-03 14:46:25

标签: java jetty

使用嵌入式Jetty(9.4.5.v20170502),使用servlet处理程序和URL:

http://localhost:8081/?para=%u65E5

(此网址由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()时同一网址没有错误。

主要课程:

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);
    }
}

2 个答案:

答案 0 :(得分:0)

这似乎是Jetty中的错误。用户可以设计一个导致Jetty无法处理请求的URL。

在Jetty 9.4.15上,我发现它就像将?%% 0附加到URL一样简单。一旦处理URL的代码尝试访问查询参数,Jetty就会引发异常:

org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query

就目前而言,我没有一个好的解决方案或解决方法。

这可能仅在恶意人员测试您的站点弱点时发生。在这种情况下,Jetty停止处理而不是继续处理不良数据可能是可以接受的。

答案 1 :(得分:0)

简单的解决方案:我只是在浏览器应用程序中的javascript中使用了“ encodeURI(url)”(在ajax函数之前),问题已解决