Java';s HttpURLConnection不';t支持报告/PROPFIND-我该怎么办?
HttpURLConnection只支持GET、POST和HEAD,但不支持REPORT/PROPFIND。我要实现一个CalDAV客户机,但是如果没有这些操作(如果我想使用它们,我会得到一个ProtocolException),我必须用auth编写/交付一个完整的、巨大的HTTP库,等等 “过度杀戮”Java';s HttpURLConnection不';t支持报告/PROPFIND-我该怎么办?,java,caldav,Java,Caldav,HttpURLConnection只支持GET、POST和HEAD,但不支持REPORT/PROPFIND。我要实现一个CalDAV客户机,但是如果没有这些操作(如果我想使用它们,我会得到一个ProtocolException),我必须用auth编写/交付一个完整的、巨大的HTTP库,等等 “过度杀戮” 如何使用PROPFIND和REPORT发送请求?您可能希望为此查找WebDAV库,而不是HTTP库 也许可以看看。您可以尝试使用另一个HTTP库,例如和扩展它(例如,请参见HttpGet和Htt
如何使用PROPFIND和REPORT发送请求?您可能希望为此查找WebDAV库,而不是HTTP库
也许可以看看。您可以尝试使用另一个HTTP库,例如和扩展它(例如,请参见
HttpGet
和HttpPost
)
或者,您可以直接使用WebDAV客户端库。考虑使用
它支持:
- 轻松生成报告请求
- 基于httpclient 3.0
- 安卓应用程序
- 目前正在迁移到jackrabbit
- 我在WebDav上遇到了类似的问题,即PROPFIND方法
通过实施此解决方案解决了问题:
试试看{
httpURLConnection.setRequestMethod(方法);
}捕获(最终协议例外pe){
试一试{
最终类httpURLConnectionClass=httpURLConnection
.getClass();
最终类parentClass=httpURLConnectionClass
.getSuperclass();
最终字段methodField;
//如果实现类是HTTPS URL连接,则
//需要在继承权中提升一级才能修改
//“方法”字段。
if(parentClass==HttpsURLConnection.class){
methodField=parentClass.getSuperclass().getDeclaredField(
“方法”);
}否则{
methodField=parentClass.getDeclaredField(“方法”);
}
methodField.setAccessible(true);
set(httpURLConnection,method);
}捕获(最终异常e){
抛出新的运行时异常(e);
}
}
您可以使用
示例代码
// 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();
//使用OkHttp
公共类PropFindExample{
私有最终OkHttpClient客户端=新OkHttpClient();
字符串运行(字符串url)引发IOException{
字符串凭证=凭证.basic(用户名、密码);
//身体
字符串体=“\n”+
“\n”+
“\n”+
“\n”+
“\n”+
"";
Request Request=newrequest.Builder()
.url(url)
.method(“PROPFIND”,RequestBody.create(MediaType.parse(body),body))
.标题(“深度”、“1”)
.标题(“授权”,凭证)
.header(“内容类型”、“文本/xml”)
.build();
Response=client.newCall(request.execute();
返回响应.body().string();
}
}
或者玩插座
示例代码
// 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();
String host=“example.com”;
int端口=443;
字符串路径=“/placeholder”;
字符串userName=“userName”;
字符串password=“password”;
SSLSocketFactory ssf=(SSLSocketFactory)SSLSocketFactory.getDefault();
Socket Socket=ssf.createSocket(主机、端口);
PrintWriter out=新的PrintWriter(新的BufferedWriter(新的OutputStreamWriter(socket.getOutputStream()));
//要在正文中发送的xml数据
字符串xmlData=“”;
//附加标题
println(“PROPFIND路径HTTP/1.1”);
out.println(“主机:+Host”);
字符串userCredentials=username+“:”+密码;
String basicAuth=“Basic”+新字符串(Base64.encode(userCredentials.getBytes(),Base64.DEFAULT));
字符串authorization=“authorization:”+basicAuth;
out.println(authorization.trim());
out.println(“内容长度:+xmlData.Length());
println(“内容类型:text/xml”);
out.println(“深度:1”);
out.println();
//附加正文
out.println(xmlData);
out.flush();
//得到回应
BufferedReader in=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
字符串输入线;
System.out.println(“-------------------------------------------------------------------------------------”);
System.out.println(“--------------打印响应-------------------------------”);
System.out.println(“-------------------------------------------------------------------------------------”);
而((inputLine=in.readLine())!=null){
系统输出打印LN(输入线);
}
in.close();
私有静态void setRequestMethod(HttpURLConnection conn,String方法)抛出Throwable{
试一试{
conn.setRequestMethod(方法);
}捕获(协议例外e){
c类=连接getClass();
FieldMethodField=null;
字段delegateField=null;
试一试{
delegateField=c.getDeclaredField(“委托”);
}捕获(NoSuchFieldException nsfe){
}
而(c!=null&&methodField==null){
试一试{
methodField=c.getDeclaredField(“方法”);
}捕获(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(委托,方法);
}
}
}
+1用于指向Jackrabbit的链接,尽管您发送的链接是针对服务器端的。这可能更直接相关:断开的链接是一个很好的答案!但是,在我的例子中,httpURLConnection有一个委托,而答案不起作用。因此,我通过re提取httpURLConnection对象的委托字段