Add HTTP header to response in java socket server - java

I'm not sure where or what command to use to add the HTTP header to the response from the server.
import java.io.*;
import java.net.*;
import com.sun.net.httpserver.*;
public class Response {
private static final int BUFFER_SIZE = 9999;
Request request;
BufferedOutputStream output;
//constructor para el output
public Response(BufferedOutputStream output){
this.output = output;
}
//Set del request
public void setRequest(Request request){
this.request = request;
}
public void sendResource() throws IOException{
File file = new File(Java_Server.Web_dir,request.getUri());
byte [] bytearray = new byte[(int) file.length()];
FileInputStream file_out = null;
if(file.exists())
file_out = new FileInputStream(file);
else{
String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: 23\r\n" +
"\r\n" +
"<h1>File Not Found</h1>";
output.write(errorMessage.getBytes());
}
BufferedInputStream bis = new BufferedInputStream(file_out);
try{
bis.read(bytearray,0,bytearray.length);
output.write(bytearray,0 , bytearray.length);
output.flush();
output.close();
return;
}catch (IOException e){
e.printStackTrace();
}
}
The contents is deliver to the browser but without the HTTP header and if a image is send for example, the browser doesn't show the image, it shows byte for byte.

The preferred way to do is, is to implement a Servlet and run it in a Servlet Container. Then you call the method setHeader on the HttpServletResponse object:
public class ExampleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setHeader("X-Whatever-Header-Name-You-Want", "Value");
}
}

Related

JSF command button can be clicked only once when calling servlet for file download

I have some command buttons in a jsf, one of which when clicked when create a file and download. In the action class that handle the jsf action , I create the url object that has the URL for calling the Servlet.
This all works , the file is downloaded one time when I click on the button , but the issue is , I cannot click on the button or any other command buttons on the page after this. Why is the request not complete? Please help.
<h:commandButton id="filedownloadbtn" action="#{fileDownloadInit.submit}" value = "thisform">
Action
try {
String baseURL = facesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
String url = baseURL + "/DataloadServlet";
facesContext.getCurrentInstance().getExternalContext().redirect(url);
return null;
} finally {
facesContext.responseComplete();
}'
DataloadServlet
public Object[] getFileNameAndData(HttpServletRequest request)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
//does some processing...
return new Object[] {fileName, stream.toByteArray()};
}
FileDownloadservlet
public abstract class FileDownloadservlet extends javax.servlet.http.HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Object[] file = getFileNameAndData(request);
if (file != null)
{
String fileName = (String)file[0];
byte[] fileData = (byte[])file[1];
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName +"\"");
response.setHeader("Cache-Control", "no-cache, no-store"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
String contentType = "application/vnd.ms-excel";
response.setContentType(");
response.setContentLength(fileData.length);
try
{
OutputStream output = response.getOutputStream();
output.write(fileData);
output.flush();
output.close();
}
catch (IOException ex)
{
}
}
}

How can I reuse JAX-RS Response into HttpServletResponse?

I have a Servlet which makes a request to my Rest API, and I want it to return the API Response content to the final user through the HttpServletResponse.
The content is actually a .xls file to download which I put in the Response with the StreamingOutput Object.
How can I do that ? I can't cast the Response into a HttpServletResponse
Rest API method :
#GET
#Produces( MediaType.APPLICATION_JSON )
#Path("bla")
public Response getTopicByName() {
final Workbook wb = new HSSFWorkbook();
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream output) throws IOException, WebApplicationException {
wb.write(output);
}
};
responseBuilder = responseBuilder.entity(stream);
responseBuilder = responseBuilder.status(Response.Status.OK);
responseBuilder = responseBuilder.header("Content-Disposition", "attachment; filename=" + device + ".xls");
return responseBuilder.build();
}
Servlet POST method :
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(url);
Response res = target. request().get();
if (res.getStatus() == 200) {
// how to put res stream into response stream ?
ServletOutputStream stream = response.getOutputStream();
}
client.close();
}
EDIT :
I tried TedTrippin method and after finding out the way to recover an InputStream from the Response, it worked well.
But I keep getting corrupted xls files. And it is quite annoying. I don't get those corrupted files when I make the request directly from the browser.
Got any clues where it comes from ?
POST method :
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(url + param + format);
Response res = target.request().get();
if (res.getStatus() == 200) {
response.setHeader("Content-Disposition", "attachment; filename=test.xls");
InputStream in = res.readEntity(InputStream.class);
ServletOutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
while (in.read(buffer) >= 0) {
out.write(buffer);
}
out.flush();
}
client.close();
}
Simplest way is to read the response stream and write it straight to the response output stream. Either use a library function from IOUtils or Guava or pure java...
try (InputStream in = ...;
OutputStream out = ...) {
byte[] buffer = new byte[1024];
while (in.read(buffer) >= 0)
out.write(buffer);
} catch (IOException ex) {
...
}
A nicer (depending on your view) way would be to read/save the response as a temporary file then you could return that or write it to the output stream.
Third approach would be to create a pipe, but I don't think that would be applicable here.

Return File From Resteasy Server

Hi, I wanted to return a file from a resteasy server. For this purpose, I have a link at the client side which is calling a rest service with ajax. I want to return the file in the rest service. I tried these two blocks of code, but both didn't work as I wanted them to.
#POST
#Path("/exportContacts")
public Response exportContacts(#Context HttpServletRequest request, #QueryParam("alt") String alt) throws IOException {
String sb = "Sedat BaSAR";
byte[] outputByte = sb.getBytes();
return Response
.ok(outputByte, MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition","attachment; filename = temp.csv")
.build();
}
.
#POST
#Path("/exportContacts")
public Response exportContacts(#Context HttpServletRequest request, #Context HttpServletResponse response, #QueryParam("alt") String alt) throws IOException {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=temp.csv");
ServletOutputStream out = response.getOutputStream();
try {
StringBuilder sb = new StringBuilder("Sedat BaSAR");
InputStream in =
new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
byte[] outputByte = sb.getBytes();
//copy binary contect to output stream
while (in.read(outputByte, 0, 4096) != -1) {
out.write(outputByte, 0, 4096);
}
in.close();
out.flush();
out.close();
} catch (Exception e) {
}
return null;
}
When I checked from the firebug console, both of these blocks of code wrote "Sedat BaSAR" in response to the ajax call. However, I want to return "Sedat BaSAR" as a file. How can I do that?
Thanks in advance.
There're two ways to to it.
1st - return a StreamingOutput instace.
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response download() {
InputStream is = getYourInputStream();
StreamingOutput stream = new StreamingOutput() {
public void write(OutputStream output) throws IOException, WebApplicationException {
try {
output.write(IOUtils.toByteArray(is));
}
catch (Exception e) {
throw new WebApplicationException(e);
}
}
};
return Response.ok(stream, MediaType.APPLICATION_OCTET_STREAM).header("content-disposition", "attachment; filename=\"temp.csv\"").build();
}
You can return the filesize adding Content-Length header, as the following example:
return Response.ok(stream, MediaType.APPLICATION_OCTET_STREAM).header("content-disposition", "attachment; filename=\"temp.csv\"").header("Content-Length", getFileSize()).build();
But if you don't want to return a StreamingOutput instance, there's other option.
2nd - Define the inputstream as an entity response.
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response download() {
InputStream is = getYourInputStream();
return Response.code(200).entity(is).build();
}

I can´t open a .pdf in my browser by Java

I´m trying to open a pdf that I have created using iText library in my browser, but it fails.
This is the code I´m using to send to browser
File file = new File(path);
try{
//InputStream stream=blob.getBinaryStream();
InputStream streamEntrada = new FileInputStream(file);
//ServletOutputStream fileOutputStream = response.getOutputStream();
PrintWriter print = response.getWriter();
int ibit = 256;
while ((ibit) >= 0)
{
ibit = streamEntrada.read();
print.write(ibit);
}
response.setContentType("application/text");
response.setHeader("Content-Disposition", "attachment;filename="+name);
response.setHeader("Pragma", "cache");
response.setHeader("Cache-control", "private, max-age=0");
streamEntrada.close();
print.close();
return null;
}
catch(Exception e){
return null;
}
}
I tried with FileOutputStream but isn´t works. I´m desperate.
Thank you.
Now, I´m trying this way, but it doesn´t work:
public class MovilInfoAction extends DownloadAction{
protected StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
//Here the creation of the PDF
//Storing data
PdfData dPdf = pdf.drawPDF(terminal);
String path = dPdf.getPath();//Path
String name = dPdf.getName()+".pdf";//Pdf´s name
String contentType = "application/pdf";//ContentType
response.setContentType(contentType);
response.setHeader("Content-Disposition","attachment; filename="+name);
response.setHeader("Cache-control", "private, max-age=0");
response.setHeader("Content-Disposition", "inline");
File file = new File(path);
byte[] pdfBytes = es.vodafone.framework.utils.Utils.getBytesFromFile(file);
return new ByteArrayStreamInfo(contentType, pdfBytes);
}
protected class ByteArrayStreamInfo implements StreamInfo {
protected String contentType;
protected byte[] bytes;
public ByteArrayStreamInfo(String contentType, byte[] bytes) {
this.contentType = contentType;
this.bytes = bytes;
}
public String getContentType() {
return contentType;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
}
}
You specify the mimetype as application/text, when it should be application/pdf.
You should set the Header and ContentType before you write the data.
And set the Content Type to application/pdf.
change
response.setContentType("application/text");
to
response.setContentType("application/pdf");
and if you want your pdf to open in browser then make following change
response.setHeader("Content-Disposition", "inline");
Put the filename in double quote "
response.setHeader("Content-Disposition","attachment; filename=\"" + attachmentName + "\"");
Android Default Browser requires GET Request. It does not understand POST Request and hence cannot download the attachment. You can send a GET request as by sending GET request, it resolved my problem. Android browser generates a GET request on its own and sends it back to server. The response received after second request will be considered final by the browser even if GET request is sent on first time by the servlet.

How to correctly read url content with utf8 chars?

public class URLReader {
public static byte[] read(String from, String to, String string){
try {
String text = "http://translate.google.com/translate_a/t?"+
"client=o&text="+URLEncoder.encode(string, "UTF-8")+
"&hl=en&sl="+from+"&tl="+to+"";
URL url = new URL(text);
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream(), "UTF-8"));
String json = in.readLine();
byte[] bytes = json.getBytes("UTF-8");
in.close();
return bytes;
//return text.getBytes();
}
catch (Exception e) {
return null;
}
}
}
and:
public class AbcServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain;charset=UTF-8");
resp.getWriter().println(new String(URLReader.read("pl", "en", "koń")));
}
}
When I run this i get:{"sentences"[{"trans":"end","orig":"koďż˝","translit":"","src_translit":""}],"src":"pl","server_time":30}
so utf doesnt work correctly but if i return encoded url: http://translate.google.com/translate_a/t?client=o&text=ko%C5%84&hl=en&sl=pl&tl=en and paste at url bar i get correctly:{"sentences":[{"trans":"horse","orig":"koń","translit":"","src_translit":""}],"dict":[{"pos":"noun","terms":["horse"]}],"src":"pl","server_time":76}
byte[] bytes = json.getBytes("UTF-8");
gives you a UTF-8 bytes sequences so URLReader.read also give you UTF-8 bytes sequences
but you tried to decode with without specifying the encoder, i.e. new String(URLReader.read("pl", "en", "koń")) so Java will use your system default encoding to decode (which is not UTF-8)
Try :
new String(URLReader.read("pl", "en", "koń"), "UTF-8")
Update
Here is fully working code on my machine:
public class URLReader {
public static byte[] read(String from, String to, String string) {
try {
String text = "http://translate.google.com/translate_a/t?"
+ "client=o&text=" + URLEncoder.encode(string, "UTF-8")
+ "&hl=en&sl=" + from + "&tl=" + to + "";
URL url = new URL(text);
URLConnection conn = url.openConnection();
// Look like faking the request coming from Web browser solve 403 error
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String json = in.readLine();
byte[] bytes = json.getBytes("UTF-8");
in.close();
return bytes;
//return text.getBytes();
} catch (Exception e) {
System.out.println(e);
// becarful with returning null. subsequence call will return NullPointException.
return null;
}
}
}
Don't forget to escape ń to \u0144. Java compiler may not compile Unicode text properly so it is good idea to write it in plain ASCII.
public class AbcServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain;charset=UTF-8");
byte[] read = URLReader.read("pl", "en", "ko\u0144");
resp.getOutputStream().write(read) ;
}
}

Categories

Resources