利用泛型类返回多个结果

来源:互联网 发布:redis json排序 编辑:程序博客网 时间:2024/04/30 11:26

由于项目需要,需要一个返回结果中包括多个值,比如包括Map,List等。由于客户端使用的类型没有确定,而且是变化的,所以考虑用泛型来实现。

下面的类Pair可以看做包括2种类型数据的容器,而其内部类Three是包括3种数据类型的容器。之所以将Three作为Pair的内部类,是因为Three的方法要用到Pair的内部方法或属性,而这些内部方法和属性对外部是不可见的,而其内部类可以访问。

package cn.ac.registAService.commons.util;/**  * @author  secret * @version 1.0 * @date    2012-12-3 下午4:07:54  * @fuction Just a container of 2 elements. Good for returning 2 values. */public class Pair<L,R>{/** * A factory to create a new pair * @param <L> The left component type * @param <R> The right component type * @param left The left component value * @param right The right component value * @return A new Pair object */public static <L, R>  Pair<L, R> of(L left,R right){return new Pair<L, R>(left, right);}/** * A factory to create a new pair * @param <L> The left component type * @param <R> The right component type * @param p A pair of objects * @return A new Pair object */public static <L, R> Pair<L, R> of(Pair<? extends L,? extends R> p){return new Pair<L, R>(p);}    private L left;    private R right;        /**     * Constructor to create the Pair object     * @param left The left component value     * @param right The right component value     */    private Pair(L left,R right)    {    this.left=left;    this.right=right;    }        /**     * Constructor to create the Pair object     * @param p A pair of objects     */    private Pair(Pair<? extends L,? extends R> p)    {    left=p.getLeft();    right=p.getRight();    }public L getLeft() {return left;}public R getRight() {return right;}//Just a container of 3 elements. Good for returning 3 values.public static class Three<L,R,C> extends Pair<L, R>{//A factory to create a new threepublic static <L,R,C> Three<L,R,C> of(L left,R right,C c){return new Three<L,R,C>(left, right, c);}//constructorprivate Three(L left,R right,C c){super(left, right);this.c=c;}private C c;public C getC(){return c;}}@Overridepublic String toString() {return "Pair [left=" + left + ", right=" + right + "]";}        }
对上述类的使用

1 方法getRecordsResponse返回一个包括2个Element(指dom4j中xml节点元素)的数据类型

/** * GetTecords操作,查询符合条件的资源 * @param strQuery 查询条件 * @param maxRecords  return Pair.of(, right); * @return Pair<Element, Element> * 第一个Element记录返回结果中节点geonet:Summary 的信息,第二个Element记录返回结果中节点csw:SearchResults信息 * @throws BusinessException */private Pair<Element, Element> getRecordsResponse(String strQuery,long maxRecords) throws BusinessException{//查询资源模版Document queryDocument = null;//1获取查询资源模版logger.info("4.1查询多个资源:获取查询资源模版");try {queryDocument=XmlReader.getDocument(CswTool.getRecordsFilePath);} catch (DocumentException e) {throw new BusinessException("读取查询多个资源模版出错,文件路径"+CswTool.getRecordsFilePath);}            //设置返回结果数目(如果为0,返回全部结果)if(maxRecords>0){queryDocument.getRootElement().addAttribute("maxRecords", Long.toString(maxRecords));}    //2设置查询条件logger.info("4.2查询多个资源:设置查询条件");Element queryElement=(Element)queryDocument.selectSingleNode("/csw:GetRecords/csw:Query/csw:Constraint/ogc:Filter");if(strQuery!=null && strQuery!="")queryElement.setText(strQuery);//3查询资源String requestXml = queryDocument.asXML();logger.info("4.3查询多个资源requestXml:"+"\n"+requestXml);String responseXml = CswTool.loginAndRun(requestXml);logger.info("4.3查询资源responseXml:"+"\n"+responseXml);//4 解析查询结果Document responseDoc;try {responseDoc = XmlReader.StringToXml(responseXml);Element summaryElement=(Element) responseDoc.selectSingleNode("/csw:GetRecordsResponse/geonet:Summary");Element searchResultsElement=(Element) responseDoc.selectSingleNode("/csw:GetRecordsResponse/csw:SearchResults");return Pair.of(summaryElement, searchResultsElement);} catch (DocumentException e) {throw new BusinessException("解析查询结果xml出错:"+e.getMessage());}}
2 getRecordsAllInfor 方法使用了上述1中的方法,然后返回包括3种类型的数据String,Map,List

/** * 得到GetRecords查询的所有信息,包括summary信息 * @param strQuery 查询条件 * @param maxRecords 最多返回符合查询结果的数目,如果为0,则返回全部查询结果 * @return Three<String, Map<String, String>, List<MetadataIso>> * String 符合查询条件的资源数目 * Map<String, String>存放summary中的信息(目前只存资源组织信息<资源组织名称,资源组织数目>,后期可扩展存储服务等信息) * List<MetadataIso>>存放返回的资源信息 * @throws BusinessException */public Three<String, Map<String, String>, List<MetadataIso>> getRecordsAllInfor(String strQuery,long maxRecords) throws BusinessException{String matchedRecords=null;  //符合查询条件的资源数目//TODO 存放summary中的信息(目前只存资源组织信息<资源组织名称,资源组织数目>,后期可扩展存储服务等信息)Map<String, String> hashMap=new HashMap<String,String>();  List<MetadataIso> arrayList=new ArrayList<MetadataIso>(); //存放返回的资源信息Pair<Element, Element> pair=getRecordsResponse(strQuery, maxRecords);Element summaryElement=pair.getLeft();Element searchResultsElement=pair.getRight();logger.info("GetRecords的summary节点"+"\n"+summaryElement.asXML());logger.info("GetRecords的searchResultsElement节点"+"\n"+summaryElement.asXML());try {if(summaryElement!=null){List<Element> listOrg=summaryElement.selectNodes("//organizationNames/organizationName");if(listOrg!=null){for(Element el:listOrg){String orgName=el.attributeValue("name");   //资源组织名称String orgCount=el.attributeValue("count"); //资源组织数目hashMap.put(orgName, orgCount);} //end for(Element el:listOrg)} //end if(listOrg!=null)} //end if(summaryElement!=null)if(searchResultsElement!=null){matchedRecords=searchResultsElement.attributeValue("numberOfRecordsMatched");List<Element> listMetadata=searchResultsElement.selectNodes("//gmd:MD_Metadata");if(listMetadata!=null){for(Element el:listMetadata){arrayList.add(CswTool.getMetadata(el));}} //end if(listMetadata!=null)}  //end if(searchResultsElement!=null)return Pair.Three.of(matchedRecords, hashMap, arrayList);} catch (BusinessException e) {throw new BusinessException("GetRecords处理返回结果出错:"+e.getMessage());}}
3  getRecords从Three类中得到数据对象MetadataIso的数据
public List<MetadataIso> getRecords(String strQuery, long maxRecords) throws BusinessException {Three<String, Map<String, String>, List<MetadataIso>> threeTuple=getRecordsAllInfor(strQuery, maxRecords);List<MetadataIso> listMetadata=threeTuple.getC();return listMetadata;}
   泛型在为编写通用的,需求变化的类提供了方便。
原创粉丝点击