2010-08-11 9 views
5

HttpURLConnection ne supporte que des choses comme GET, POST et HEAD - mais pas REPORT/PROPFIND. Je vais implémenter un client CalDAV mais sans les opérations de theese (si je veux les utiliser je reçois une exception ProtocolException) je dois écrire/livrer une bibliothèque HTTP complète et énorme avec auth et ainsi de suite.HttpURLConnection de Java ne supporte pas REPORT/PROPFIND - que dois-je faire?

"Surcharge". Comment envoyer des demandes avec PROPFIND et REPORT?

Comment envoyer des demandes avec PROPFIND et REPORT?

Répondre

3

Vous voudrez probablement rechercher une bibliothèque WebDAV, pas une bibliothèque HTTP, pour celle-ci.

Peut-être jeter un oeil à Apache Jackrabbit.

+0

+1 pour le lien vers Jackrabbit, bien que le lien que vous avez envoyé est pour le côté serveur. Cela pourrait être plus directement pertinent: http://jackrabbit.apache.org/api/1.3/org/apache/jackrabbit/webdav/client/methods/package-summary.html – Bruno

2

Vous pouvez essayer d'utiliser une autre bibliothèque HTTP, tels que Apache HTTP client et étendre son HttpRequestBase (voir par exemple HttpGet et HttpPost).

Vous pouvez également utiliser directement une bibliothèque client WebDAV.

0

Tenir compte à l'aide Caldav4j

Il prend en charge:

  • génération facile de demande rapport
  • basé sur httpclient 3.0
  • app android
  • migration actuellement Jackrabbit
3

J'ai eu un problème similaire sur WebDav pour la méthode PROPFIND.

a résolu le problème en mettant en œuvre cette solution: https://java.net/jira/browse/JERSEY-639

try { 
      httpURLConnection.setRequestMethod(method); 
     } catch (final ProtocolException pe) { 
      try { 
       final Class<?> httpURLConnectionClass = httpURLConnection 
         .getClass(); 
       final Class<?> parentClass = httpURLConnectionClass 
         .getSuperclass(); 
       final Field methodField; 
       // If the implementation class is an HTTPS URL Connection, we 
       // need to go up one level higher in the heirarchy to modify the 
       // 'method' field. 
       if (parentClass == HttpsURLConnection.class) { 
        methodField = parentClass.getSuperclass().getDeclaredField(
          "method"); 
       } else { 
        methodField = parentClass.getDeclaredField("method"); 
       } 
       methodField.setAccessible(true); 
       methodField.set(httpURLConnection, method); 
      } catch (final Exception e) { 
       throw new RuntimeException(e); 

      } 
    } 
+1

Bonne réponse! Cependant, dans mon cas, httpURLConnection a un délégué et la réponse ne fonctionne pas. Par conséquent, j'extraire le champ délégué de l'objet httpURLConnection par la réflexion. Le champ délégué est également la sous-classe (sub sub) de HttpURLConnection. J'applique votre procédure pour cette connexion de délégué par methodField = parentClass.getSuperclass(). GetSuperclass(). GetDeclaredField ("méthode") ;. Cela fonctionne bien. Merci! – KNaito

+0

J'ai essayé la solution ci-dessus, et obtenu erro comme "méthode http non autorisé". Pourriez-vous s'il vous plaît donner un pointeur à ce sujet?Je vois aussi que httpURLConnection a un délégué, mais quand j'ai essayé la solution commentée, j'obtiens une erreur noSuchMethod. – Dhamayanthi

+0

@KNaito pourrait vous aider à me s'il vous plaît résoudre ce problème, j'utilise JDK 1.7 et directement à l'aide HttpURLConnection – Dhamayanthi

3

Soit vous pouvez utiliser https://github.com/square/okhttp

Exemple de code

// using OkHttp 
    public class PropFindExample {   
    private final OkHttpClient client = new OkHttpClient(); 
    String run(String url) throws IOException { 
     String credential = Credentials.basic(userName, password); 
     // body 
     String body = "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\">\n" + 
       " <d:prop>\n" + 
       "  <d:displayname />\n" + 
       "  <d:getetag />\n" + 
       " </d:prop>\n" + 
       "</d:propfind>"; 
     Request request = new Request.Builder() 
       .url(url) 
       .method("PROPFIND", RequestBody.create(MediaType.parse(body), body)) 
       .header("DEPTH", "1") 
       .header("Authorization", credential) 
       .header("Content-Type", "text/xml") 
       .build(); 

     Response response = client.newCall(request).execute(); 
     return response.body().string(); 
    } 
} 

Ou jouer avec douilles

Exemple de code

String host = "example.com"; 
int port = 443; 
String path = "/placeholder"; 
String userName = "username"; 
String password = "password"; 

SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
Socket socket = ssf.createSocket(host, port); 
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))); 

// xml data to be sent in body 
String xmlData = "<?xml version=\"1.0\"?> <d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\"> <d:prop> <d:displayname /> <d:getetag /> </d:prop> </d:propfind>"; 
// append headers 
out.println("PROPFIND path HTTP/1.1"); 
out.println("Host: "+host); 
String userCredentials = username+":"+password; 
String basicAuth = "Basic " + new String(Base64.encode(userCredentials.getBytes(), Base64.DEFAULT)); 
String authorization = "Authorization: " + basicAuth; 
out.println(authorization.trim()); 
out.println("Content-Length: "+ xmlData.length()); 
out.println("Content-Type: text/xml"); 
out.println("Depth: 1"); 
out.println(); 
// append body 
out.println(xmlData); 
out.flush(); 

// get response 
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
String inputLine; 

System.out.println("--------------------------------------------------------"); 
System.out.println("---------------Printing response--------------------------"); 
System.out.println("--------------------------------------------------------"); 
while ((inputLine = in.readLine()) != null) { 
    System.out.println(inputLine); 
} 

in.close(); 
+0

S'il vous plaît ne pas [copier/coller] (http://stackoverflow.com/a/35490228/189134) la même réponse à plusieurs questions. Au lieu de personnaliser la réponse aux questions individuelles et expliquer comment ils résolvent ce problème particulier. – Andy

+0

Bien sûr! Merci pour votre message! –

0
private static void setRequestMethod(HttpURLConnection conn, String method) throws Throwable { 
    try { 
     conn.setRequestMethod(method); 
    } catch (ProtocolException e) { 
     Class<?> c = conn.getClass(); 
     Field methodField = null; 
     Field delegateField = null; 
     try { 
      delegateField = c.getDeclaredField("delegate"); 
     } catch (NoSuchFieldException nsfe) { 

     } 
     while (c != null && methodField == null) { 
      try { 
       methodField = c.getDeclaredField("method"); 
      } catch (NoSuchFieldException nsfe) { 

      } 
      if (methodField == null) { 
       c = c.getSuperclass(); 
      } 
     } 
     if (methodField != null) { 
      methodField.setAccessible(true); 
      methodField.set(conn, method); 
     } 

     if (delegateField != null) { 
      delegateField.setAccessible(true); 
      HttpURLConnection delegate = (HttpURLConnection) delegateField.get(conn); 
      setRequestMethod(delegate, method); 
     } 
    } 
}