从Java客户端应用程序发布到Google App Engine上的servlet的正确方法

问题描述 投票:0回答:1

我已将部署到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-app-engine servlets post apache-httpclient-4.x
1个回答
0
投票

在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

© www.soinside.com 2019 - 2024. All rights reserved.