4

This seems like such a common use case that there ought to be a simple solution, yet everywhere I look is filled with extremely bloated examples.

Let's say I have a form that looks like:

<form action="http://localhost/endpoint" method="POST" enctype="multipart/form-data">
    <input type="text" name="value" />
    <input type="submit" value="Submit"/>
</form>

I submit it and on the server want to get the input value:

On the server I set up an HttpServer with a single endpoint, that in this case just sends the body data straight back:

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.*;
import java.net.InetSocketAddress;
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        try {
            HttpServer server = HttpServer.create(new InetSocketAddress(80), 10);
            server.setExecutor(null);
            server.createContext(
                    "/endpoint",
                    (HttpExchange httpExchange) -> {

                            InputStream input = httpExchange.getRequestBody();
                            StringBuilder stringBuilder = new StringBuilder();

                            new BufferedReader(new InputStreamReader(input))
                                .lines()
                                .forEach( (String s) -> stringBuilder.append(s + "\n") );

                            httpExchange.sendResponseHeaders(200, stringBuilder.length());

                            OutputStream output = httpExchange.getResponseBody();
                            output.write(stringBuilder.toString().getBytes());

                            httpExchange.close();
                    }
            );

            server.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Now, if submitting the form with the input "hi", returns

------WebKitFormBoundaryVs2BrJjCaLCWNF9o
Content-Disposition: form-data; name="value"

hi
------WebKitFormBoundaryVs2BrJjCaLCWNF9o--

This tells me that there should be a way to get the string values, but the only way I can see to do it is to manually parse it.

(Also, I'm trying to get a little dirty, implementing this server only with the libraries that come with the JDK. I've used Apache server quite a bit at work, but that isn't what I'm trying to do here.)

AaronF
  • 2,841
  • 3
  • 22
  • 32
  • Well, that's one of the reasons all these libraries libraries outside of the JDK, and Java EE, exist: to make this much simpler. You chose the hard way on purpose, to get your hands dirty, so it's harder than the easy way, and you'll have to make your hands dirty. It would be much easier if you didn't choose to make your form use multipart/form-data, though. – JB Nizet May 06 '17 at 15:41
  • I had the same problem with URL-encoded. Still have to parse out the info. – AaronF May 06 '17 at 16:07
  • Sure, but the parsing should be easier. – JB Nizet May 06 '17 at 16:08
  • Yeah, you're right. I'll do that. – AaronF May 06 '17 at 16:38
  • Have you figured out a good way to handle files in this case? I am able to parse if only text data is present but unable to do if files are present. – Dhruv garg Nov 17 '20 at 06:59

1 Answers1

4
public Server() throws IOException {
    HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
    server.createContext("/", new HttpHandler() {
        @Override
        public void handle(HttpExchange t) throws IOException {
            StringBuilder sb = new StringBuilder();
            InputStream ios = t.getRequestBody();
            int i;
            while ((i = ios.read()) != -1) {
                sb.append((char) i);
            }
            System.out.println("hm: " + sb.toString());

            String response = " <html>\n"
                    + "<body>\n"
                    + "\n"
                    + "<form action=\"http://localhost:8000\" method=\"post\">\n"
                    + "input: <input type=\"text\" name=\"input\"><br>\n"
                    + "input2: <input type=\"text\" name=\"input2\"><br>\n"
                    + "<input type=\"submit\">\n"
                    + "</form>\n"
                    + "\n"
                    + "</body>\n"
                    + "</html> ";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();

        }
    });
    server.setExecutor(null);
    server.start();
}

not sure if you wanted this or what but this returns string of all posts page did with names and values

like that

input=value&input2=value2&......