现在的位置: 首页 > 综合 > 正文

利用泛型类返回多个结果

2018年03月18日 ⁄ 综合 ⁄ 共 5401字 ⁄ 字号 评论关闭

由于项目需要,需要一个返回结果中包括多个值,比如包括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 three
		public static <L,R,C> Three<L,R,C> of(L left,R right,C c)
		{
			return new Three<L,R,C>(left, right, c);
		}
		
		//constructor
		private Three(L left,R right,C c)
		{
			super(left, right);
			this.c=c;
		}
		
		private C c;
		
		public C getC(){
			return c;
		}
		
	}
	
	@Override
	public 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;
	}

   泛型在为编写通用的,需求变化的类提供了方便。

抱歉!评论已关闭.