网络通信与xml转换知识点.docx
《网络通信与xml转换知识点.docx》由会员分享,可在线阅读,更多相关《网络通信与xml转换知识点.docx(38页珍藏版)》请在冰豆网上搜索。
![网络通信与xml转换知识点.docx](https://file1.bdocx.com/fileroot1/2023-1/8/2bcfb8a9-5789-4378-bbd7-e96564223378/2bcfb8a9-5789-4378-bbd7-e965642233781.gif)
网络通信与xml转换知识点
一,网络工具类
webutils
HTTP协议可能是现在Internet上使用得最多、最重要的协议了,越来越多的Java应用程序需要直接通过HTTP协议来访问网络资源。
虽然在JDK的javanet包中已经提供了访问HTTP协议的基本功能,但是对于大部分应用程序来说,JDK库本身提供的功能还不够丰富和灵活。
HttpClient是ApacheJakartaCommon下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。
HttpClient已经应用在很多的项目中
HttpURLConnection是java的标准类,HttpURLConnection继承自URLConnection,可用于向指定网站发送GET请求、POST请求。
它在URLConnection的基础上提供了如下便捷的方法:
•intgetResponseCode():
获取服务器的响应代码。
•StringgetResponseMessage():
获取服务器的响应消息。
•StringgetResponseMethod():
获取发送请求的方法。
•voidsetRequestMethod(Stringmethod):
设置发送请求的方法。
在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。
但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。
在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。
但不会缓存服务器的响应,不能执行HTML页面中嵌入的Javascript代码;也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
使用HttpClient发送请求、接收响应很简单,只要如下几步即可。
1.创建HttpClient对象。
2.如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3.如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParamsparams)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntityentity)方法来设置请求参数。
4.调用HttpClient对象的execute(HttpUriRequestrequest)发送请求,执行该方法返回一个HttpResponse。
5.调用HttpResponse的getAllHeaders()、getHeaders(Stringname)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。
程序可通过该对象获取服务器的响应内容。
另外,Android已经成功地集成了HttpClient,这意味着开发人员可以直接在Android应用中使用Httpclient来访问提交请求、接收响应。
比如一个Android应用需要向指定页面发送请求,但该页面并不是一个简单的页面,只有当用户已经登录,而且登录用户的用户名有效时才可访问该页面。
如果使用HttpURLConnection来访问这个被保护的页面,那么需要处理的细节就太复杂了。
其实访问Web应用中被保护的页面,使用浏览器则十分简单,用户通过系统提供的登录页面登录系统,浏览器会负责维护与服务器之间的Sesion,如果用户登录的用户名、密码符合要求,就可以访问被保护资源了。
在Android应用程序中,则可使用HttpClient来登录系统,只要应用程序使用同一个HttpClient发送请求,HttpClient会自动维护与服务器之间的Session状态,也就是说程序第一次使用HttpClient登录系统后,接下来使用HttpClient即可访问被保护页而了。
扩展知识:
了解HttpCore
1.HTTPClient
Org.apache.http.client工具包
项目1
/**
*向远程的url服务器进行post一个数据包
*
*@paramurl
*需要进行post的服务器
*@paramparas
*数据包中的参数
*@return
*@throwsException
*/
publicstaticStringpostData(Stringurl,Stringdata,
StringuploadEncoding,StringresponseEncoding)throwsException{
RequestConfigconfig=RequestConfig.custom().build();
HttpClientclient=HttpClients.custom()
.setDefaultRequestConfig(config).build();
HttpClientContextcontext=HttpClientContext.create();
HttpPostpost=newHttpPost(url);
if(StringUtils.isNotBlank(data)){
post.setEntity(newStringEntity(data,uploadEncoding));
}
CloseableHttpResponseresponse=(CloseableHttpResponse)client
.execute(post,context);
returnEntityUtils.toString(response.getEntity(),responseEncoding);
}
2.URLConnection
Java自带
publicstaticStringgetFromSpecialUrl(Stringstr,Stringparam)throwsException{
log.info("requestcorezy++++++++++++++++++++++++++++++++++++++++++");
URLurl=null;
URLConnectionconn=null;
BufferedReaderbufferedReader=null;
InputStreaminputStream=null;
StringBufferresponseXml=null;
PrintWriteroutput=null;
Stringresult;
try{
url=newURL(str);
log.info("url"+url);
conn=(URLConnection)url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setConnectTimeout(1000);
output=newPrintWriter(conn.getOutputStream());
output.print(param.toString());
output.close();
responseXml=newStringBuffer();
inputStream=conn.getInputStream();
bufferedReader=newBufferedReader(newInputStreamReader(
inputStream,"GBK"));
Strings;
while((s=bufferedReader.readLine())!
=null){
responseXml.append(s);
}
bufferedReader.close();
}catch(IOExceptione){
e.printStackTrace();
System.out.println("系统处理异常!
");
}
result=responseXml.toString();
System.out.println("接收到的报文:
"+result);
returnresult;
}
3.HTTPClient和URLConnection的区别
对比项目
URLConnection
HTTPClient
提交方式(Methods)
HEAD,GET,POST,PUT,DELETE,TRACE,OPTIONS
HEAD,GET,POST,PUT,DELETE,TRACE,OPTIONS,WEBDav,IPP,甚至各种自定义提交方式
响应(ResponseCodes)
只能获取http状态码小于400的状态码,响应头信息(headers),响应内容.对于响应状态码为4xx或者5xx获取response的任何信息都只会抛出IOException
任何时候都可以获取响应的任何信息:
响应状态码,响应头信息,响应内容信息等等。
代理和SOCKS
支持,SOCKS仅支持4
支持,SOCKS支持4和5
认证(Authorization)
支持Basic、早期的DigestJDK1.2+(不支持现在的Digestauthentication),甚至不能处理apache返回的Digest信息
支持Basic、DigestAuthentication、自定义的其他认证方案
Cookies
不支持
支持
请求输出流
(Truerequestoutputstreams)
请求发送之前,所有的数据都被缓存起来
通过socket直接输出HttpOutputStream
响应输入流
(Trueresponseinputstreams)
JDK1.2-支持,1.3+不支持chunkedencoding(不支持大多数推送服务器的响应)
支持
长连接
(PersistentConnections)
JDK1.2-HTTP/1.0Keep-Alive,JDK1.3+ HTTP/1.1Persistent
支持HTTP/1.0Keep-Alive和HTTP/1.1Persistent
PipeliningofRequests
不支持
支持
设置超时
不支持
支持
处理HTTP之外的协议
支持如:
ftp,gopher,mailto,文件系统
不支持
开源
否
是
处理HTTP之外的协议
支持如:
ftp,gopher,mailto,文件系统
不支持
二,XML工具包xStream
XmlUtils
xStream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换;
它们都完美支持JSON,但是对xml的支持还不是很好。
一定程度上限制了对Java对象的描述,不能让xml完全体现到对Java对象的描述。
这里将会介绍xStream对JSON、XML的完美支持。
xStream不仅对XML的转换非常友好,而且提供annotation注解,可以在JavaBean中完成对xml节点、属性的描述。
以及对JSON也支持,只需要提供相关的JSONDriver就可以完成转换。
1、下载jar包、及官方资源
xStream的jar下载地址:
https:
//nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream-distribution/1.3.1/xstream-distribution-1.3.1-bin.zip
添加xstream-1.3.1.jar文件到工程中,就可以开始下面的工作;需要的jar如下:
2、测试用例代码
publicclassXStreamTest{
privateXStreamxstream=null;
privateObjectOutputStreamout=null;
privateObjectInputStreamin=null;
privateStudentbean=null;
@Before
publicvoidinit(){
xstream=newXStream();
//xstream=newXStream(newDomDriver());//需要xpp3jar
bean=newStudent();
bean.setAddress("china");
bean.setEmail("jack@");
bean.setId
(1);
bean.setName("jack");
Birthdayday=newBirthday();
day.setBirthday("2010-11-22");
bean.setBirthday(day);
}
@After
publicvoiddestory(){
xstream=null;
bean=null;
if(out!
=null){
out.flush();
out.close();
}
if(in!
=null){
in.close();
}
System.gc();
}
通过XStream对象的toXML方法就可以完成Java对象到XML的转换,toXML方法还有2个相同签名的方法,需要传递一个流。
然后通过流来完成xml信息的输出。
3、需要的JavaBean
packagecom.hoo.entity;
publicclassStudent{
privateintid;
privateStringname;
privateStringemail;
privateStringaddress;
privateBirthdaybirthday;
//getter、setter
publicStringtoString(){
returnthis.name+"#"+this.id+"#"+this.address+"#"+this.birthday+"#"+this.email;
}
}
1、Java转换成XML
1.1JavaBean转换XM
@Test
publicvoidwriteBean2XML(){
System.out.println("------------Bean->XML------------");
System.out.println(xstream.toXML(bean));
System.out.println("重命名后的XML");
//类重命名
//xstream.alias("account",Student.class);
//xstream.alias("生日",Birthday.class);
//xstream.aliasField("生日",Student.class,"birthday");
//xstream.aliasField("生日",Birthday.class,"birthday");
//System.out.println(xstream.toXML(bean));
//属性重命名
xstream.aliasField("邮件",Student.class,"email");
//包重命名
xstream.aliasPackage("hoo","com.hoo.entity");
System.out.println(xstream.toXML(bean));
}
看结果中的第一份xml内容,是没有经过然后修改或重命名的文档,按照原样输出。
文档中的第二份文档的package经过重命名,email属性也经过重命名以及类名也可以进行重命名的。
运行后结果如下:
------------Bean->XML------------
1
jack
jack@
china
2010-11-22
重命名后的XML
1
jack
<邮件>jack@邮件>
china
2010-11-22
1.2将List集合转换成xml文档
@Test
publicvoidwriteList2XML(){
try{
//修改元素名称
xstream.alias("beans",ListBean.class);
xstream.alias("student",Student.class);
System.out.println("----------List-->XML----------");
ListBeanlistBean=newListBean();
listBean.setName("thisisaListCollection");
List
list.add(bean);
list.add(bean);//引用bean
//list.add(listBean);//引用listBean,父元素
bean=newStudent();
bean.setAddress("china");
bean.setEmail("tom@");
bean.setId
(2);
bean.setName("tom");
Birthdayday=newBirthday("2010-11-22");
bean.setBirthday(day);
list.add(bean);
listBean.setList(list);
//将ListBean中的集合设置空元素,即不显示集合元素标签
//xstream.addImplicitCollection(ListBean.class,"list");
//设置reference模型
//xstream.setMode(XStream.NO_REFERENCES);//不引用
xstream.setMode(XStream.ID_REFERENCES);//id引用
//xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);//绝对路径引用
//将name设置为父类(Student)的元素的属性
xstream.useAttributeFor(Student.class,"name");
xstream.useAttributeFor(Birthday.class,"birthday");
//修改属性的name
xstream.aliasAttribute("姓名","name");
xstream.aliasField("生日",Birthday.class,"birthday");
System.out.println(xstream.toXML(listBean));
}catch(Exceptione){
e.printStackTrace();
}
}
上面的代码运行后,结果如下:
----------List-->XML----------
thisisaListCollection
1
jack@
china
2
tom@
china
如果不加xstream.addImplicitCollection(ListBean.class,"list");
这个设置的话,会出现一个List节点包裹着Student节点元素。
添加addImplicitCollection可以忽略这个list节点元素。
那么上面的list节点就不存在,只会在beans元素中出现name、student这2个xml元素标签;
setMode是设置相同的对象的引用方式,如果设置XStream.NO_REFERENCES就是不引用,会输