Je développe un service qui connecte REST à Java, et avez-vous des demandes que je connecte? Il y a un cas que je veux confirmer. Dans un tel cas, je passe par un proxy, mais j'ai cherché comment le faire et j'organiserai les résultats. Le client Java REST utilise la partie client de Jersey, qui est également l'implémentation de référence de JAX-RS.
Je suis toujours reconnaissant de la sagesse de mes prédécesseurs. En gros, j'ai fait référence aux informations sur ce site. Comment passer un proxy avec Jersey Client
Cependant, au moins dans l'API à laquelle j'accède cette fois, l'erreur suivante de SSL
javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Cela semble se produire, je vais donc me concentrer sur l'enquête supplémentaire.
pom.xml
<!--Mais si vous utilisez simplement le client Jersey-->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.25</version>
</dependency>
<!--De plus, lors de l'utilisation de Proxy avec Jersey.-->
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
<version>2.25</version>
</dependency>
La destination d'accès est l'API de Qiita
https://qiita.com/api/v2/users/qiita/items?per_page=1&page=4
J'essaierai de cibler.
curl 'https://qiita.com/api/v2/users/qiita/items' -d 'per_page=1' -d 'page=4' -G
Je pense que du JSON est retourné.
Vient ensuite Java. Le premier est le modèle qui ne passe pas par le proxy.
Nous allons l'implémenter en se référant au document suivant. Jersey 2.25 User Guide/5. Client API
ClientSamples.java
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class ClientSamples {
public static void main(String[] args) {
new ClientSamples().execute();
}
public void execute() {
String target = "https://qiita.com";
String path = "/api/v2/users/qiita/items";
// Client client = createSecureClient();
Client client = createClient();
Response restResponse = client
.target(target)
.path(path)
.queryParam("page", "4")
.queryParam("per_page", "1")
.request(MediaType.APPLICATION_JSON_TYPE)
.get();
System.out.println(restResponse.readEntity(String.class));
}
private Client createClient() {
return ClientBuilder.newClient();
}
}
Vous devriez obtenir le même résultat qu'avec curl.
Veuillez vous référer à la page suivante et au site que j'ai mentionné plus tôt comme référence. Comment passer un proxy avec Jersey Client Jersey 2.25 User Guide/5.9. Securing a Client
ClientSamples.java
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
public class ClientSamples {
public static void main(String[] args) {
new ClientSamples().execute();
}
public void execute() {
String target = "https://qiita.com";
String path = "/api/v2/users/qiita/items";
Client client = createSecureClient();
// Client client = createClient();
Response restResponse = client
.target(target)
.path(path)
.queryParam("page", "4")
.queryParam("per_page", "1")
.request(MediaType.APPLICATION_JSON_TYPE).get();
System.out.println(restResponse.readEntity(String.class));
}
private Client createSecureClient() {
String proxyHost = "http://127.0.0.1:8080";
ClientConfig config = new ClientConfig();
//Fournisseur de support proxy?À
config.connectorProvider(new ApacheConnectorProvider());
config.property(ClientProperties.PROXY_URI, proxyHost);
// config.property(ClientProperties.PROXY_USERNAME, "userName");
// config.property(ClientProperties.PROXY_PASSWORD, "password");
//Générer un constructeur
ClientBuilder b = ClientBuilder.newBuilder().withConfig(config);
return b.build();
}
}
Lorsque je l'exécute, j'obtiens toujours une exception javax.net.ssl.SSLHandshakeException. Il semble que vous essayez de vous connecter à un serveur SSL non approuvé via un proxy. Insérez donc le code suivant pour invalider le processus de vérification du certificat SSL et le processus de vérification du nom d'hôte.
ClientSamples.java
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
public class ClientSamples {
public static void main(String[] args) {
new ClientSamples().execute();
}
public void execute() {
String target = "https://qiita.com";
String path = "/api/v2/users/qiita/items";
Client client = createSecureClient();
// Client client = createClient();
Response restResponse = client
.target(target)
.path(path)
.queryParam("page", "4")
.queryParam("per_page", "1")
.request(MediaType.APPLICATION_JSON_TYPE)
.get();
System.out.println(restResponse.readEntity(String.class));
}
private Client createClient() {
return ClientBuilder.newClient();
}
private Client createSecureClient() {
String proxyHost = "http://127.0.0.1:8080";
ClientConfig config = new ClientConfig();
//Fournisseur de support proxy?À
config.connectorProvider(new ApacheConnectorProvider());
config.property(ClientProperties.PROXY_URI, proxyHost);
// config.property(ClientProperties.PROXY_USERNAME, "userName");
// config.property(ClientProperties.PROXY_PASSWORD, "password");
SSLContext sslContext = createSSLContext();
HostnameVerifier hostnameVerifier = createHostNameVerifier();
//Générer un constructeur
ClientBuilder b = ClientBuilder.newBuilder().withConfig(config)
.sslContext(sslContext).hostnameVerifier(hostnameVerifier);
return b.build();
}
private SSLContext createSSLContext() {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null,
new X509TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
} }, new SecureRandom());
// HttpsURLConnection
// .setDefaultSSLSocketFactory(sslContext.getSocketFactory());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslContext;
}
private HostnameVerifier createHostNameVerifier() {
return new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {return true;}
};
}
}
Cela semble fonctionner. .. Il semble qu'il puisse également gérer les cas où le serveur de test a un certificat oléore.
Comment passer un proxy avec Jersey Client Jersey 2.25 User Guide/5. Client API Jersey 2.25 User Guide/5.9. Securing a Client