Java 动态生成网站sitemap地图,sitemapindex索引文件,引入多个sitemap地址

发布时间:2018-04-01作者:laosun阅读(3278)

Java

Java 动态生成网站sitemap地图,可无限扩展;sitemap.xml 是有限制的,单个sitemap文件不能包括超过50000个URL,不能超过10兆(M)。所以我们需要设置sitemap索引主文件。

    Java 动态生成网站sitemap地图,可无限扩展,博主在写这篇文章的时候,网站sitemap放部署了两天。之前也是找寻一些开源api,但是发现很多写的都比较死,如果一个站点万级的文章,那么这个sitemap如何生成,很可怕,sitemap.xml 是有限制的,所以我们需要分批分块生成,设置主sitemap sitemapindex索引文件,引用多个子sitemap子文件,主要内容放入子sigtemap内。

    单个sitemap文件不能包括超过50000个URL,不能超过10兆(M)

    单个管理员帐户向google提交的sitemaps不能超过500个;

    一个sitemap中可以索引多个sitemaps;

    Sitemap 索引文件最多可列出 1,000 个 Sitemap;

    本博客站点设置sitemap的方法是,根据导航栏目设置,每个导航栏目对应一个sitemap.xml。 其实这个扩展性也不好,但是对于博主来说已经足够了,能乘载几十万的文章了。真正的大型网站估计都不需要sitemap.xml 

    直接看代码吧!sitemap的结构什么的,我就不介绍了,本sitemap读写速度非常快,毫秒级!

    好了,下载工具包:

    <!-- https://mvnrepository.com/artifact/com.google.code/sitemapgen4j -->
    <dependency>
        <groupId>com.google.code</groupId>
        <artifactId>sitemapgen4j</artifactId>
        <version>1.0.1</version>
    </dependency>

    生成源码:

    博主为了大家都能看明白,又重新做了一个简版,保证大家都能看明白!

    执行之前大家请先修改 String realPath = "/Users/sun/Documents"; 这是生成目录。

    生产环境下,需要最好获取当前项目的根目录。

    import java.io.File;
    import java.io.PrintWriter;
    import java.io.Writer;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Date;
    import java.util.List;
    
    import org.apache.commons.lang.StringUtils;
    
    import com.google.common.collect.Lists;
    import com.redfin.sitemapgenerator.ChangeFreq;
    import com.redfin.sitemapgenerator.WebSitemapGenerator;
    import com.redfin.sitemapgenerator.WebSitemapUrl;
    import com.sunjs.utils.SiteMapUtils;
    import com.sunjs.utils.Sitemap;
    
    public class Sunjs {
    	
    	public static String DATE_FORMAT = "yyyy-MM-dd";
    	
    	public static void main(String[] args) {
    		Sunjs sunjs = new Sunjs();
    		sunjs.createSiteMap();
    	}
    	
    	/**
    	 * 动态生成sitemap
    	 * 目录,web根目录,就是你的站点首页 index.html所在同级目录
    	 * @author sun
    	 * @date 2018年3月31日 下午8:02:47
    	 */
    	public void createSiteMap(){
    		try {
    			long start = System.currentTimeMillis();
    			String WEBSITE = "https://www.sunjs.com";
    			/** 存储位置,实际应用项目中,需要指到网站的根目录 request.getSession().getServletContext().getRealPath("/") **/
    			String realPath = "/Users/sun/Documents";
    			
    			List<Category> cList = findCategoryBy();
    			if(cList==null || cList.size()<1){
    				return ;
    			}
    			List<String> siteMapList = Lists.newArrayList();//存放子sitemap路径的list集合
    			for(Category category:cList){
    				/** 查询每个分类下对应的文章 **/
    				List<Article> aList = findArticleBy(category.getId());
    				if(aList!=null && aList.size()>0){
    					//start ======================================================================
    					String path = realPath+"/sitemap/"+category.getId();
    					fileExists(path);//判断文件夹是否存在,不存在则创建
    					WebSitemapGenerator sitemapGenerator = WebSitemapGenerator.builder(WEBSITE, new File(path)).gzip(false).build();
    					for(Article article:aList){//遍历取出来的文章
    						String url = "https://www.sunjs.com";//文章详情页的url地址
    						WebSitemapUrl sitemapUrl = new WebSitemapUrl.Options(url).lastMod(formatDate(article.getAddTime(), DATE_FORMAT)).priority(0.9).changeFreq(ChangeFreq.HOURLY).build();
    						sitemapGenerator.addUrl(sitemapUrl);
    					}
    					sitemapGenerator.write();
    					// end ======================================================================
    					siteMapList.add(WEBSITE+"/sitemap/"+category.getId()+"/sitemap.xml");//主索引文件需要这个路径
    				}
    			}
    			
    			//TODO
    			//其实分类 - list 页 url也应该存一个sitemap,看自己吧,如果也想告诉搜索引擎,我的list列表页也很重要,那么就做
    			
    			/** 生成主索引文件 **/
    			if(siteMapList!=null && siteMapList.size()>0){
    				Collection<Sitemap> s = new ArrayList();
    				for(String url:siteMapList){
    					s.add(new Sitemap(url));
    				}
    				Writer wt = new PrintWriter(new File(realPath+"/sitemap.xml"));
    				SiteMapUtils.writeSitemapIndex(wt, s.iterator());
    				wt.close();
    			}
    			long end = System.currentTimeMillis();
    			System.out.println("生成Sitemap完毕, 共耗时:"+(end-start));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 模拟数据库查询 - 查询符合条件的文章分类
    	 * @author sun
    	 * @date 2018年3月31日 下午8:12:41
    	 * @param categoryId
    	 * @return
    	 */
    	public List<Category> findCategoryBy(){
    		List<Category> cList = Lists.newArrayList();
    		cList.add(new Category(1, new Date()));
    		cList.add(new Category(2, new Date()));
    		return cList;
    	}
    	
    	/**
    	 * 模拟数据库查询 - 查询符合条件的文章
    	 * @author sun
    	 * @date 2018年3月31日 下午7:47:50
    	 * @return
    	 */
    	public List<Article> findArticleBy(Integer categoryId){
    		System.out.println("查询文章分类id为 "+categoryId+" 的所有符合条件的文章");
    		List<Article> aList = Lists.newArrayList();
    		aList.add(new Article(10, new Date()));
    		aList.add(new Article(11, new Date()));
    		aList.add(new Article(12, new Date()));
    		return aList;
    	}
    	
    	/**
    	 * 格式化日期
    	 * @author sun
    	 * @date 2018年3月31日 下午8:05:30
    	 * @param date
    	 * @param pattern
    	 * @return
    	 */
    	public static String formatDate(Date date, String pattern) {
    		if (StringUtils.isEmpty(pattern)) {
    			pattern = DATE_FORMAT;
    		}
    		DateFormat df = new SimpleDateFormat(pattern);
    		return df.format(date);
    	}
    	
    	/**
    	 * 判断文件目录是否存在 如果不存在,则创建新的文件夹
    	 * @author sun
    	 * @date 2018年3月31日 下午7:58:24
    	 * @param path
    	 */
    	public static void fileExists(String path) {
    		try {
    			File file = new File(path);
    			if (!file.exists()) {
    				file.mkdirs();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 分类
    	 * @author sun
    	 * @date 2018年3月31日 下午8:12:21
    	 */
    	public class Category{
    		private int id;
    		private Date addTime;
    		
    		public Category(int i, Date addTime) {
    			super();
    			this.id = i;
    			this.addTime = addTime;
    		}
    		public int getId() {
    			return id;
    		}
    		public void setId(int id) {
    			this.id = id;
    		}
    		public Date getAddTime() {
    			return addTime;
    		}
    		public void setAddTime(Date addTime) {
    			this.addTime = addTime;
    		}
    	}
    	
    	/**
    	 * 文章
    	 * @author sun
    	 * @date 2018年3月31日 下午7:31:42
    	 */
    	public class Article{
    		private int id;
    		private Date addTime;
    		
    		public Article(int i, Date addTime) {
    			super();
    			this.id = i;
    			this.addTime = addTime;
    		}
    		public int getId() {
    			return id;
    		}
    		public void setId(int id) {
    			this.id = id;
    		}
    		public Date getAddTime() {
    			return addTime;
    		}
    		public void setAddTime(Date addTime) {
    			this.addTime = addTime;
    		}
    	}
    
    }

    SiteMapUtils.java

    package com.sunjs.utils;
    
    import java.io.IOException;
    import java.io.Writer;
    import java.util.Iterator;
    
    import javax.xml.bind.DataBindingException;
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.PropertyException;
    
    public class SiteMapUtils {
    
    	protected final static String URLSET_START = "<?xml version='1.0' encoding='UTF-8'?>\n"
    			+ "<urlset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
    			+ "         xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\"\n"
    			+ "         xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
    	protected final static String URLSET_END = "\n</urlset>";
    
    	protected final static String SITEMAPINDEX_START = "<?xml version='1.0' encoding='UTF-8'?>\n"
    //			+ "<?xml-stylesheet type=\"text/xsl\" href=\"http://lusongsong.com/zb_users/plugin/Nobird_Seo_Tools/Sitemap/sitemap.xsl\"?>"
    			+ "<sitemapindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
    			+ "         xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd\"\n"
    			+ "         xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
    	protected final static String SITEMAPINDEX_END = "\n</sitemapindex>";
    
    	public static void writeSitemapIndex(Writer writer, Iterator<? extends Sitemap> mappings) throws IOException {
    		writeXml(writer, SITEMAPINDEX_START, mappings, SITEMAPINDEX_END);
    	}
    
    	public static long writeUrlset(Writer writer, Iterator<Url> urls) throws IOException {
    		return writeXml(writer, URLSET_START, urls, URLSET_END);
    	}
    
    	private static long writeXml(Writer writer, String start, Iterator<?> it, String end) throws IOException {
    		writer.write(start);
    		long count = writeSubtree(writer, it);
    		writer.write(end);
    		return count;
    	}
    
    	public static long writeSubtree(Writer writer, Iterator<?> it) throws IOException {
    		long size = 0;
    		Marshaller m;
    		try {
    			JAXBContext jc = JAXBContext.newInstance(Sitemap.class, Url.class);
    			m = jc.createMarshaller();
    			m.setProperty(Marshaller.JAXB_FRAGMENT, true);
    			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    		} catch (PropertyException e) {
    			throw new DataBindingException(e);
    		} catch (JAXBException e) {
    			throw new DataBindingException(e);
    		}
    
    		boolean first = true;
    		while (it.hasNext()) {
    			if (first)
    				first = false;
    			else
    				writer.write("\n");
    			try {
    				m.marshal(it.next(), writer);
    			} catch (JAXBException e) {
    				throw new IOException(e);
    			}
    			size++;
    		}
    		return size;
    	}
    	
    }

    Sitemap.java

    package com.sunjs.utils;
    
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement(name = "sitemap")
    public class Sitemap {
    
    	private String ioc;
    
    	public Sitemap() {
    	}
    
    	public Sitemap(String ioc) {
    		super();
    		this.ioc = ioc;
    	}
    
    	@XmlElement(name = "ioc")
    	public String getIoc() {
    		return ioc;
    	}
    
    	public void setIoc(String ioc) {
    		this.ioc = ioc;
    	}
    
    }


    Url.java

    package com.sunjs.utils;
    
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement(name = "url")
    public class Url {
    
    	private String ioc;
    
    	public Url() {
    	}
    
    	public Url(String ioc) {
    		super();
    		this.ioc = ioc;
    	}
    
    	@XmlElement(name = "ioc")
    	public String getIoc() {
    		return ioc;
    	}
    
    	public void setIoc(String ioc) {
    		this.ioc = ioc;
    	}
    
    }


    博主发表文章之前没有检查文章源码是否完整,给大家造成的不便深感抱歉!

    上边博主发出的源码已经经过博主自己的校验。按照步骤来是没有问题的。



8 +1

版权声明

 Java  源码

 请文明留言

10 条评论