Java 谷歌地图API(方向)在Payara中抛出403错误,而不是在WebLogic中

Java 谷歌地图API(方向)在Payara中抛出403错误,而不是在WebLogic中,java,google-maps,directions,payara,Java,Google Maps,Directions,Payara,我的任务是将我们的应用程序从WebLogic 12.1.3迁移到Payara 4.1,我遇到了一个问题,我觉得我差不多已经到了故障排除的终点。 我们有一个EJB(一个无状态bean),它有两个方法,一个调用Google Maps Directions API,另一个调用Google Maps Geocoding API,这两个方法都使用相同的凭证和用于Java的Google客户端库。这两种方法都在WebLogic上运行,但在切换到Payara后,使用Directions API的方法给了我一个错

我的任务是将我们的应用程序从WebLogic 12.1.3迁移到Payara 4.1,我遇到了一个问题,我觉得我差不多已经到了故障排除的终点。 我们有一个EJB(一个无状态bean),它有两个方法,一个调用Google Maps Directions API,另一个调用Google Maps Geocoding API,这两个方法都使用相同的凭证和用于Java的Google客户端库。这两种方法都在WebLogic上运行,但在切换到Payara后,使用Directions API的方法给了我一个错误。以下是stacktrace的相关部分:

java.io.IOException: Server Error: 403 Forbidden
    at com.google.maps.internal.OkHttpPendingResult.parseResponse(OkHttpPendingResult.java:258)
    at com.google.maps.internal.OkHttpPendingResult.await(OkHttpPendingResult.java:167)
    at com.google.maps.PendingResultBase.await(PendingResultBase.java:56)
    at com.somecompany.integration.GoogleDirectionsIntegration.getDirections(GoogleDirectionsIntegration.java:XXX)
    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)
因此,地理编码方法在这两种平台上仍然有效,但当尝试调用Directions API时,我从Google得到一个403,表明我的凭证被弄乱了,但同样的凭证适用于地理编码调用。代码在从一个平台切换到另一个平台时没有任何改变

更令人困惑的是,如果我从日志中抓取呼叫谷歌的实际URL并在浏览器中尝试,即粘贴“ 里金=某地&目的地=某地+其他地&候补地 ives=false&signature=nfre3XYZ2kmuDX8Qibce87ZFKQQ=“进入Chrome,它可以工作。我从谷歌那里得到了正确的答案。(顺便说一句,这些不是我使用的实际凭证或来源地和目的地,它们已“匿名化”:-)。我还检查了这个URL(由客户端库构建)是否在两个平台上运行,以及是否在Google的开发者页面上使用了URL签名调试器,但都没有用。我的证件应该没有问题

我真的已经走到了这条线的尽头,已经花了好几天的时间进行故障排除和在线搜索,却没有找到解决方案

这并不重要,但我自己并没有写这段代码,当然,写这段代码的人也不再在这里工作了

无论如何,下面是代码(有点匿名):

@无状态
公共类GoogleDirectionsIntegration{
私有静态最终记录器Logger=Logger.getLogger(GoogleDirectionIntegration.class.getName());
私有GeoApicContext上下文=null;
/**
*初始值设定项
*/
@施工后
公共void init(){
LOGGER.log(Level.INFO,“初始化{0}”,this.getClass().getSimpleName());
this.context=new GeoApiContext().setEnterpriseCredentials(“gme公司”、“companyGoogleCryptographicSecret”);
this.context.setReadTimeout(1,TimeUnit.SECONDS)
.setRetryTimeout(1,时间单位为秒)
.setConnectTimeout(1,时间单位为秒)
.setWriteTimeout(1,时间单位为秒);
OkHttpRequestHandler OkHttpRequestHandler=null;
OkHttpClient OkHttpClient=null;
试一试{
Field requestField=this.context.getClass().getDeclaredField(“requestHandler”);
requestField.setAccessible(true);
okHttpRequestHandler=(okHttpRequestHandler)requestField.get(this.context);
字段f=okHttpRequestHandler.getClass().getDeclaredField(“客户端”);
f、 setAccessible(true);
okHttpClient=(okHttpClient)f.get(okHttpRequestHandler);
}捕获(NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException e){
抛出新的IllegalStateException(“未能创建SSL上下文”,e);
}
SSLContext sslCtx=this.getSslContext();
if(sslCtx!=null&&okHttpClient!=null){
SSLSocketFactory SSLSocketFactory=sslCtx.getSocketFactory();
okHttpClient.SetssSocketFactory(sslSocketFactory);
}
}
私有SSLContext getSslContext(){
TrustManager[]tm=新的TrustManager[]{
新CustomTrustManager()
};
SSLContext SSLContext=null;
试一试{
sslContext=sslContext.getInstance(“TLSv1.2”);
init(null,tm,new SecureRandom());
}catch(nosuchagorithmexception | KeyManagementException ex){
抛出新的IllegalStateException(“未能创建SSL上下文”,ex);
}
返回sslContext;
}
公共方向Route getDirections(最终字符串原点、最终字符串目标、最终距离单位距离单位、,
@Nullable TransportMode模式,@NotNull Instant arrivalTime)引发NotFoundException{
TransportMode actualMode=mode==null?TransportMode.CAR:mode;
方向路线[]方向路线;
DirectionsApi请求DirectionsApi请求=DirectionsApi.getDirections(this.context,origin,destination);
directionsApiRequest.arrivalTime(新即时(arrivalTime));
directionsApiRequest.Alternations(错误);
directionsApiRequest.mode(this.toTravelMode(actualMode));
试一试{
DirectionsResult res=directionsApiRequest.await();//这就是它中断的地方!
方向路由=恢复路由;
}捕获(例外e){
LOGGER.log(Level.WARNING,e.getMessage(),e);
抛出新的NotFoundException(如getMessage());
}
if(directionsrouts.length!=1){
抛出new NotFoundException(“未能获取有效方向”);
}
返回方向路由[0];
}
public void getAddress(位置、位置、布尔缓存覆盖)引发异常{
com.google.maps.model.LatLng gLatLng=new com.google.maps.model.LatLng(startLocation.getLat(),startLocation.getLng());
GeocodingApiRequest GeocodingApiRequest=GeocodingApi.reverseGeocode(this.context,gLatLng);
地理编码结果[]地理编码结果;
geocodingResults=geocodingApiRequest.await();
if(0<地理编码结果长度){
//…与结果相关的代码。。
}否则{
LOGGER.log(Level.WARNING,“收到来自[{0}]的Google反向地理编码的空结果”,第二级);
}
}
}

所以我解决了它。问题不在代码中,而是在依赖项中,或者更确切地说是在依赖项之一的依赖项中—OkHttp。我只是简单地更改了版本,现在就可以使用了。

您已经为您的密钥启用了Google Maps Directions Web服务了吗?(中)@geoc
@Stateless
public class GoogleDirectionsIntegration {

private static final Logger LOGGER = Logger.getLogger(GoogleDirectionsIntegration.class.getName());

private GeoApiContext context = null;

/**
 * Initializer
 */
@PostConstruct
public void init() {
    LOGGER.log(Level.INFO, "initiating {0}", this.getClass().getSimpleName());
    this.context = new GeoApiContext().setEnterpriseCredentials("gme-company", "companyGoogleCryptographicSecret");
    this.context.setReadTimeout(1, TimeUnit.SECONDS)
            .setRetryTimeout(1, TimeUnit.SECONDS)
            .setConnectTimeout(1, TimeUnit.SECONDS)
            .setWriteTimeout(1, TimeUnit.SECONDS);
    OkHttpRequestHandler okHttpRequestHandler = null;
    OkHttpClient okHttpClient = null;

    try {
        Field requestField = this.context.getClass().getDeclaredField("requestHandler");
        requestField.setAccessible(true);
        okHttpRequestHandler = (OkHttpRequestHandler) requestField.get(this.context);
        Field f = okHttpRequestHandler.getClass().getDeclaredField("client");
        f.setAccessible(true);
        okHttpClient = (OkHttpClient) f.get(okHttpRequestHandler);
    } catch (NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException e) {
        throw new IllegalStateException("Failed to create SSL context", e);
    }

    SSLContext sslCtx = this.getSslContext();

    if (sslCtx != null && okHttpClient != null) {
        SSLSocketFactory sslSocketFactory = sslCtx.getSocketFactory();
        okHttpClient.setSslSocketFactory(sslSocketFactory);
    }
}

private SSLContext getSslContext() {
    TrustManager[] tm = new TrustManager[] {
            new CustomTrustManager()
    };

    SSLContext sslContext = null;
    try {
        sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, tm, new SecureRandom());
    } catch (NoSuchAlgorithmException | KeyManagementException ex) {
        throw new IllegalStateException("Failed to create SSL context", ex);
    }
    return sslContext;
}

public DirectionsRoute getDirections(final String origin, final String destination, final DistanceUnit distanceUnit,
        @Nullable TransportMode mode, @NotNull Instant arrivalTime) throws NotFoundException {
    TransportMode actualMode = mode == null ? TransportMode.CAR : mode;
    DirectionsRoute[] directionsRoutes;

    DirectionsApiRequest directionsApiRequest = DirectionsApi.getDirections(this.context, origin, destination);
    directionsApiRequest.arrivalTime(new Instant(arrivalTime));
    directionsApiRequest.alternatives(false);
    directionsApiRequest.mode(this.toTravelMode(actualMode));

    try {
        DirectionsResult res = directionsApiRequest.await(); // THIS IS WHERE IT BREAKS!
        directionsRoutes = res.routes;
    } catch (Exception e) {
        LOGGER.log(Level.WARNING, e.getMessage(), e);
        throw new NotFoundException(e.getMessage());
    }

    if (directionsRoutes.length != 1) {
        throw new NotFoundException("Failed to fetch valid directions");
    }

    return directionsRoutes[0];
}

public void getAddress(LatLng startLocation, Location location, boolean cacheOverride) throws Exception {
    com.google.maps.model.LatLng gLatLng = new com.google.maps.model.LatLng(startLocation.getLat(), startLocation.getLng());
    GeocodingApiRequest geocodingApiRequest = GeocodingApi.reverseGeocode(this.context, gLatLng);
    GeocodingResult[] geocodingResults;
    geocodingResults = geocodingApiRequest.await();
    if (0 < geocodingResults.length) {
        //.. Code that does stuff with the result..
    } else {
        LOGGER.log(Level.WARNING, "Received empty results from Google reverse geocode for [{0}].", startLocation);
    }
}

}