在 Jersey REST 服务中调用 Google Geocode API 导致内部 400 错误

Call to Google Geocode API within Jersey REST Service causes internal 400 error

我在尝试访问后端的球衣 REST 服务调用中的 Google 地理编码 API 时遇到问题。 当我这样做时,它会导致服务器出现内部 HTTP 400 错误 但是,直接通过浏览器或客户端调用调用 Geocode API 是可行的 此外,调用另一个球衣休息服务的球衣休息服务也可以 直接调用任何东西都有效。将球衣服务嵌套在另一个球衣服务中是可行的。但是在球衣服务中嵌套 Google API 调用失败。

调用位置服务("A")

JerseyClient client = JerseyClientBuilder.newClient();

JerseyWebTarget webTarget = client.target("http://localhost:8080/arenamaster-backend/api").path("tournaments").path("location");

JerseyInvocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);

String input = "10621 Braddock Road – Ste B, Fairfax, VA 22032";

Response response = invocationBuilder
                .post(Entity.entity(input, MediaType.TEXT_PLAIN));

定位服务:("B")

@POST
@Path("/location")
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_JSON)
@CrossOrigin
public Response getLatLngFromAddress(String address) {
    LatLng latlng = LocationUtility.geocode(address);

    return Response.status(200).entity(latlng).build();     
}

直接调用位置实用程序地理编码器("C")

String address = "10621 Braddock Road – Ste B, Fairfax, VA 22032";

LatLng latlng= LocationUtility.geocode(address); 

System.out.println(latlng);

地理编码函数调用 Google 地理编码 API ("D")

public static LatLng geocode(String address) {
    String address_key = address.replace(' ', '+');                 
    String API_key = "***hidden***";            

    String request = "https://maps.googleapis.com/maps/api/geocode/json?address=" + address_key + "&key=" + API_key;
    JerseyClient client = JerseyClientBuilder.newClient();

    JerseyWebTarget webTarget = client.target(request);

    JerseyInvocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);

    Response response = invocationBuilder
            .get(Response.class);

    if (response.getStatus()/100 != 2) {
        throw new RuntimeException("Failed : HTTP error code : "
                + response.getStatus());
    }

    String output = response.readEntity(String.class);

    LatLng latlng = null;

    try {
        JSONObject geocode = new JSONObject(output);
        JSONArray results = geocode.getJSONArray("results");
        JSONObject address_components = (JSONObject) results.get(0);
        JSONObject geometry = (JSONObject) address_components.get("geometry");
        JSONObject location = (JSONObject) geometry.get("location");
        latlng = new LatLng(location.getDouble("lat"), location.getDouble("lng"));
    }catch(Exception e) {
        e.printStackTrace();
    }

    return latlng;
}

呼叫样本测试中的呼叫 ("E")

//call within a call sample test
JerseyClient client = JerseyClientBuilder.newClient();

JerseyWebTarget webTarget = client.target("http://localhost:8080/arenamaster-backend/api").path("test").path("func1");

JerseyInvocation.Builder invocationBuilder = webTarget.request(MediaType.TEXT_PLAIN);


Response response = invocationBuilder
    .get(Response.class);

if (response.getStatus()/100 != 2) {
    throw new RuntimeException("Failed : HTTP error code : "
        + response.getStatus());
}

System.out.println("Output from Server .... \n");
String output = response.readEntity(String.class);
System.out.println(output);

在一个调用中调用两个测试服务端点 ("F")

@GET
@Path("/func1")
@Produces(MediaType.TEXT_PLAIN)
@CrossOrigin
public Response testFunc1() {
    System.out.println("1st service invoked");
    String response = "";

    response = TestDAO.callSecondService();

    return Response.status(200).entity(response).build();
}

@GET
@Path("/func2")
@Produces(MediaType.TEXT_PLAIN)
@CrossOrigin
public Response testFunc2() {
    System.out.println("2nd service invoked");
    String response = "";

    response = TestDAO.getMessage();

    return Response.status(200).entity(response).build();
}

在调用测试函数中调用:("G")

public static String callSecondService() {

    JerseyClient client = JerseyClientBuilder.newClient();

    JerseyWebTarget webTarget = client.target("http://localhost:8080/arenamaster-backend/api").path("test").path("func2");

    JerseyInvocation.Builder invocationBuilder = webTarget.request();


    Response response = invocationBuilder
            .get(Response.class);

    if (response.getStatus()/100 != 2) {
        throw new RuntimeException("Failed : HTTP error code : "
                + response.getStatus());
    }

    System.out.println("Output from Server .... \n");
    String output = response.readEntity(String.class);
    System.out.println(output);

    return output;
}

public static String getMessage() {
    return "Success!"; 
}

C-D 成功 E-F-G 成功 A-B-D 失败并在服务器控制台上打印下面的堆栈跟踪

    java.lang.RuntimeException: Failed : HTTP error code : 400
at utilities.LocationUtility.geocode(LocationUtility.java:38)
at services.TournamentAlphaService.getLatLngFromAddress(TournamentAlphaService.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static[=19=](ResourceMethodInvocationHandlerFactory.java:52)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:124)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:253)
at org.glassfish.jersey.internal.Errors.call(Errors.java:248)
at org.glassfish.jersey.internal.Errors.call(Errors.java:244)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:392)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:365)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:318)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

更新:

呼叫内呼叫测试 (E-F-G) 在以下行时正常工作

WebTarget webTarget = client.target("http://localhost:8080/arenamaster-backend/api").path("test").path("func3"); 被这个取代: WebTarget webTarget = client.target("https://en.wikipedia.org/wiki/List_of_HTTP_status_codes");

阅读正文后发现 Google 地理编码 API 不接受 non-UTF-8 字符编码。我必须更改这一行才能使其正常工作:

String request = "https://maps.googleapis.com/maps/api/geocode/json?address=" + new URLEncoder().encode(address_key, Charset.availableCharsets().get("UTF-8")) + "&key=" + API_key;