From 2969ca9fb0696b0337174ecca4bb030f0f10fe70 Mon Sep 17 00:00:00 2001 From: Lay Date: Sat, 3 Apr 2021 13:48:38 +0800 Subject: [PATCH 1/2] 1.Add the lastBuildDate in RSS. 2.Add the updated in Atom. 3.Change the date format in RSS and Atom 4.Add the lastModified in the response header. --- .../content/ContentFeedController.java | 70 +++++++++++++++---- .../resources/templates/common/web/atom.ftl | 2 +- .../resources/templates/common/web/rss.ftl | 4 +- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/main/java/run/halo/app/controller/content/ContentFeedController.java b/src/main/java/run/halo/app/controller/content/ContentFeedController.java index d672017156..b6954f7620 100644 --- a/src/main/java/run/halo/app/controller/content/ContentFeedController.java +++ b/src/main/java/run/halo/app/controller/content/ContentFeedController.java @@ -1,11 +1,7 @@ package run.halo.app.controller.content; -import static org.springframework.data.domain.Sort.Direction.DESC; - import freemarker.template.Template; import freemarker.template.TemplateException; -import java.io.IOException; -import java.util.List; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RegExUtils; import org.springframework.data.domain.Page; @@ -32,6 +28,15 @@ import run.halo.app.service.OptionService; import run.halo.app.service.PostCategoryService; import run.halo.app.service.PostService; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Locale; +import java.util.OptionalLong; + +import static org.springframework.data.domain.Sort.Direction.DESC; /** * @author ryanwang @@ -47,6 +52,8 @@ public class ContentFeedController { private static final String XML_MEDIA_TYPE = MediaType.APPLICATION_XML_VALUE + UTF_8_SUFFIX; + private static final String LAST_MODIFIED_HEADER = "Last-Modified"; + private final PostService postService; private final CategoryService categoryService; @@ -79,8 +86,13 @@ public ContentFeedController(PostService postService, */ @GetMapping(value = {"feed", "feed.xml", "rss", "rss.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody - public String feed(Model model) throws IOException, TemplateException { - model.addAttribute("posts", buildPosts(buildPostPageable(optionService.getRssPageSize()))); + public String feed(Model model, HttpServletResponse response) + throws IOException, TemplateException { + List posts = buildPosts(buildPostPageable(optionService.getRssPageSize())); + model.addAttribute("posts", posts); + Timestamp lastModified = this.getLastModifiedTime(posts); + this.lastModified2ResponseHeader(response, lastModified); + model.addAttribute("lastModified", lastModified); Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -97,13 +109,18 @@ public String feed(Model model) throws IOException, TemplateException { @GetMapping(value = {"feed/categories/{slug}", "feed/categories/{slug}.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody - public String feed(Model model, @PathVariable(name = "slug") String slug) + public String feed(Model model, @PathVariable(name = "slug") String slug, + HttpServletResponse response) throws IOException, TemplateException { Category category = categoryService.getBySlugOfNonNull(slug); CategoryDTO categoryDTO = categoryService.convertTo(category); + List posts = + buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO); model.addAttribute("category", categoryDTO); - model.addAttribute("posts", - buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO)); + model.addAttribute("posts", posts); + Timestamp lastModified = this.getLastModifiedTime(posts); + this.lastModified2ResponseHeader(response, lastModified); + model.addAttribute("lastModified", lastModified); Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -118,8 +135,13 @@ public String feed(Model model, @PathVariable(name = "slug") String slug) */ @GetMapping(value = {"atom", "atom.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody - public String atom(Model model) throws IOException, TemplateException { - model.addAttribute("posts", buildPosts(buildPostPageable(optionService.getRssPageSize()))); + public String atom(Model model, HttpServletResponse response) + throws IOException, TemplateException { + List posts = buildPosts(buildPostPageable(optionService.getRssPageSize())); + model.addAttribute("posts", posts); + Timestamp lastModified = this.getLastModifiedTime(posts); + this.lastModified2ResponseHeader(response, lastModified); + model.addAttribute("lastModified", lastModified); Template template = freeMarker.getConfiguration().getTemplate("common/web/atom.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -136,13 +158,18 @@ public String atom(Model model) throws IOException, TemplateException { @GetMapping(value = {"atom/categories/{slug}", "atom/categories/{slug}.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody - public String atom(Model model, @PathVariable(name = "slug") String slug) + public String atom(Model model, @PathVariable(name = "slug") String slug, + HttpServletResponse response) throws IOException, TemplateException { Category category = categoryService.getBySlugOfNonNull(slug); CategoryDTO categoryDTO = categoryService.convertTo(category); + List posts = + buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO); model.addAttribute("category", categoryDTO); - model.addAttribute("posts", - buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO)); + model.addAttribute("posts", posts); + Timestamp lastModified = this.getLastModifiedTime(posts); + this.lastModified2ResponseHeader(response, lastModified); + model.addAttribute("lastModified", lastModified); Template template = freeMarker.getConfiguration().getTemplate("common/web/atom.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -248,4 +275,19 @@ private List buildCategoryPosts(@NonNull Pageable pageable, }); return posts.getContent(); } + + private Timestamp getLastModifiedTime(List posts) { + OptionalLong lastModifiedTimestamp = + posts.stream().mapToLong(post -> post.getEditTime().getTime()).max(); + if (!lastModifiedTimestamp.isPresent()) { + return new Timestamp(System.currentTimeMillis()); + } + return new Timestamp(lastModifiedTimestamp.getAsLong()); + } + + private void lastModified2ResponseHeader(HttpServletResponse response, Timestamp time) { + SimpleDateFormat dateFormat = + new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); + response.setHeader(LAST_MODIFIED_HEADER, dateFormat.format(time)); + } } diff --git a/src/main/resources/templates/common/web/atom.ftl b/src/main/resources/templates/common/web/atom.ftl index fdf5990935..6f12b992e3 100644 --- a/src/main/resources/templates/common/web/atom.ftl +++ b/src/main/resources/templates/common/web/atom.ftl @@ -14,7 +14,7 @@ ${user.description!} - ${.now?iso_local} + ${lastModified?iso_local} <#if category??> ${category.fullPath!} <#else> diff --git a/src/main/resources/templates/common/web/rss.ftl b/src/main/resources/templates/common/web/rss.ftl index 2139f15d5a..6619206aa5 100644 --- a/src/main/resources/templates/common/web/rss.ftl +++ b/src/main/resources/templates/common/web/rss.ftl @@ -1,4 +1,5 @@ +<#setting locale="en_US"> <#if category??> @@ -21,6 +22,7 @@ Halo ${version!} + ${lastModified?string('EEE, dd MMM yyyy HH:mm:ss z')} <#if posts?? && posts?size gt 0> <#list posts as post> @@ -35,7 +37,7 @@ - ${post.createTime?iso_local} + ${post.createTime?string('EEE, dd MMM yyyy HH:mm:ss z')} From 50dc2ba6a904f4fa641708e09af89453ce68fd91 Mon Sep 17 00:00:00 2001 From: Lay Date: Thu, 8 Apr 2021 09:22:29 +0800 Subject: [PATCH 2/2] fix code style --- .../content/ContentFeedController.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/run/halo/app/controller/content/ContentFeedController.java b/src/main/java/run/halo/app/controller/content/ContentFeedController.java index b6954f7620..822f992de8 100644 --- a/src/main/java/run/halo/app/controller/content/ContentFeedController.java +++ b/src/main/java/run/halo/app/controller/content/ContentFeedController.java @@ -1,7 +1,16 @@ package run.halo.app.controller.content; +import static org.springframework.data.domain.Sort.Direction.DESC; + import freemarker.template.Template; import freemarker.template.TemplateException; +import java.io.IOException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Locale; +import java.util.OptionalLong; +import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RegExUtils; import org.springframework.data.domain.Page; @@ -28,15 +37,6 @@ import run.halo.app.service.OptionService; import run.halo.app.service.PostCategoryService; import run.halo.app.service.PostService; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.List; -import java.util.Locale; -import java.util.OptionalLong; - -import static org.springframework.data.domain.Sort.Direction.DESC; /** * @author ryanwang @@ -77,7 +77,7 @@ public ContentFeedController(PostService postService, } /** - * Get post rss + * Get post rss. * * @param model model * @return rss xml content @@ -279,7 +279,7 @@ private List buildCategoryPosts(@NonNull Pageable pageable, private Timestamp getLastModifiedTime(List posts) { OptionalLong lastModifiedTimestamp = posts.stream().mapToLong(post -> post.getEditTime().getTime()).max(); - if (!lastModifiedTimestamp.isPresent()) { + if (lastModifiedTimestamp.isEmpty()) { return new Timestamp(System.currentTimeMillis()); } return new Timestamp(lastModifiedTimestamp.getAsLong());