java springboot 动态生成 sitemap.xml 网站地图
2019-10-17
阅读 {{counts.readCount}}
评论 {{counts.commentCount}}
## 背景
建站以来,试过好多方法实现 `sitemap.xml` ,从最早的手动更新,到后来每次更新自动写入本地io文件。一方面感觉太零零散散,另外实时的程度不高,再加上好多ZZ引擎,sitemap的要求还能和别人不一样。。。总之最终决定写个动态的,通过springboot的GET接口返回字符串实现,xml结构不复杂,就自己拼。最终通过nginx代理到网站的sitemap.xml上去。让ZZ引擎以为是静态的。
## 代码
#### 实体类
**SiteMap.java**
```java
import com.zzzmh.api.utils.DateUtils;
import com.zzzmh.api.utils.SiteMapUtils;
import java.util.Date;
public class SiteMap {
public SiteMap() {
}
public SiteMap(String loc) {
this.loc = loc;
this.lastmod = new Date();
this.changefreq = SiteMapUtils.CHANGEFREQ_ALWAYS;
this.priority = "1.0";
}
public SiteMap(String loc, Date lastmod, String changefreq, String priority) {
this.loc = loc;
this.lastmod = lastmod;
this.changefreq = changefreq;
this.priority = priority;
}
/**
* url https://www.xxx.com
*/
private String loc;
/**
* 最后更新时间 yyyy-MM-dd
*/
private Date lastmod;
/**
* 更新速度 always hourly daily weekly monthly yearly never
*/
private String changefreq;
/**
* 权重 1.0 0.9 0.8
*/
private String priority;
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Date getLastmod() {
return lastmod;
}
public void setLastmod(Date lastmod) {
this.lastmod = lastmod;
}
public String getChangefreq() {
return changefreq;
}
public void setChangefreq(String changefreq) {
this.changefreq = changefreq;
}
public String getPriority() {
return priority;
}
public void setPriority(String priority) {
this.priority = priority;
}
@Override
/** 重写 toString 适应xml格式 */
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("<url>");
sb.append("<loc>" + loc + "</loc>");
sb.append("<lastmod>" + DateUtils.sdf_yyyy_MM_dd.format(lastmod) + "</lastmod>");
sb.append("<changefreq>" + changefreq + "</changefreq>");
sb.append("<priority>" + priority + "</priority>");
sb.append("</url>");
return sb.toString();
}
}
```
#### 工具类
**SiteMapUtils.java**
```java
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zzzmh.api.entity.BlogCard;
import com.zzzmh.api.entity.ChromeCrx;
import com.zzzmh.api.entity.SiteMap;
import com.zzzmh.api.service.IBlogCardService;
import com.zzzmh.api.service.IChromeCrxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
/**
* @author zzzmh
* @since 2019-8-13
* <p>
* 动态生成 sitemap工具类
* 直连数据库,取出数据拼xml
*/
@Component
public class SiteMapUtils {
public final static String BEGIN_DOC = "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
public final static String END_DOC = "</urlset>";
public final static String CHANGEFREQ_ALWAYS = "always";
public final static String CHANGEFREQ_HOURLY = "hourly";
public final static String CHANGEFREQ_DAILY = "daily";
public final static String CHANGEFREQ_WEEKLY = "weekly";
public final static String CHANGEFREQ_MONTHLY = "monthly";
public final static String CHANGEFREQ_YEARLY = "yearly";
public final static String CHANGEFREQ_NEVER = "never";
@Autowired
private IBlogCardService blogCardService;
@Autowired
private IChromeCrxService chromeCrxService;
public String getBlogSiteMap() {
StringBuffer sb = new StringBuffer();
sb.append(BEGIN_DOC);
sb.append(new SiteMap("https://zzzmh.cn"));
QueryWrapper<BlogCard> wrapper = new QueryWrapper<>();
List<BlogCard> cards = blogCardService.list(wrapper.eq("isdel", 0).orderByDesc("id"));
for (BlogCard card : cards) {
sb.append(new SiteMap("https://zzzmh.cn/single?id=" + card.getId(), card.getDate(), CHANGEFREQ_MONTHLY, "0.9"));
}
sb.append(END_DOC);
return sb.toString();
}
public String getBzSiteMap() {
StringBuffer sb = new StringBuffer();
sb.append(BEGIN_DOC);
sb.append(new SiteMap("https://bz.zzzmh.cn"));
sb.append(END_DOC);
return sb.toString();
}
}
```
#### 接口调用
**Controller.java**
```java
@GetMapping(value = "/{path}/sitemap.xml",produces = {"application/xml"})
@ApiOperation("获取 sitemap.xml")
public String getSiteMap(@PathVariable("path") String path) {
switch (path) {
case "blog": {
return siteMapUtils.getBlogSiteMap();
}
case "bz": {
return siteMapUtils.getBzSiteMap();
}
default: {
return "";
}
}
}
```
## 效果
访问url `http://localhost:10000/api/blog/sitemap.xml`
得到以下内容
```xml
<?xml version="1.0" encoding="utf-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://zzzmh.cn</loc>
<lastmod>2019-08-13</lastmod>
<changefreq>always</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=77</loc>
<lastmod>2019-07-12</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=76</loc>
<lastmod>2019-07-12</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=75</loc>
<lastmod>2019-07-11</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=74</loc>
<lastmod>2019-07-10</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=73</loc>
<lastmod>2019-07-07</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=72</loc>
<lastmod>2019-07-07</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=71</loc>
<lastmod>2019-07-06</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=70</loc>
<lastmod>2019-07-06</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=69</loc>
<lastmod>2019-06-30</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=68</loc>
<lastmod>2019-06-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=67</loc>
<lastmod>2019-05-16</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=66</loc>
<lastmod>2019-05-09</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=65</loc>
<lastmod>2019-04-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=64</loc>
<lastmod>2019-04-11</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=63</loc>
<lastmod>2019-04-10</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=62</loc>
<lastmod>2019-03-18</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=61</loc>
<lastmod>2019-02-14</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=60</loc>
<lastmod>2019-01-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=59</loc>
<lastmod>2019-01-23</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=58</loc>
<lastmod>2019-01-22</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=57</loc>
<lastmod>2019-01-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=56</loc>
<lastmod>2019-01-09</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=55</loc>
<lastmod>2019-01-09</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=54</loc>
<lastmod>2019-01-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=53</loc>
<lastmod>2019-01-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=51</loc>
<lastmod>2018-12-17</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=50</loc>
<lastmod>2018-12-09</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=49</loc>
<lastmod>2018-11-30</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=48</loc>
<lastmod>2018-11-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=47</loc>
<lastmod>2018-11-22</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=46</loc>
<lastmod>2018-11-18</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=45</loc>
<lastmod>2018-11-13</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=44</loc>
<lastmod>2018-11-10</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=43</loc>
<lastmod>2018-10-24</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=42</loc>
<lastmod>2018-10-21</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=41</loc>
<lastmod>2018-10-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=40</loc>
<lastmod>2018-10-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=39</loc>
<lastmod>2018-10-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=38</loc>
<lastmod>2018-09-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=37</loc>
<lastmod>2018-09-19</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=36</loc>
<lastmod>2018-09-08</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=35</loc>
<lastmod>2018-09-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=34</loc>
<lastmod>2018-08-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=33</loc>
<lastmod>2018-08-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=32</loc>
<lastmod>2018-08-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=31</loc>
<lastmod>2018-08-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=30</loc>
<lastmod>2018-08-25</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=29</loc>
<lastmod>2018-08-20</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=28</loc>
<lastmod>2018-08-18</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=27</loc>
<lastmod>2018-08-18</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=26</loc>
<lastmod>2018-08-18</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=25</loc>
<lastmod>2018-08-15</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=24</loc>
<lastmod>2018-08-14</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=22</loc>
<lastmod>2018-08-05</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=21</loc>
<lastmod>2018-08-03</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=20</loc>
<lastmod>2018-08-03</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=19</loc>
<lastmod>2018-08-03</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=18</loc>
<lastmod>2018-08-03</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=17</loc>
<lastmod>2018-08-03</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=16</loc>
<lastmod>2018-08-03</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=15</loc>
<lastmod>2018-07-15</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=14</loc>
<lastmod>2018-07-14</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=13</loc>
<lastmod>2018-07-05</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=12</loc>
<lastmod>2018-06-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=11</loc>
<lastmod>2018-06-20</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=7</loc>
<lastmod>2018-05-15</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=6</loc>
<lastmod>2018-05-04</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=5</loc>
<lastmod>2018-04-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=3</loc>
<lastmod>2018-03-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=2</loc>
<lastmod>2018-03-21</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=1</loc>
<lastmod>2018-04-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://zzzmh.cn/single?id=0</loc>
<lastmod>2018-05-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
</urlset>
```
Nginx反向代理
```nginx
location /xml/sitemap.xml {
proxy_pass http://localhost:8080/xxx/sitemap.xml;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_connect_timeout 30;
proxy_read_timeout 30;
proxy_send_timeout 30;
access_log off;
break;
}
```
## END
这样就不再需要手动更新或者定时任务更新sitemap.xml了
并且项目直接可以细分、可以开发不同版本针对不同引擎