# ServletInputStream leer?



## SchlechterInformatiker (29. Okt 2008)

Hallo, 
ich mache mich gerade an die Servlet Programmierung ran. Das klappt soweit ganz gut, mein Browser zeigt die vom Servlet generierte HMTL Seite an. Aber ich würde gerne den Text auslesen und in eine Datei schreiben, die beim Request auf meinen Servlet mitgeschickt wird. Aber irgendwie enthält der ServletInputStream keine Daten. Ich habe folgenden Code:


```
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public class HelloWorld extends HttpServlet
{
  int n;	
  public HelloWorld()
  {
	  super();
	  n = 1;
  }
  protected void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException
  {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    out.println("<HTML><HEAD><TITLE>Hallo Du da!</TITLE></HEAD><BODY>Hallo Welt!</BODY></HTML>");
    
    File f = new File("TestLog.txt");
    FileWriter fw = new FileWriter(f);
   
    fw.write(Integer.toString(n) + "\n");
    
    
    BufferedReader br = req.getReader();
    if(br == null)
    {
    	fw.write("br == null");
    }
    else if (br.readLine() == null)
    {
    	fw.write("br.readLine() == null");
    }
    else
    {
        br.reset();
        fw.write(br.readLine());    	
    }
    fw.close();
    out.close();
  }
  public String getServletInfo()
  {
   return "HelloClientServlet";
  }
}
```

Der Text in der Datei "TestLog.txt" ist "br.readLine() == null". Auch wenn ich mir direkt den ServletInputStream hole und da dann eine der read()-Methoden benutze, wird nix gelesen. Wieso ist das denn leer? Ich hätte jetzt eher sowas wie

GET /helloworld/Test HTTP/1.1
Host:localhost:8080

oder so in der art erwartet.

Übrigens: Die übertragenen Header kann ich mir alle problemlos ausgeben lassen, also irgendwas scheint zu funktionieren, nur will ich halt unverfälscht und direkt an die übertragenen Daten heran und anhand derer mein Response generieren. Die Header reichen mir nicht.

Weiß einer wie ich da ran komme bzw. warum der ServletInputStream keine Daten enthält?



mfg
SchlechterInformatiker


----------



## Guest (30. Okt 2008)

Probiere mal folgende Methoden auf dem Request:

getQueryString(), getRequestURI(), getRequestURL()


----------



## SchlechterInformatiker (30. Okt 2008)

Hab ich getestet,

getRequestURI() liefert "/helloworld/Test"
und getRequestURL().toString() liefert "http://localhost:8080/helloworld/Test"

soweit ok, aber getQueryString() liefert eine NullPointerException.


----------



## maki (30. Okt 2008)

>> soweit ok, aber getQueryString() liefert eine NullPointerException.

Glaub ich nicht.

Zeig mal den Code.


----------



## Guest (30. Okt 2008)

Also hier nochmal der Quellcode:


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


```
public class HelloWorld extends HttpServlet
{
  int n;	
  public HelloWorld()
  {
	  super();
	  n = 1;
  }
  protected void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException
  {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    out.println("<HTML><HEAD><TITLE>Hello Du da!</TITLE>"+
                "</HEAD><BODY>Hallo Welt!</BODY></HTML>");
    
    File f = new File("TestLog.txt");
    FileWriter fw = new FileWriter(f);
      
    fw.write(req.getQueryString());
    
    fw.close();
    out.close();
  }
  public String getServletInfo()
  {
   return "HelloClientServlet";
  }
}
```

Und die die Antwort im Browserfenster:


HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NullPointerException
	java.io.Writer.write(Unknown Source)
	HelloWorld.doGet(HelloWorld.java:24)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.
Apache Tomcat/6.0.18


----------



## maki (30. Okt 2008)

```
java.lang.NullPointerException
java.io.Writer.write(Unknown Source)
```
Dein FileWriter fw wirft die Exception, da getQueryString null zurückgit weil der eben leer ist.

Doku lesen kann helfen 


> getQueryString
> 
> public java.lang.String getQueryString()
> 
> ...



Damit der QueryStirng nicht leer ist solltest du einen mitschicken, zB.
http://localhost:8080/helloworld/Test?name1=wert1&name2=wert2


----------



## SchlechterInformatiker (30. Okt 2008)

Aso, ja ok dann weiß ich jetzt mal was der Query String ist

Aber eigentlich wollte ich ja an diesen Text ran, der beim HTTP Protokoll bei einem Request vom Browser an meinen Servlet geschickt wird, also z.B. dieses

GET /helloworld/Test HTTP/1.1
Host:localhost:8080 
usw...

Also hier nochmal ein Code der nen Fehler liefert:

```
import java.io.*;
import java.util.Calendar;

import javax.servlet.*;
import javax.servlet.http.*;


public class HelloWorld extends HttpServlet
{
private static final long serialVersionUID = 1L;
private int n;	
  public HelloWorld()
  {
	  super();
	  n = 1;
  }
  protected void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException
  {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    Calendar c = Calendar.getInstance();
    out.println("<HTML><HEAD><TITLE>Hallo Welt Programm</TITLE>"+
                "</HEAD><BODY>Hallo Welt! </BODY></HTML>");
    
    File f = new File("TestLog.txt");
    FileWriter fw = new FileWriter(f);
    BufferedReader  br = req.getReader();  
    fw.write(br.readLine());
    
    fw.close();
    out.close();
  }
  public String getServletInfo()
  {
   return "HelloClientServlet";
  }
}
```

Der liefert dann folgendes

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NullPointerException
	java.io.Writer.write(Unknown Source)
	HelloWorld.doGet(HelloWorld.java:32)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.
Apache Tomcat/6.0.18


Der BufferedReader kann hier nichts auslesen weil der ServletInputStream leer ist. Oder bin ich hier auf dem Holzweg?

mfg


----------



## maki (30. Okt 2008)

> Aber eigentlich wollte ich ja an diesen Text ran, der beim HTTP Protokoll bei einem Request vom Browser an meinen Servlet geschickt wird, also z.B. dieses


Lies dir mal die Doku zum ServletRequest und HttpServletRequest durch.

Eigentlich solltest du eine IllegalStateException bekommen.


----------



## SchlechterInformatiker (30. Okt 2008)

Ich hab die Doku schon gelesen, so ist es ja nicht 
Nur passiert in meinem Code nicht das was in der Doku steht.



> getInputStream
> 
> public ServletInputStream getInputStream() throws java.io.IOException
> 
> ...






Laut Doku sollten doch die empfangenen Daten in diesem ServletInputStream drin sein. Ich hab jetzt mal das Servlet Interface selber implementiert um sicher zu gehen, dass niemand (wie z.B. die Klasse HttpServlet) den ServletInputStream leert. Sie so aus:


```
import java.io.*;
import javax.servlet.*;

public class HelloWorld implements Servlet
{
	ServletConfig sc;
	public void destroy() 
	{
		
	}

	public ServletConfig getServletConfig() 
	{
		return sc;
	}

	public String getServletInfo() 
	{
		return "TestServlet";
	}

	public void init(ServletConfig arg0) throws ServletException 
	{
		sc = arg0;
	}

	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException 
	{
	    res.setContentType("text/html");

	    File f = new File("TestLog.txt");
	    FileWriter fw = new FileWriter(f);

	    byte[] b = new byte[100];
	    ServletInputStream sis = req.getInputStream();
	    
	    int n = sis.read(b);
	    fw.write(Integer.toString(n));

	    fw.close();
	}
}
```


In meiner Datei "TestLog.txt" steht "-1" drin, was ja bedeutet dass auch hier der ServletInputStream von vornherein schon leer ist, oder?

Oder gibt es vielleicht eine andere Möglichkeit an das heranzukommen was ich haben will?

GET /helloworld/Test HTTP/1.1
Host:localhost:8080
usw... 


mfg


----------



## SchlechterInformatiker (31. Okt 2008)

Nun gut, über den QueryString kann ich realisieren, was ich machen will. Finde aber das sieht ein wenig unschön aus wenn die Daten, die ich an den Servlet übertragen will da in der Adress-Leiste im Browser stehen.

Aber was ist wenn mein Servlet so eine Art HTTP-Sniffer werden soll? Jemand eine Idee wie das dann gehen soll? Woher bekomme ich die Original-Daten die von einem Browser an meinen Servlet übermittelt werden? Geht das überhaupt mit einem Servlet oder muss ich da mit einem richtigen Java-Programm daherkommen welches dann mit Sockets usw arbeitet?

Trotzdem schon mal danke an maki !!

mfg


----------

