Question

I'm running an embedded Jetty (9.1.0.v20131115) setup, and have several Handlers setup to process requests on several different contexts.

One of these Handlers performs login functionality when the user submits a form. It's setup as follows:

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

// Other handlers go here...

contexts.setHandlers(new Handler[]{rootContext, logoutContext, loginContext, resourceHandler});
server.setHandler(contexts);

That should be pretty standard and is nothing special. What perplexes me is that when I run the LoginHandler through a debugger, the HttpServletRequest object has no parameters, even though the form clearly has two form input elements!

here's a copy of the request, which I caught via 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

On top of that, if I change the form action to GET instead of POST the parameters show up just fine!

Is there anything special that must be done to get a Handler to accept POST parameters?

Était-ce utile?

La solution

Seems to work just fine.

package jetty;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.InetSocketAddress;
import java.net.Socket;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IO;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class JettyPostTest
{
    public static class LoginHandler extends HandlerWrapper
    {
        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            PrintWriter out = response.getWriter();
            response.setContentType("text/plain");

            out.printf("username = %s\n",request.getParameter("username"));
            out.printf("password = %s\n",request.getParameter("password"));

            baseRequest.setHandled(true);
        }
    }

    private static Server server;
    private static int port;

    @BeforeClass
    public static void startServer() throws Exception
    {
        server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(0);
        server.addConnector(connector);

        // collection for handlers
        HandlerCollection handlers = new HandlerCollection();
        server.setHandler(handlers);

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

        // default handler
        handlers.addHandler(new DefaultHandler());

        // start server
        server.start();

        // grab port
        port = connector.getLocalPort();
    }

    @AfterClass
    public static void stopServer() throws Exception
    {
        server.stop();
    }

    @Test
    public void testPostParameters() throws IOException
    {
        StringBuilder req = new StringBuilder();
        req.append("POST /login/ HTTP/1.1\r\n");
        req.append("Host: localhost:").append(port).append("\r\n");
        req.append("Connection: close\r\n");
        req.append("Content-Length: 31\r\n");
        req.append("Cache-Control: max-age=0\r\n");
        req.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n");
        req.append("Origin: http://localhost:").append(port).append("\r\n");
        req.append("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\r\n");
        req.append("Content-Type: application/x-www-form-urlencoded\r\n");
        req.append("Referer: http://localhost:").append(port).append("/dashboard/\r\n");
        req.append("Accept-Encoding: gzip,deflate,sdch\r\n");
        req.append("Accept-Language: en-US,en;q=0.8\r\n");
        req.append("\r\n");
        req.append("username=myuser&password=mypass\r\n");

        try (Socket socket = new Socket())
        {
            socket.connect(new InetSocketAddress("localhost",port));
            // Write request
            try (OutputStream out = socket.getOutputStream();
                    OutputStreamWriter writer = new OutputStreamWriter(out);
                    InputStream in = socket.getInputStream();
                    InputStreamReader reader = new InputStreamReader(in))
            {
                StringReader reqStream = new StringReader(req.toString());
                IO.copy(reqStream,writer);
                writer.flush();
                out.flush();

                StringWriter respStream = new StringWriter();
                IO.copy(reader,respStream);

                System.out.println(respStream.toString());

                String expected = "username = myuser\npassword = mypass\n";
                assertThat("Response",respStream.toString(),containsString(expected));
            }
        }
    }
}

Results in the output:

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}

Only change I made from your request is to change Connection: keep-alive to Connection: close to let jetty close the connection. This change is minor and only made to allow the test to execute swiftly, using the original value does not change the results of the test.

Something piece of information is missing from your question.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top