Rory's Blog
Happy study,Happy work,Happy life
posts - 22,  comments - 46,  trackbacks - 0
xstream是个好东西。对于配置文件的读取很方便。在mybog中我就用到了。不过今天打算用yupoo的api来做相册。发现xstream对于xmlnode的attribute解析支持不是那么的好。
对于这种节点格式的非常的简单
<result>
    
<page>1</page>
    
<pages>1</pages>
    
<perpage>100</perpage>
    
<total>19</total>
    
<photos>
        
<photo>
            
<id>ff8080810fc8ac78010fd3f158d40a52</id>
            
<owner>ff8080810f1a387b010f1a83d6530dfc</owner>
            
<title>Gmail-2</title>
            
<host>4</host>
            
<dir>20061230</dir>
            
<filename>231905_1463411198</filename>
        
</photo>
    
</photos>
</result>

简单的alias一下就可以读到值了
File file = new File("src/test/java/com/jdkcn/test/result.xml");
BufferedReader reader 
= new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
XStream stream 
= new XStream();
stream.alias(
"result", YupooResult.class);
stream.alias(
"photo",YupooPhoto.class);
YupooResult result 
= (YupooResult)stream.fromXML(reader);
可是Yupoo的api返回的xmlrpc的结果是这样的
<result page="1" pages="1" perpage="100" total="19">
    
<photos>
        
<photo id="ff8080810fc8ac78010fd3f158d40a52"
            owner
="ff8080810f1a387b010f1a83d6530dfc" title="Gmail-2" host="4"
            dir
="20061230" filename="231905_1463411198" />
    
</photos>
</result>
这样就load不到值了。没法去mailist里面找答案,果然有人问。
Hello,

I am not sure about the subject but here is what I needed help for:

XML:

<field name="value">I am a Field.</field>

I have already tried several structures and nothing seem to work.

Is this possible for XStream? :)

How is the Java class form to support this?

Thanks!




有人回答是看Converter的文档。果然找到答案了。
自己写一个converter就可以了。
下面是我的converter
package com.jdkcn.xstream;

import java.util.ArrayList;
import java.util.List;

import com.jdkcn.yupoo.YupooPhoto;
import com.jdkcn.yupoo.YupooResult;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

/**
 * 
@author <a href="mailto:rory.cn@gmail.com">somebody</a>
 * 
@since Jan 16, 2007 6:12:35 PM
 * 
@version $Id YupooResultConverter.java$
 
*/
public class YupooResultConverter implements Converter {
    
/* (non-Javadoc)
     * @see com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object, com.thoughtworks.xstream.io.HierarchicalStreamWriter, com.thoughtworks.xstream.converters.MarshallingContext)
     
*/
    
public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) {
        
// FIXME unfinish.
    }

    
/* (non-Javadoc)
     * @see com.thoughtworks.xstream.converters.Converter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader, com.thoughtworks.xstream.converters.UnmarshallingContext)
     
*/
    
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        YupooResult result 
= new YupooResult();
        result.setPage(
new Integer(reader.getAttribute("page")));
        result.setPages(
new Integer(reader.getAttribute("pages")));
        result.setPerpage(
new Integer(reader.getAttribute("perpage")));
        result.setTotal(
new Integer(reader.getAttribute("total")));
        reader.moveDown();
        List
<YupooPhoto> photos = new ArrayList<YupooPhoto>();
        
while(reader.hasMoreChildren()) {
            reader.moveDown();
            YupooPhoto photo 
= new YupooPhoto();
            photo.setDir(reader.getAttribute(
"dir"));
            photo.setFilename(reader.getAttribute(
"filename"));
            photo.setHost(reader.getAttribute(
"host"));
            photo.setId(reader.getAttribute(
"id"));
            photo.setOwner(reader.getAttribute(
"owner"));
            photo.setTitle(reader.getAttribute(
"title"));
            photos.add(photo);
            reader.moveUp();
        }
        result.setPhotos(photos);
        
return result;
    }
    
/* (non-Javadoc)
     * @see com.thoughtworks.xstream.converters.ConverterMatcher#canConvert(java.lang.Class)
     
*/
    
public boolean canConvert(Class clazz) {
        
return clazz.equals(YupooResult.class);
    }
}

然后调用的地方修改一下就ok了。
XStream stream = new XStream();
stream.registerConverter(
new YupooResultConverter());
stream.alias(
"result", YupooResult.class);



参考:
http://xstream.codehaus.org/converter-tutorial.html

2007年1月18日更新。
这里感谢网友 Ivan Chen(西滨) 的提示。原来新版的xstream可以简单的解决了。在1.2.1的doc里面找到了这个两个方法。

useAttributeFor

public void useAttributeFor(java.lang.String fieldName,
                            java.lang.Class type)
Use an XML attribute for a field or a specific type.

Parameters:
fieldName - the name of the field
type - the Class of the type to be rendered as XML attribute
Throws:
XStream.InitializationException - if no AttributeMapper is available
Since:
1.2

useAttributeFor

public void useAttributeFor(java.lang.Class type)
Use an XML attribute for an arbotrary type.

Parameters:
type - the Class of the type to be rendered as XML attribute
Throws:
XStream.InitializationException - if no AttributeMapper is available
Since:
1.2

这两个方法都是从1.2开始支持的。
也不用自己写converter了。这样就可以了
        stream.alias("result", YupooResult.class);
        stream.useAttributeFor(
"page", Integer.class);
        stream.useAttributeFor(
"pages", Integer.class);
        stream.useAttributeFor(
"perpage", Integer.class);
        stream.useAttributeFor(
"total", Integer.class);
        stream.alias(
"photo", YupooPhoto.class);
        stream.useAttributeFor(
"id", String.class);
        stream.useAttributeFor(
"owner", String.class);
        stream.useAttributeFor(
"title", String.class);
        stream.useAttributeFor(
"host", String.class);
        stream.useAttributeFor(
"dir", String.class);
        stream.useAttributeFor(
"filename", String.class);

创造共用协议:署名,非商业,保持一致
   除经特别注明外,本文章版权归莫多泡泡所有.
署名,非商业用途,保持一致.   somebody(莫多)
posted @ 2007-01-17 18:24 莫多 阅读(7982) | 评论 (2)编辑 收藏

  上周更新了一下myblog,添加了一个Filter,做统计访问用。可是后来发现出现乱码问题了。找了很久都没有找到问题。debug的时候看到 CharacterEncodingFilter确实是执行了。不过就是没有效果。执行之前是ISO-8859-1编码的,执行之后还是, CharacterEncodingFilter就没有起到作用。后来终于找到问题的原因了。原来是Filter配置先后顺序的原因。
       刚开始的配置是这样的:

     < filter-mapping >
        
< filter-name > requestCounterFilter </ filter-name >
        
< url-pattern > *.jhtml </ url-pattern >
    
</ filter-mapping >
  
    
< filter-mapping >
        
< filter-name > encodingFilter </ filter-name >
        
< url-pattern > /dwr/* </ url-pattern >
    
</ filter-mapping >
    
    
< filter-mapping >
        
< filter-name > encodingFilter </ filter-name >
        
< url-pattern > *.jhtml </ url-pattern >
    
</ filter-mapping >
    
    
< filter-mapping >
        
< filter-name > encodingFilter </ filter-name >
        
< url-pattern > *.jsp </ url-pattern >
    
</ filter-mapping >

  先经过那个统计的filter然后再经过编码的filter。这样的话编码的filter就不起作用了。只要吧编码的filter放到最前面就没有问题了。改成这样就好。

     < filter-mapping >
        
< filter-name > encodingFilter </ filter-name >
        
< url-pattern > /dwr/* </ url-pattern >
    
</ filter-mapping >
    
    
< filter-mapping >
        
< filter-name > encodingFilter </ filter-name >
        
< url-pattern > *.jhtml </ url-pattern >
    
</ filter-mapping >
    
    
< filter-mapping >
        
< filter-name > encodingFilter </ filter-name >
        
< url-pattern > *.jsp </ url-pattern >
    
</ filter-mapping >
    
    
< filter-mapping >
        
< filter-name > requestCounterFilter </ filter-name >
        
< url-pattern > *.jhtml </ url-pattern >
    
</ filter-mapping >


以后大家一定要注意啊。顺序问题也是很重要的。
创造共用协议:署名,非商业,保持一致   除经特别注明外,本文章版权归莫多泡泡所有.
署名,非商业用途,保持一致.   somebody(莫多)

posted @ 2006-12-27 10:37 莫多 阅读(2677) | 评论 (3)编辑 收藏

<2006年12月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿(1)

随笔分类(27)

随笔档案(22)

Friends

搜索

  •  

积分与排名

  • 积分 - 61848
  • 排名 - 845

最新评论

阅读排行榜

评论排行榜