开发者

Reading POST data from html form sent to serversocket

i try to write simplest possible server app in Java, displaying html form with textarea input, which after submitting gives me possibility to parse xml typed in that textarea. For now i build simple serversocket based server like that:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class WebServer {

  protected void start() {
    ServerSocket s;
    String gets = "";
    System.out.println("Start on port 80");
    try {
      // create the main server socket
      s = new ServerSocket(80);
    } catch (Exception e) {
      System.out.println("Error: " + e);
      return;
    }

    System.out.println("Waiting for connection");
    for (;;) {
      try {
        // wait for a connection
        Socket remote = s.accept();
        // remote is now the connected socket
        System.out.println("Connection, sending data.");
        BufferedReader in = new BufferedReader(new InputStreamReader(
            remote.getInputStream()));
        PrintWriter out = new PrintWriter(remote.getOutputStream());

        String str = ".";

        while (!str.equals("")) {
          str = in.readLine();
          if (str.contains("GET")){
            gets = str;
            break;
          }
        }

        out.println("HTTP/1.0 200 OK");
        out.println("Content-Type: text/html");
        out.println("");
        // Send the HTML page
        String method = "get";
        out.print("<html><form method="+method+">");
        out.print("<textarea name=we></textarea></br>");
        out.print("<input type=text name=a><input type=submit&开发者_StackOverflow社区gt;</form></html>");
        out.println(gets);
        out.flush();

        remote.close();
      } catch (Exception e) {
        System.out.println("Error: " + e);
      }
    }
  }

  public static void main(String args[]) {
    WebServer ws = new WebServer();
    ws.start();
  }
}

After form (textarea with xml and one additional text input) is submitted in 'gets' String-type variable I have Urlencoded values of my variables (also displayed on the screen, it looks like that:

gets = GET /?we=%3Cnetwork+ip_addr%3D%2210.0.0.0%2F8%22+save_ip%3D%22true%22%3E%0D%0A%3Csubnet+interf_used%3D%22200%22+name%3D%22lan1%22+%2F%3E%0D%0A%3Csubnet+interf_used%3D%22254%22+name%3D%22lan2%22+%2F%3E%0D%0A%3C%2Fnetwork%3E&a=fooBar HTTP/1.1 

What can i do to change GET to POST method (if i simply change it in form and than put " if (str.contains("POST")){" it gives me string like

gets = POST / HTTP/1.1

with no variables. And after that, how i can use xml from my textarea field (called 'we')?


As there is a blank line following the headers, here is my relatively simple way of getting the post payload data, after having read the header information using the readLine() method of BufferedReader.

//socket is an instance of Socket
InputStream is = socket.getInputStream();
InputStreamReader isReader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isReader);

//code to read and print headers
String headerLine = null;
    while((headerLine = br.readLine()).length() != 0){
        System.out.println(headerLine);
    }

//code to read the post payload data
StringBuilder payload = new StringBuilder();
        while(br.ready()){
            payload.append((char) br.read());
            }
System.out.println("Payload data is: "+payload.toString())


This is my implementation for read POST body:

try {
    Socket socket = params[0];
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    // read request
    String line;
    line = in.readLine();
    StringBuilder raw = new StringBuilder();
    raw.append("" + line);
    boolean isPost = line.startsWith("POST");
    int contentLength = 0;
    while (!(line = in.readLine()).equals("")) {
        raw.append('\n' + line);
        if (isPost) {
            final String contentHeader = "Content-Length: ";
            if (line.startsWith(contentHeader)) {
                contentLength = Integer.parseInt(line.substring(contentHeader.length()));
            }
        }
    }
    StringBuilder body = new StringBuilder();
    if (isPost) {
        int c = 0;
        for (int i = 0; i < contentLength; i++) {
            c = in.read();
            body.append((char) c);
            Log.d("JCD", "POST: " + ((char) c) + " " + c);
        }
    }
    raw.append(body.toString());
    publishProgress(raw.toString());
    // send response
    out.write("HTTP/1.1 200 OK\r\n");
    out.write("Content-Type: text/html\r\n");
    out.write("\r\n");
    out.write(new Date().toString());
    if (isPost) {
        out.write("<br><u>" + body.toString() + "</u>");
    } else {
        out.write("<form method='POST'>");
        out.write("<input name='name' type='text'/>");
        out.write("<input type='submit'/>");
        out.write("</form>");
    }
    //
    // do not in.close();
    out.flush();
    out.close();
    socket.close();
    //
} catch (Exception e) {
    e.printStackTrace();
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    publishProgress('\n' + sw.toString());
}

I do it for android and publishProgres in my case means:

protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        instance.logTextView.append(values[0]);
    }


A typical HTTP POST request looks like this:

POST / HTTP/1.1
Host: www.example.com
Accept: text/html,*/*;q=0.5
User-Agent: BrowserName/1.0
Referer: http://www.example.com/
Content-type: application/x-www-form-urlencoded; charset=utf-8

foo=1&bar=2

The first line contains the method (typically GET or POST, but there's more, like HEAD, PUT, DELETE), the request URI, and the protocol version. Then there are a number of request headers, which may not be so important for a simple server. If the method is one that takes a request body (POST and PUT), then after the headers there's a blank line followed by the request body. In the case of a POST from an HTML form, the body will consists of key=value pairs for all form elements, joined by &. The values will be %-encoded.

You just need to take care of properly parsing the entire request.

You should be aware that line endings in HTTP are supposed to be Windows-style (\r\n). The readline() method might interpret this as two linebreaks, so it might look like there's an empty line between each of the real lines.


POST data is not in the first line. Print all lines and you'll see. It's actually immediately after a blank line.


From this -

We need to first read headers and then read again from the same BufferedReader using actual content length provided in the header section :-

BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
line = in.readLine();
while ((line = in.readLine()) != null && (line.length() != 0)) {
    System.out.println("HTTP-HEADER: " + line);
    if (line.indexOf("Content-Length:") > -1) {
    postDataI = new Integer(
        line.substring(
            line.indexOf("Content-Length:") + 16,
            line.length())).intValue();
    }
}
String postData = "";
// read the post data
if (postDataI > 0) {
    char[] charArray = new char[postDataI];
    in.read(charArray, 0, postDataI);
    postData = new String(charArray);
}

HTH

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜