I hope someone can help me.
I want to send the URL as a string to the client endpoint function, and then I want the endpoint function to load the image and send it via an HTTP request to my servlet (also running on GAE).
The problem is that there is no image at all.
Itβs strange, because if I use the same code (HttpPost class) on the android client, it works fine - the image is sent to the servlet, and the servlet saves the image in the / blobstore data store.
Is it not possible to send an HTTP request from a client endpoint to a servlet?
Solved, see answer below!
Android:
BackendApi.anyMethod("url-to-any-image").execute();
Client Endpoint Function:
@ApiMethod(path = "anyMethod") public void anyMethod(@Named("url") String url) { // -------------------------------------------------- // No input validation here - just a proof of concept // -------------------------------------------------- try { // Download image ByteArrayOutputStream buffer = new ByteArrayOutputStream(); Resources.asByteSource(new URL(url)).copyTo(buffer); // Upload image HttpPost httpPost = new HttpPost(); httpPost.setTarget(new URL(BlobstoreServiceFactory.getBlobstoreService().createUploadUrl("/upload"))); httpPost.add("image", buffer.toByteArray()); httpPost.send(); } catch (IOException e) { LOG.log(Level.WARNING, e.getMessage(), e); } }
HttpPost Class:
public class HttpPost { private final static String CRLF = "\r\n"; private String boundary; private URL url; private ByteArrayOutputStream buffer; public HttpPost() { // Generate random boundary // Boundary length: max. 70 characters (not counting the two leading hyphens) byte[] random = new byte[40]; new Random().nextBytes(random); boundary = Base64.encodeBase64String(random); // Init buffer buffer = new ByteArrayOutputStream(); } public void setTarget(URL url) { this.url = url; } public void add(String key, String value) throws IOException { addToBuffer("--" + boundary + CRLF); addToBuffer("Content-Disposition: form-data; name=\"" + key + "\"" + CRLF); addToBuffer("Content-Type: text/plain; charset=UTF-8" + CRLF + CRLF); addToBuffer(value + CRLF); } public void add(String key, byte[] fileBytes) throws IOException { addToBuffer("--" + boundary + CRLF); addToBuffer("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + key + "\"" + CRLF); addToBuffer("Content-Type: application/octet-stream" + CRLF); addToBuffer("Content-Transfer-Encoding: binary" + CRLF + CRLF); addToBuffer(fileBytes); addToBuffer(CRLF); } public void send() throws IOException { // Add boundary end addToBuffer("--" + boundary + "--" + CRLF); // Open url connection HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); connection.setRequestProperty("User-Agent", "Google App Engine"); // Open data output stream DataOutputStream request = new DataOutputStream(connection.getOutputStream()); request.write(buffer.toByteArray()); request.flush(); request.close(); // Close connection connection.disconnect(); } private void addToBuffer(String string) throws IOException { buffer.write(string.getBytes()); } private void addToBuffer(byte[] bytes) throws IOException { buffer.write(bytes); } }
Http Servlet:
public class Upload extends HttpServlet { private static final Logger LOG = Logger.getLogger(Upload.class.getName()); private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(request); List<BlobKey> blobKeys = blobs.get("image"); if (blobKeys == null) { LOG.warning("No blobkeys found"); return; }