blobStoreService.serve() is not giving download file - java

I have a servlet in which I first download a pdf in from http://www.cbwe.gov.in/htmleditor1/pdf/sample.pdf upload it's content on my blobstore and when a user sends a get request in browser a blob will be downloaded in browser, but instead of downloading it's showing data in some other format. Here is my code of servlet:
package org.ritesh;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import javax.servlet.http.*;
import org.apache.commons.io.IOUtils;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileWriteChannel;
#SuppressWarnings("serial")
public class BlobURLServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "text/plain"
String url="http://www.cbwe.gov.in/htmleditor1/pdf/sample.pdf";
URL url1=new URL(url);
HttpURLConnection conn=(HttpURLConnection) url1.openConnection();
String content_type=conn.getContentType();
InputStream stream =conn.getInputStream();
AppEngineFile file = fileService.createNewBlobFile("application/pdf");
file=new AppEngineFile(file.getFullPath());
Boolean lock = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
// This time we write to the channel directly
String s1="";
String s2="";
byte[] bytes = IOUtils.toByteArray(stream);
writeChannel.write(ByteBuffer.wrap(bytes));
writeChannel.closeFinally();
BlobKey blobKey = fileService.getBlobKey(file);
BlobstoreService blobStoreService = BlobstoreServiceFactory.getBlobstoreService();
blobStoreService.serve(blobKey, resp);
}
}
I deploy this servlet on onemoredemo1.appspot.com. Please open this url and notice when u click on BlobURL servlet it's showing content instead of showing downloading dialog. What modification should I do in my code so it shows download dialog in browser?

Look here:
resp.setContentType("text/plain");
You've said that the content is plain text, when it's not. You need to set the Content-Disposition header appropriately as an attachment, and set the content type to application/pdf.
Additionally, if you're going to serve binary content, you shouldn't also use the writer (which you're writing "Hello, world" with).
If you change your first couple of lines to:
resp.setContentType("application/pdf");
resp.setHeader("Content-Disposition", "attachment;filename=sample.pdf");
you may find that's all that's required.

Related

Blobstore upload files but only the 1st 1 mb

I have a working java servlet which will upload files into the bucket indicated but however, it is only able fully upload files with less than 1MB. If i were to upload a file with more then 1MB, only the 1st MB of data will be uploaded while the rest of the files will be empty.
package com.google.appengine;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.nio.ByteBuffer;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.blobstore.BlobstoreInputStream;
import com.google.appengine.tools.cloudstorage.GcsFileOptions;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.appengine.tools.cloudstorage.GcsOutputChannel;
import com.google.appengine.tools.cloudstorage.GcsService;
import com.google.appengine.tools.cloudstorage.GcsServiceFactory;
import com.google.appengine.tools.cloudstorage.RetryParams;
public class upload extends HttpServlet {
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String Bucketname = (String) session.getAttribute("BUCKET");
Map<String, List<BlobInfo>> blobsData = blobstoreService.getBlobInfos(request);
for (String key : blobsData.keySet())
{
for(BlobInfo blob:blobsData.get(key))
{
byte[] b = new byte[(int)blob.getSize()];
BlobstoreInputStream in = new BlobstoreInputStream(blob.getBlobKey());
in.read(b);
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename filename = new GcsFilename(Bucketname, blob.getFilename());
GcsFileOptions options = new GcsFileOptions.Builder()
.mimeType(blob.getContentType())
//.acl("authenticated-read")
.build();
gcsService.createOrReplace(filename,options,ByteBuffer.wrap(b));
in.close();
}
}
String SharedMessage = "File has been Uploaded Successfully!";
String SharedURL = "";
session.setAttribute("SHAREDMESSAGE",SharedMessage);
session.setAttribute("SHAREDURL",SharedURL);
response.sendRedirect("SharedResult.jsp");
}
}
Any help will be appreciated. Thank you
You're ignoring the return value of in.read(byte[]);. It doesn't necessarily fill the whole array, especially when the array is large. You'll need to read until you get -1, which means the stream has been exhausted.
ByteBuffer b = ByteBuffer.allocate((int)blob.getSize());
BlobstoreInputStream in = new BlobstoreInputStream(blob.getBlobKey());
byte[] buf = new byte[8192];
int bytes = 0;
while((bytes = in.read(buf)) != -1)
b.put(buf, 0, bytes);
b.flip();
...

Downloading image from Url in java.Server returned HTTP response code: 403 error. How can I get the connection to work?

I am trying to downloada picture from a certain url, but cant do so because I somehow have to give the right userclient to the website.I am sure the problem is that I cant give the user client while using the Url class, because the page can be accesed via browser. I tried using proxy and Urlconnection but couldnt get it to work. Please share your toughts on the matter!
My code is the following:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
public class KepLetolto {
public static void main(String[] args) throws IOException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
File file = new File("tempjpeg");
SocketAddress address = new java.net.InetSocketAddress("xyz.com", 8080);
// Create an HTTP Proxy using the above SocketAddress.
Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
URL url_kep =new URL("http://www.theouthousers.com/images/templates/thumbnails/128058/bayfinger_size3.png");
ImageIO.write(ImageIO.read(url_kep), "jpeg", file);
Mat uj = Highgui.imread("temp.jpeg" ,Highgui.CV_LOAD_IMAGE_COLOR);
}
}
Instead of using ImageIO.read(URL), which limits you to the default behavior of the URL's underlying URLConnection, use ImageIO.read(InputStream).
This allows you to use any HTTP client library - including the basic HttpURLConnection, which you can get from (HttpURLConnection)url_kep.openConnection(). Using that, you can set headers such as User-Agent, if that's the header required by the site, or other headers such as Referer which are sometimes used to prevent deep-linking.
Once you set up all the headers and any other request options, you can get an InputStream from the client object, and pass that to ImageIO.
This Solution Worked For Me:
URLConnection openConnection = new URL("YOUR_IMAGE_URL").openConnection();
openConnection.addRequestProperty("User-Agent", "YOUR USER AGENT");
InputStream is = openConnection.getInputStream();
BufferedImage saveImage = ImageIO.read(is);
ImageIO.write(saveImage, "png", new File("PATH\\TO\\IMAGE\\FILE.PNG"));

Uploading a file using RESTful API based on Grails JAX-RS Plugin

I'm trying to get a file with a RESTful API based with JAX-RS on Grails.The file is sent from a regular POST multi-part form with file input tag. ( For sending the file I'm using postman google extention )
But after sending the request I get "HTTP Status 400 - Bad Request" response.
I checked many tutorials and followed exactly their steps but it's not working.
Here is the the code in REST service to handle the request :
import com.sun.jersey.multipart.FormDataParam
import com.sun.jersey.core.header.FormDataContentDisposition;
import org.json.simple.JSONObject
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.ws.rs.Consumes
import javax.ws.rs.FormParam
import javax.ws.rs.GET
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.Context
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.MultivaluedMap
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
#Path('/api/upload/')
class UploadResource {
#POST
#Path("/tst")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces('application/json')
public String uploadFile(#FormDataParam("file") InputStream is, #FormDataParam("file") FormDataContentDisposition fileDetail){
String uploadedFileLocation = "Some Location";
// save it
saveToFile(is, uploadedFileLocation);
JSONObject JObject = new JSONObject();
JObject.put("Message", "Aha")
JObject.put("Response", "200")
JObject.put("Status", "OK")
return JObject.toJSONString()
}
}
And here is the way I send the file :
http://postimg.org/image/x3wfrs6h5/
Instead of disabling Grails' multipart resolver completely for the whole application (see: https://code.google.com/p/grails-jaxrs/issues/detail?id=52#c11) you could get the file by accessing the multipart file from Grails' WebUtils Holder.
#POST
#Path("/tst")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces('application/json')
public String uploadFile() {
String uploadedFileLocation = "Some Location";
// here is the workaround for issue: https://code.google.com/p/grails-jaxrs/issues/detail?id=52
GrailsWebRequest request = WebUtils.retrieveGrailsWebRequest()
MultipartFile multipartFile = request.getRequest().getFile('file')
def is = multipartFile.inputStream
// save it
saveToFile(is, uploadedFileLocation);
JSONObject JObject = new JSONObject();
JObject.put("Message", "Aha")
JObject.put("Response", "200")
JObject.put("Status", "OK")
return JObject.toJSONString()
}
The problem occures because the controller initiated by the jaxrs plugin parses the request upfront and this leads to the error.
This problem is known and there is a workaround for this: https://code.google.com/p/grails-jaxrs/issues/detail?id=52#c11
But it is still a known bug on jaxrs plugin.
By default Grails defines a bean named 'multipartResolver' defined for
CommonsMultipartResolver, but this does not work with jax-rs as per the reasons detailed by Denny.
The only issue I see with his proposal to use GrailsWebRequest is that if you go to YOUR_APP_URL/application.wadl, you will not see the file param there and therefore auto-generated client code will not work.
What I have done is override this in resources.groovy to:
multipartResolver(org.springframework.web.multipart.support.StandardServletMultipartResolver) { bean ->
bean.autowire = 'byName'
}

Generate PDF file in an appropriate format

For my use, I created a PDF file using flying-saucer library. It was a legacy HTML so I cleaned out the XHTML using HTMLCleaner library.
After this I serialize the XML as string then pass it to the iText module of flying-saucer to render it and subsequently create the PDF.
This PDF I place it in the OutputStream. After the response is committed I get a dialog asking to save or open it. However it does not get saved as PDF file. I have to right-click and open it in Adobe or any PDF reader.
How do I make it display in the PDF reader. And make the file be saved as .pdf file. What would be an effective and user-friendly way to handle this issue? Help as always will be greatly appreciated!
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringBufferInputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.DomSerializer;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.PrettyXmlSerializer;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XmlSerializer;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.resource.XMLResource;
public class MyPDF extends HttpServlet {
public MyPDF() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/pdf");
String html = request.getParameter("source");
try
{
HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties props = cleaner.getProperties();
TagNode node = cleaner.clean(html);
//String content = "<" + node.getName() + ">" + cleaner.getInnerHtml(node) + "</" + node.getName() + ">";
//System.out.println("content " +content);
OutputStream os = response.getOutputStream();
System.out.println("encoding " +response.getCharacterEncoding());
final XmlSerializer xmlSerializer = new PrettyXmlSerializer(props);
final String html1 = xmlSerializer.getAsString(node);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html1);
renderer.layout();
renderer.createPDF(os);
os.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public void init() throws ServletException {
}
}
Your MIME type is incorrect for PDF. It should be application/pdf.
Change
response.setContentType("text/pdf");
to
response.setContentType("application/pdf");
See https://www.rfc-editor.org/rfc/rfc3778 for the RFC for the PDF MIME type.
Edit: Totally overlooked the "Save as .pdf" question.
You'll also need to add something like:
response.setHeader("content-disposition", "attachment; filename=yourFileName.pdf");
to tell the browser what the default file name should be.

How do I use Java to launch a local HTML page that uses Javascript to load a local json file and display its contents?

I have a java application that reports on the up/down status of several websites and creates a .json file with the data. I have an HTML page that uses javascript to take a .json file and display a nice little grid with red or green lights telling you if a website is up or down. I have no idea how to make the java app tell the html page exactly what the .json file is named (i create a new timestamped .json file every app run). Is there any way to pass a parameter or something to the HTML page on load (currently using Desktop.getDesktop().browse(URI.create("file://blah");), or am I stuck to overwriting my .json file every time I run the app?
How about using a query parameter? Like file://blah.html?json=foo.json Or a fragment: file://blah.html#foo.json.
You could create a tiny local server and register the url /json to any file you want:
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class main {
static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/", new IndexHandler());
server.createContext("/json", new JsonHandler());
server.start();
}
static class IndexHandler implements HttpHandler {
#Override
public void handle(HttpExchange httpExchange) throws IOException {
String response = readFile("index.html", StandardCharsets.UTF_8);
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
static class JsonHandler implements HttpHandler {
#Override
public void handle(HttpExchange httpExchange) throws IOException {
String response = readFile("whatEverJsonYouWant.json", StandardCharsets.UTF_8);
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
Now the JS can be changed to fetch /json

Categories