我希望有人可以帮助我。
我想将一个url作为字符串发送到客户端端点函数,然后我希望端点函数下载图像并通过HTTP Post请求发送到我的servlet(也在GAE上运行)。
问题是 - 根本没有张贴图片。
这很奇怪,因为如果我在Android客户端上使用完全相同的代码(HttpPost类),它工作正常 - 图像被发布到servlet,servlet将图像存储到数据存储区/ blobstore中。
是否有可能从客户端端点函数向servlet发送HTTP Post请求?
解决了,请看下面的答案!
安卓:
BackendApi.anyMethod("url-to-any-image").execute();
客户端端点功能:
@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类:
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;
}
// Get blob key
BlobKey blobKey = blobKeys.get(0);
if (blobKey == null) {
LOG.warning("No blobkey found");
return;
}
// Create new image object
Image image = new Image();
image.setBlobKey(blobKey);
image.setTimestamp(new Date());
// Save image to datastore
OfyService.ofy().save().entity(image).now();
LOG.log(Level.INFO, "Image upload successful");
}
}
根据Google App Engine文档,您不能获取自己的网址:
为了防止应用程序导致无休止的请求递归,请求处理程序不允许获取自己的URL。 仍然可以通过其他方式进行无限递归,因此如果您的应用程序可以获取用户提供的URL请求,请务必谨慎。
这意味着这样做的唯一方法是在Android客户端上下载图像,然后将其发布到HttpServlet。
安卓:
try {
// Download image to the Android client
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Resources.asByteSource(new URL(url)).copyTo(buffer);
// Upload image to HttpServlet
HttpPost httpPost = new HttpPost();
httpPost.setTarget(new URL("http-servlet-upload-url"));
httpPost.add("image", buffer.toByteArray());
httpPost.send();
} catch (IOException e) {
Logcat.error(e.getMessage());
}