6

HttpURLConnection does only support things like GET, POST and HEAD - but no REPORT/PROPFIND. I'm going to implement a CalDAV-Client but without theese operations (if I want to use them I get a ProtocolException) I have to write/deliver a complete and huge HTTP library with auth and so on.

"Overkill".

How do I send requests with PROPFIND and REPORT?

4

8 回答 8

4

对于 PROPFIND 方法,我在 WebDav 上遇到了类似的问题。

通过实施此解决方案解决了问题: 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);

            }
     }
于 2014-08-26T14:54:55.747 回答
3

您可能希望为此寻找一个 WebDAV 库,而不是 HTTP 库。

也许看看Apache Jackrabbit

于 2010-08-11T14:56:42.010 回答
3

您可以使用https://github.com/square/okhttp

示例代码

    // 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();
    }
 }

或者玩 Sockets

示例代码

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();
于 2016-02-18T18:19:08.607 回答
2

您可以尝试使用另一个 HTTP 库,例如Apache HTTP 客户端并扩展它HttpRequestBase(参见HttpGetHttpPost示例)。

或者,您可以直接使用 WebDAV 客户端库。

于 2010-08-11T15:00:11.743 回答
0

考虑使用Caldav4j

它支持:

  • 轻松生成报告请求
  • 基于httpclient 3.0
  • 安卓应用
  • 目前正在迁移到jackrabbit
于 2011-02-28T23:02:48.590 回答
0

“方法 PROPFIND 不能有请求体。执行此代码时会发生此异常。”

于 2021-10-21T21:16:12.040 回答
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);
        }
    }
}
于 2017-04-03T00:14:27.933 回答
0

"方法 PROPFIND 不能有请求体。执行上述示例代码 3 的代码时会发生此异常。

于 2021-10-22T08:28:46.527 回答