I am trying to implement a very basic functionality of uploading images from Android,iPhone and web clients to the google app engine. I did an initial version of the implementation thanks to this blog:
However there always seems to be a 2 step process to uploading an image:
Get the initial upload URL to POST to using the createUploadUrl(). I am attaching the fragment of code which I use :
public class CreateUploadUrl extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
String uploadURL = blobstoreService.createUploadUrl("/image/uploadImage");
resp.setContentType("text/plain");
resp.getWriter().println(uploadURL);
}
}
POST the image using the URL which you just "got"
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
BlobKey blobKey = ParameterExtractor.getBlobParameter(req, "blob-key", blobstoreService);
if (blobKey == null) {
log.info("blob Id is null. POST failed");
} else {
log.info("ze business logic");
}
}
My question is if it is possible to do it in one step since right now all clients need to do a http GET to get the upload URL and then a http POST to POST the image.
Is it not possible to just do one Http POST with a predefined URL.
Thanks
Rajat
This is possible, with limitations. You can bypass the UploadUrl mechanism by creating blobs directly in your servlet using the (currently experimental) createNewBlobFile API. In your mobile app(s) create an HTTP request encoded as multipart/form-data, and teach your servlet how to decode such a thing (consult e.g. How to upload files in JSP/Servlet?). Be aware that HTTP requests are limited to 32MB; with form encoding the amount of binary data you can upload will be less than that.
Sure you can do it with single POST. For example you have user that have an id. This user select image and you send in POST image data and user data on client side.
On server side (GAE) you have url for image uploding (your_host/imageUpload) and server or Spring controller that read data from request and write it to Blobstore.
Related
So Basically I have:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/zips/packet.html").forward(request, response);
return;
}
As you can you can see when a request is made for this servlet, It responds with packet.html file. To be precise, inside my packet.html I have a video element with src="" which I need to fill it by users requested url.
Question: How do I send a little extra data saying video source to the client, So in my client side it could change the video source from src="" to src="actual video source"
I TRIED:
String video_source = "/zips/video.mp4";
response.getWriter().append(video_source);
request.getRequestDispatcher("/zips/packet.html").forward(request, response);
With this method I can see my packet.html being received in my front-end But I can't find the video_source. FYI: don't know how to receive the video_source.
Well, To satasify your demand you can follow many apporoaches. One approach that I would suggest would put into consideration whatever you've already started
As Below
Step 1. Forward your request and response objects into packet.jsp,instead of into packet.html
Step 2. inside packet.jsp grab the input from user and send it with
the request object from packet.jsp
Step 3. Write a servlet class that process the request object from
packet.jsp and send the video as mulitpart file with the response.
Moreover, Do some research on how to use jsp's and servlets
The second approach would be to write client side javascript code that send ajax request to grab the video in a second call. For this you might even consider some client side frameworks and libraries(like jquery, angular, etc) that ease your work.
You could do the following:
Pass that additional information via request attribute (request.setAttribute())
Use some dynamic handler (like a servlet or JSP) to serve /zips/handler.html
Use request.getAttribute() in that handler.
So:
in your initial servlet, put
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("real_source", /some real source/);
request.getRequestDispatcher("/zips/packet.html").forward(request, response);
return;
}
In your /zips/packet.html you just use request.getAttribute("real_source") to generate the html attribute you need.
I managed to upload the blob from Javascript to Java Endpointfunction
Javascript
var request = gapi.client.helloworldendpoints.uploadImage({
'imageData': __upload.imageData,
'fileName': __upload.fileName,
'mimeType': __upload.mimeType,
'size': __upload.size
});
Java Endpoint
public ImageUploadRequest uploadImage(
Request imageData,
#Named("fileName") String fileName,
#Named("mimeType") String mimeType,
#Named("size") float size
) { ... }
Request is just this
public class Request {
public Blob image;
}
Now i want to send a MultipartRequest from my Java Endpoint at GAE to my UploadServlet to create a blobkey and save the data into blobstorage, since Blobstorage only accepts data send to servlet. How can I create a MultipartRequest?
There are numerous ways to construct an HTTP request in Java. This question, while dealing with some very specific systems, is too broad for Stack Overflow, since the real question is "how can I build and execute a multi-part/form-data request in Java?" You should look into the UrlFetch service on App Engine, since this is how all HTTP requests are sent. You can find examples of HTTP requests in Java all over the internet.
I'm trying to use the code below to upload image to blobstore using curl and I get the following error "Must be called from a blob upload callback request".
However if I use a form with an action it does upload:
blobstoreService.createUploadUrl("/upload")
===Servlet Code===
public class Upload extends HttpServlet {
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
#SuppressWarnings("deprecation")
#Override
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobKey = blobs.get("myFile");
}
}
Does anyone know how I can incorporate " blobstoreService.createUploadUrl("/upload")" into the servlet so that I can perform curl requests as such:
curl -XPOST http://localhost:8888/upload -F "myFile=#image.jpg"
I'm using the following example from Google's developer page:
https://developers.google.com/appengine/docs/java/blobstore/
This is the way the Blobstore works:
You request a URL to do an upload (provision some resources).
The client uses that URL to post (this means, the request goes to the Blobstore servers and not your application).
The Blobstore servers receive the data, save it, and forward the request to your application.
You get the keys and run your code, then return to the client.
What I'm trying to say is that you must let the Blobstore do it's job, that means you can't have a fixed URL for uploads, you must first ask for a URL to post. This is how the system was designed.
So you'll have to make 2 curl calls, one to request the url, then use that to post, no other way around it.
Of course, it's not as sexy or simple, but other solutions would be complicated and even expensive.
Request request = Request.newUploadPhotoRequest(Session.getActiveSession(),imageToBeUploaded,new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(getString(R.string.photo_post),response.getGraphObject(), response.getError());
}
});
ATM I am uploading to facebook by passing a bitmap.
But i have to upload photos from my website. So i download the image in AsyncTask and pass it here
Is there any method to upload via url using non depreciated methods ?
There is no documented way of doing this that I know of, you could use https://developers.facebook.com/docs/reference/api/batch/ (look at the Uploading Binary Data section) , and put in your url requests, but I think the best way is to download the file locally and post it as data , this way you can control the url content
To get the URL hash # in javascript you can just do:
window.location.hash
Is there a similar simple and easy way to do it in JSTL?
Example of a URL I have: http://hatsos.com/#somehashname
If there is not a built-in easy method, how would I go about getting the URL and then parsing the hash out of it?
The only way to get the hash fragment identifier in the server side is to let the client side send a HTTP request with the value as a request parameter whenever it has changed. For example, with Ajax during the window.onhashchange event. I see in your question history that you're familiar with jQuery. Here's a kickoff example:
window.onhashchange = function() {
$.get('someservlet', { 'hash', window.location.hash }, function(response) {
// ...
});
}
with
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String hash = request.getParameter("hash");
// ...
}
To cover lack of IE6/7 support for window.onhashchange, consider jQuery hashchange plugin.
You're talking about a URI Fragment id, and most user agents don't even send that to the server, so you can't really get it there. JavaScript can access it because it runs on the client side.