# Servlet Response fehlerhaft



## neela (6. Jul 2011)

Guten Morgen

ich komme gerade bei der Anwort eines Servlets nicht weiter. Das Servlet soll eine pdf zurück an den Client senden und diese PDF dann direkt im Browser anzeigen 

Folgenden Code habe ich bereits:


```
PdfReader reader1 = new PdfReader(pdfKompl_byte);
			PdfReader reader2 = new PdfReader(pdf2_byte);

			// Anhang (konstanter Teil) hinzugefügt
			PdfReader reader3 = new PdfReader((file1));

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			PdfCopyFields copy = new PdfCopyFields(baos);
			copy.addDocument(reader1);
			copy.addDocument(reader2);
			copy.addDocument(reader3);
			copy.close();
			baos.close();
			pdfKompl_byte= baos.toByteArray();
		
			
			HttpServletResponse response = Start.getResponse();
			ServletOutputStream servletOutputStream = response
			.getOutputStream();
			response.setContentType("application/pdf");
			response.setHeader("Content-Transfer-Encoding", "binary");
			response.setContentLength(pdfKompl_byte.length);
			response.setStatus(200);
				
			response.getOutputStream().write(pdfKompl_byte, 0, pdfKompl_byte.length);
			response.getOutputStream().flush();
			response.getOutputStream().close();
```

Jedoch wird leider nichts zurück geliefert. 
Ich hänge nun schon 2 Tage an dem Problem und finde aber den Fehler nicht.

Währe nett wenn ihr mir Helfen könntet


----------



## ARadauer (6. Jul 2011)

Schreib pdfKompl_byte mal in ein File. Ist das File fehlerhaft, liegt der Fehler oberhalb zeile 15. Ist das File korrekt liegt der Fehler darunter...


----------



## neela (6. Jul 2011)

dies hab ich schon getestet und die pdf war da auch vollständig


----------



## ARadauer (6. Jul 2011)

mhn ok... ich schau dir mal wie ich das immer mache...


```
HttpServletResponse response = Start.getResponse(); // was ist Start? Gib den response direkt an diese Methode aus der doPost/doGet weiter
ServletOutputStream servletOutputStream = response.getOutputStream();
response.setContentType("application/pdf"); //ok...
//response.setHeader("Content-Transfer-Encoding", "binary"); mach ich nie
//response.setContentLength(pdfKompl_byte.length); mach ich auch nie
//response.setStatus(200); das mach ich auch nicht
               
response.setHeader("Content-disposition", "attachment; filename=test.pdf"); //dafür mach ich das
response.getOutputStream().write(pdfKompl_byte);
//response.getOutputStream().flush(); müsste auch ohne flush und close gehen
//response.getOutputStream().close();
```

Poste mal die ganze Klasse und dein Servlet


----------



## neela (6. Jul 2011)

Zunächst einmal die Startklasse 
	
	
	
	





```
package nutzerschnittstelle;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.Map;

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

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

/**
 * Servlet implementation class Start
 */
public class Start extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private HttpServletRequest request;
	private static HttpServletResponse response;


	
	public Start() {
		// TODO Auto-generated constructor stub
	}

	
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		Start druck = new Start();
		druck.setRequest(request); 
		druck.setResponse(response);
		Map param = request.getParameterMap();
		String xml= (String) param.get("xml");
		Document doc= null;
		try {
			
		if (xml==null)
		{(request.getInputStream())).readLine();
		
			InputStream input = request.getInputStream();
			doc = new SAXBuilder().build(input);
		}
		else {
	
		
			doc = new SAXBuilder().build(new StringReader(xml));
		}} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		fachlogik.Xml.xml_auslesen(doc); // wird die übertragene Datei ausgewertet 
		destroy();
	}
}
```

und nun noch die Klasse, welche den Response sendet 

```
public static void creat_pdf() {

	
		HashMap parameter = new HashMap();
		JasperReport jasperReport;
		JasperPrint jPrint;
		Image wappen;
		byte[] pdfKompl_byte = null;
		byte[] pdf2_byte = null;

// füllen der Hashmap aus Platzgründen hab ich das mal rausgenommen		

			input = new ByteArrayInputStream(Datenbank.template(format));
			jasperReport = JasperCompileManager.compileReport(input);

			jPrint = JasperFillManager.fillReport(jasperReport, parameter,
					new JREmptyDataSource());
			
			pdfKompl_byte = JasperExportManager.exportReportToPdf(jPrint);

			
			input = new ByteArrayInputStream(Datenbank.template("anhang1"));

			jasperReport = JasperCompileManager.compileReport(input);
			jPrint = JasperFillManager.fillReport(jasperReport, parameter,
					new JREmptyDataSource());
			pdf2_byte = JasperExportManager.exportReportToPdf(jPrint);

			// Pdf´s werden zusammengefügt
			PdfReader reader1 = new PdfReader(pdfKompl_byte);
			PdfReader reader2 = new PdfReader(pdf2_byte);

			// Anhang (konstanter Teil) hinzugefügt
			PdfReader reader3 = new PdfReader((Datenbank.template("anhang2")));

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			PdfCopyFields copy = new PdfCopyFields(baos);
			copy.addDocument(reader1);
			copy.addDocument(reader2);
			copy.addDocument(reader3);
			copy.close();
			baos.close();
			pdfKompl_byte = baos.toByteArray();

			HttpServletResponse response = Start.getResponse();
			ServletOutputStream servletOutputStream = response
					.getOutputStream();
			response.setContentType("application/pdf");
			//response.setHeader("Content-Transfer-Encoding", "binary");
			//response.setContentLength(pdfKompl_byte.length);
			response.setHeader("Content-disposition", "attachment; filename=test.pdf");
			response.setStatus(200);

			
			response.getOutputStream().write(pdfKompl_byte, 0,
					pdfKompl_byte.length);
			//response.getOutputStream().flush();
		
			
		} catch (JRException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();*/
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
```


----------



## Gelöschtes Mitglied 5909 (6. Jul 2011)

Du bist dir bewusst dass du new Start im servlet machs? 
Ein Servlet wird vom Servlet container erzeugt und sollte nicht von dir erzeugt werden.
Das machst du nur wegen request/response und du merkst sie dir auch noch statisch -> das ist bullshit

Warum reichst du die nicht in deine createpdf methode?

destroy() solltest du auch nicht unbedingt aufrufen, das wird automatisch gemacht.

genereller ablauf (normalerweise)

1. Servlet liest parameter von request aus.
2. Servlet ruft klasse auf, die die parameter verarbeitet
3. Klasse liefert ergebnis, Servlet schreibt ergebnis in response


----------



## ARadauer (6. Jul 2011)

> Du merkst sie dir statisch -> das ist bullshit


ich hätte es jetzt nicht so ausgedrückt aber rail hat recht. Das darfst du nicht machen!
Nicht einmal wenn es nicht static wäre, wäre es falsch. Da das Servlet als Instanz doch nur einmal existiert.



> Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections.



Also ich würde einem Servlet keine Instanz Variblen geben...


----------



## neela (6. Jul 2011)

danke für die Hinweise 
das ist das erste mal das ich mit Servlets in berührung kommen
aus diesem Grund habe ich auch diese Fehler gemacht 

hab nun alles umgeändert mal schaun ob es dann geht 
	
	
	
	





```
public class Start extends HttpServlet {
	private static final long serialVersionUID = 1L;
		public Start() {
			}
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
		protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String xml = request.getParameter("xml");
		Document doc = null;
		if (xml != null) {
			try {
				doc = new SAXBuilder().build(new StringReader(xml));
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			  fachlogik.Xml.xml_auslesen(response, doc);   
		}else 
			response.setStatus(600);
	}
}
```

ps. der aufruf der parameter mit
	
	
	
	





```
String xml=request.getParameter("xml");
```
  ist aber ok so?


----------



## Gelöschtes Mitglied 5909 (6. Jul 2011)

```
fachlogik.Xml.xml_auslesen(response, doc);
```

Da ist auch schon wieder was statisches drinnen (Xml), was ich nicht machen würde.

Insgesamt würde ich noch umwandeln, in etwa so:


```
String xml=request.getParameter("xml");
// hier wird der parameter erstmal validiert
XmlReader reader = new XmlReader(); // das wäre die Klasse mit der logik
Result result = reader.handleDocument(xml); // hier wird die logik ausgeführt
// jetzt wird das ergebnis geschrieben
// Result ist fiktiv, da können ggf. auch fehlermeldungen etc. drinnen sein
if (!result.hasErrors()) {
response.getWriter().print(result.getAsHtml());
} else {
 response.getWriter().print(result.getErrorMessages());
}
```

Und dann solltest noch nochmal deine Schreibweise überdenken.
Normalerweilse verwendet man in java lowerCamelCase und nicht sowas_hier_mit_underscores


----------



## neela (6. Jul 2011)

Danke für die Tips

habe nun wirklich alles angepasst 
mal schaun ob es nun funktionieren will


----------



## neela (6. Jul 2011)

Auf meinen Testclient erhalte ich nun folgenden Fehler 

```
java.net.SocketException: Unexpected end of file from server
	at sun.net.[url]www.http.HttpClient.parseHTTPHeader(HttpClient.java:818[/url])
	at sun.net.[url]www.http.HttpClient.parseHTTP(HttpClient.java:711[/url])
	at sun.net.[url]www.http.HttpClient.parseHTTPHeader(HttpClient.java:816[/url])
	at sun.net.[url]www.http.HttpClient.parseHTTP(HttpClient.java:711[/url])
	at sun.net.[url]www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:626[/url])
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:272)
	at test.beginn.run(beginn.java:195)
	at test.beginn.doPost(beginn.java:79)
	at test.beginn.doGet(beginn.java:59)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:627)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879)
	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
	at java.lang.Thread.run(Thread.java:534)
```

Liegt dieser Fehler an meinem Testclient und ist die Ursache in meinem Servlett zu suchen 
hab schon das Internet durchstöbert aber nichts richtiges gefunden.


----------



## Gelöschtes Mitglied 5909 (6. Jul 2011)

Du lässt in dem Servlet das die PDF generiert einen Client laufen der wiederum gegen das Servlet geht in dem du dich gerade befindest?


----------



## neela (6. Jul 2011)

Nein der Client läuft extra


----------



## Gelöschtes Mitglied 5909 (6. Jul 2011)

wie sueht test.begin#run() aus? Das ist doch teil vom Servlet


----------



## neela (8. Jul 2011)

jep das war von dem anderen Servlet welches dieses aufrufen sollte 
der fehler lag bei dem client nun funtkioniert alles 
vielen dank


----------

