Demande PATCH en utilisant le client Jersey
Je veux exécuter un PATCH de requête pris en charge par notre serveur de test à l'aide de Jersey client. Mon code est comme ci-dessous, mais j'ai com.sun.jersey.api.client.ClientHandlerException: java.net.ProtocolException: HTTP method PATCH doesn't support output
exception. Quelqu'un peut-il me faire savoir qui est mauvais avec le code ci-dessous?
String complete_url = "http://localhost:8080/api/request";
String request = "[{\"op\":\"add\", \"path\":\"/name\", \"value\":\"Hello\"}]";
DefaultClientConfig config = new DefaultClientConfig();
config.getProperties().put(URLConnectionClientHandler.PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND, true);
Client client = Client.create(config);
WebResource resource = client.resource(complete_url);
ClientResponse response = resource.header("Authorization", "Basic xyzabCDef")
.type(new MediaType("application", "json-patch+json"))
.method("PATCH", ClientResponse.class, request);
Ici, c'est la pleine exception,
com.sun.jersey.api.client.ClientHandlerException: java.net.ProtocolException: HTTP method PATCH doesn't support output
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:155)
at com.sun.jersey.api.client.Client.handle(Client.java:652)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.method(WebResource.java:634)
at com.acceptance.common.PatchTest.patch(PatchTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.net.ProtocolException: HTTP method PATCH doesn't support output
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1021)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler$1$1.getOutputStream(URLConnectionClientHandler.java:238)
at com.sun.jersey.api.client.CommittingOutputStream.commitStream(CommittingOutputStream.java:117)
at com.sun.jersey.api.client.CommittingOutputStream.write(CommittingOutputStream.java:89)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
at java.io.BufferedWriter.flush(BufferedWriter.java:236)
at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:300)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:217)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:153)
source d'informationauteur nilesh
Vous devez vous connecter pour publier un commentaire.
C'est un bug dans le courant du JDK de mise en œuvre qui a été fixé dans le JDK8 mise en œuvre.Checkout ce lien pour plus de détails https://bugs.openjdk.java.net/browse/JDK-7157360.
Il y a un moyen de pirater autour de cela, mais Maillot de l'équipe a décidé de ne pas fixer https://github.com/eclipse-ee4j/jersey/issues/1639
2 solutions qui, je pense, de
faire une requête post. Reportez-vous à http://zcox.wordpress.com/2009/06/17/override-the-http-request-method-in-jersey/
]
Pour information, juste au cas où tout le monde court dans cette en Jersey 2, voir:
https://jersey.github.io/apidocs/latest/jersey/org/glassfish/jersey/client/HttpUrlConnectorProvider.html
et l'utilisation de la SET_METHOD_WORKAROUND propriété comme suit:
M'a pris une éternité pour trouver ce - pensé que je pouvais aider de court-circuit de la courbe d'apprentissage pour les autres.
Si vous utilisez
HttpsUrlConnection
(note de l' 's') - puis en définissant laHttpUrlConnectorProvider.SET_METHOD_WORKAROUND
ne fonctionne pas. Continuer la lecture pour une description détaillée de la solution.Dans mon cas, le réglage de
HttpUrlConnectorProvider.SET_METHOD_WORKAROUND
bien causé unNoSuchFieldException
depuis monHttpUrlConnection
instance était en fait de type:sun.net.www.protocol.https.HttpsURLConnectionImpl
et c'est super:javax.net.ssl.HttpsURLConnection
(qui hérite deHttpUrlConnection
).Alors, quand Jackson code d'essayer d'obtenir la méthode de champ à partir de ma connexion instance super (instance de
javax.net.ssl.HttpsURLConnection
) ici:Nous obtenons un
NoSuchFieldException
indiquant qu'un champ nommémethod
n'existe pas (depuis getDeclaredFields() apporte tous les domaines, indépendamment de leur accessibilité, mais seulement pour la classe actuelle, pas toutes les classes de base que l'actuelle classe peut être héritant de).Alors j'ai regardé dans Java HttpUrlConnection code et vu que les méthodes autorisées sont précisées par un private static String[]:
La solution a été de changer ce tableau à l'aide de méthodes de réflexion:
Puisque les méthodes de champ est statique, l'évolution de sa valeur fonctionne pour n'importe quel béton instance qui est l'extension de
HttpUrlConnection
y comprisHttpsUrlConnection
.Note de côté: je préfère Java pour ajouter le PATCH méthode pour le JDK ou de Jackson pour effectuer le champ rechercher à travers l'ensemble de la hiérarchie dans leur solution de contournement.
De toute façon, j'espère que cette solution vous fera gagner du temps.