首页 > 解决方案 > 在 Jersey REST 服务中调用 Google Geocode API 会导致内部 400 错误

问题描述

我在后端的 jersey REST 服务调用中尝试访问 Google Geocode API 时遇到问题。当我这样做时,它会在服务器上导致内部 HTTP 400 错误但是,直接通过浏览器或客户端调用调用 Geocode API 可以工作此外,调用调用另一个球衣休息服务的球衣 REST 服务也可以直接调用对任何事情都有效。将 jersey 服务嵌套在另一个 jersey 服务中是可行的。但是在球衣服务中嵌套 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 Geocode 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!"; 
}

CD 成功 EFG 成功 ABD 失败并在服务器控制台上打印下面的堆栈跟踪

    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$0(ResourceMethodInvocationHandlerFactory.java:52)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.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$1.run(ServerRuntime.java:253)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.glassfish.jersey.internal.Errors$1.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)

更新:

呼叫内呼叫测试(EFG)在以下行时正常工作

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");

标签: javarestjax-rsjersey-2.0

解决方案


阅读正文显示 Google Geocode API 不接受非 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;

推荐阅读