HttpURLConnection只支持GET,POST和HEAD之類的東西 - 但沒有REPORT/PROPFIND。我要實現一個CalDAV-客戶端,但沒有這些操作(如果我想使用它們,我會得到一個ProtocolException),我必須使用auth等編寫/提供一個完整的大型HTTP庫。Java的HttpURLConnection不支持REPORT/PROPFIND - 我該怎麼辦?
「Overkill」。
如何使用PROPFIND和REPORT發送請求?
HttpURLConnection只支持GET,POST和HEAD之類的東西 - 但沒有REPORT/PROPFIND。我要實現一個CalDAV-客戶端,但沒有這些操作(如果我想使用它們,我會得到一個ProtocolException),我必須使用auth等編寫/提供一個完整的大型HTTP庫。Java的HttpURLConnection不支持REPORT/PROPFIND - 我該怎麼辦?
「Overkill」。
如何使用PROPFIND和REPORT發送請求?
你可能會想爲這個尋找一個WebDAV庫,而不是HTTP庫。
也許看看Apache Jackrabbit。
您可以嘗試使用另一個HTTP庫,例如Apache HTTP client並擴展它的HttpRequestBase
(例如,請參閱HttpGet
和HttpPost
)。
或者,您可以直接使用WebDAV客戶端庫。
我在WebDav for PROPFIND方法上有類似的問題。
通過實施該解決方案解決了問題: 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);
}
}
很好的答案!但是,在我的情況下,httpURLConnection有一個委託,答案不起作用。因此我通過反射提取httpURLConnection對象的委託字段。委託字段也是HttpURLConnection的(sub sub)子類。我通過methodField = parentClass.getSuperclass()。getSuperclass()。getDeclaredField(「method」);來爲你的過程應用這個委託連接。這很好。謝謝! – KNaito 2015-01-04 03:44:31
我嘗試了上面的解決方案,並因爲「http方法不允許」而出錯。你能否給我提供一些指示。我也看到httpURLConnection有一個委託,但是當我嘗試評論的解決方案時,我得到noSuchMethod錯誤。 – Dhamayanthi 2017-08-10 07:19:05
@KNaito能否請你幫我解決這個問題,我使用的是JDK 1.7,並直接使用HttpURLConnection的 – Dhamayanthi 2017-08-22 12:04:51
要麼你可以使用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();
}
}
或用插座玩
示例代碼
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();
的問題請不要[複製/粘貼](http://stackoverflow.com/a/35490228/189134 )多個問題的答案相同。而是定製個別問題的答案,並解釋他們如何解決特定問題。 – Andy 2016-02-19 03:57:59
當然!感謝您的留言! – 2016-02-19 16:05:50
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);
}
}
}
+1的鏈接兔崽子,雖然你發送的鏈接是在服務器端。這可能更直接相關:http://jackrabbit.apache.org/api/1.3/org/apache/jackrabbit/webdav/client/methods/package-summary.html – Bruno 2010-08-11 15:23:26