How can I parse URL queries with a system like this.
For Example something like get these URL arguments in variables.
http://localhost?format=json&apikey=838439873473kjdhfkhdf
http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html
I made these files
WorkerRunnable.java
package servers;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.Socket;
/**
*/
public class WorkerRunnable implements Runnable{
protected Socket clientSocket = null;
protected String serverText = null;
public WorkerRunnable(Socket clientSocket, String serverText) {
this.clientSocket = clientSocket;
this.serverText = serverText;
}
public void run() {
try {
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
long time = System.currentTimeMillis();
output.write(("HTTP/1.1 200 OK\n\nWorkerRunnable: " +
this.serverText + " - " +
time +
"").getBytes());
output.close();
input.close();
System.out.println("Request processed: " + time);
} catch (IOException e) {
//report exception somewhere.
e.printStackTrace();
}
}
}
MultiThreadedServer.java
package servers;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
public class MultiThreadedServer implements Runnable{
protected int serverPort = 8080;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread= null;
public MultiThreadedServer(int port){
this.serverPort = port;
}
public void run(){
synchronized(this){
this.runningThread = Thread.currentThread();
}
openServerSocket();
while(! isStopped()){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
} catch (IOException e) {
if(isStopped()) {
System.out.println("Server Stopped.") ;
return;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
new Thread(
new WorkerRunnable(
clientSocket, "Multithreaded Server")
).start();
}
System.out.println("Server Stopped.") ;
}
private synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop(){
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8080", e);
}
}
}
Dispatch.java
package servers;
public class Dispatch {
/**
* @param args
*/
public static void main(String[] args) {
MultiThreadedServer server = new MultiThreadedServer(9000);
new Thread(server).start();
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Stopping Server");
server.stop();
}
}
You're doing fine so far.
Read the data off of the InputStream (BufferedReader might help) one line at a time. Read and learn the HTTP Protocol (see Request Message section here: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol).
The first line that the client sends is going to follow that format: GET /foo.html?x=y&a=b HTTP/1.1
followed by \n\n that's the Method, URL (with query parameters) and Protocol. Split that line (on the spaces...) and then break the URL up according to the specs.
Everything you need can be found in the String class for parsing the data.
You have forgotten to read what the clients sends. In http the clients opens the connection and than sends the request and waits for the server to reply.
To read the request you have two options. Use a BufferedReader or read it byte by byte. The BufferedReader is easier. You get a String for every line and can easily split it or replace characters, or whatever ;)
Reading every byte is a little bit faster, but it will only be relevant if you need to serve a huge amount of request per seconds. Than this can really make a difference. I just put this information just so you know ;)
I have included the necessary part for reading in your WorkerRunnable.java. This reads and prints out the whole client request.
Start your server, open your browser and type: http://127.0.0.1:9000/hello?one=1&two=2&three=3 The First line on the Console will read: GET /hello?one=1&two=2&three=3 HTTP/1.1
Before closing an OutputStream, be sure to call the flush() method. This will force any buffered bytes to be written out. If you don't do it, than there might be some bytes/characters missing and you might be spending a long time looking for the error.
try {
InputStream input = clientSocket.getInputStream();
// Reading line by line with a BufferedReader
java.io.BufferedReader in = new java.io.BufferedReader(
new java.io.InputStreamReader(input));
String line;
while ( !(line=in.readLine()).equals("") ){
System.out.println(line);
}
OutputStream output = clientSocket.getOutputStream();
long time = System.currentTimeMillis();
output.write(("HTTP/1.1 200 OK\n\nWorkerRunnable: " +
this.serverText + " - " +
time +
"").getBytes());
output.flush();
//Flushes this output stream and forces any buffered output bytes to be written out.
output.close();
input.close();
System.out.println("Request processed: " + time);
I don't know exactly what you are doing there. You just told us you need to parse the URL, but maybe a better way is to use the simpleframework (http://www.simpleframework.org) It is like an embedded HTTP-Server, you can look at the tutorial. It will give you a request object, from there you can easily fetch the parameters in the url.
Technically speaking, you can, but it would leave you with implementing the http protocol on your own.
A much better option would be to use the Java Http Server from Oracle. See the following article for tips http://alistairisrael.wordpress.com/2009/09/02/functional-http-testing-with-sun-java-6-httpserver/