我已将部署到App Engine。 我设置了SSL,并将其与自定义域相关联。 当我在本地开发应用程序时,通过http:// localhost:8080 / servlet发送到servlet时 ,按预期方式工作,但是当我将其部署到App Engine时,还没有得到合适的结果。 我已经尝试了很多事情,并且不断得到的响应代码是404或500。
我从简单的HTTPUrlConnection和DataOutputstream开始,向Servlet发送JSON,并获得适当的响应。 像这样:
URL url;
HttpURLConnection connection = null;
try {
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("custom-Header", "XYZ");
connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(urlParameters);
wr.flush ();
wr.close ();
//Get Response
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
}
finally {
if(connection != null) {
connection.disconnect();
}
}
这在本地有效。
我现在尝试使用Apache Common的HttpAsyncClient来检查它是否可能是时间问题:
final ResponseObject responseObject = new ResponseObject(); //my simple POJO
try(CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setSSLStrategy(sslSessionStrategy)
.build()) {
httpclient.start();
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/json");
post.setHeader("custom-Header", "XYZ");
post.setHeader("Content-Language", "en-US");
HttpEntity entity = new ByteArrayEntity(urlParameters);
post.setEntity(entity);
final CountDownLatch latch1 = new CountDownLatch(1);
httpclient.execute(post, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
try {
responseObject.message = entity != null ? EntityUtils.toString(entity) : null;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
responseObject.exception = new ClientProtocolException("Unexpected response status: " + status);
}
latch1.countDown();
}
public void failed(final Exception ex) {
responseObject.exception = ex;
latch1.countDown();
}
public void cancelled() {
latch1.countDown();
}
});
latch1.await();
if(responseObject.exception != null) {
throw responseObject.exception;
} else {
return responseObject.message;
}
}
这也可以在本地使用,但是在尝试访问AppEngine时仍然无法进行。
这是我简单的web.xml:
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>my.servlet.package.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>everything</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<welcome-file-list>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
在本地,我发布到http:// localhost:8080 / login 。 至于App Engine,我发给了ff:
我尝试过更改url模式。 我从/ login开始,然后登录 ,然后显式尝试了App Engine和自定义域url(即myapp.appspot.com/login和myapp.mydomain.com/login)。 在尝试没有与servlet关联的实际页面(即login.jsp或login.html)之后,我也尝试将实际的jsp或html页面发布到该页面。
当我使用HttpAsyncClient(由于SSLContext而选择)时,我得到的最好结果是与Servlet关联的页面的HTML,但从来没有我需要Servlet的响应。
有任何想法吗?
在Google Cloud Platform分散的文档之一上找到了答案: https : //cloud.google.com/appengine/docs/standard/java/how-requests-are-handled https://cloud.google.com/appengine/docs /标准/ JAVA /如何-请求,被路由
基本上,您必须在项目的appspot网址之前加上myapp.appspot.com之类的名称,并带有应用程序任何有效服务实例的版本ID。 您可以在App Engine控制台的“版本”页面下找到此类ID。 例如: https : //versionId.myapp.appspot.com 。