diff --git a/src/main/java/run/halo/app/config/WebMvcAutoConfiguration.java b/src/main/java/run/halo/app/config/WebMvcAutoConfiguration.java index 04ebbcf73656284e6daae3daa54b8d2b5833c3ff..9f86ca5e4831c18c28c6afed2a0bca679ec2c5e3 100644 --- a/src/main/java/run/halo/app/config/WebMvcAutoConfiguration.java +++ b/src/main/java/run/halo/app/config/WebMvcAutoConfiguration.java @@ -3,7 +3,6 @@ package run.halo.app.config; import com.fasterxml.jackson.databind.ObjectMapper; import freemarker.template.TemplateExceptionHandler; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.jackson.JsonComponentModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -44,8 +43,11 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer { private static final String FILE_PROTOCOL = "file:///"; - @Autowired - private HaloProperties haloProperties; + private final HaloProperties haloProperties; + + public WebMvcAutoConfiguration(HaloProperties haloProperties) { + this.haloProperties = haloProperties; + } @Override public void extendMessageConverters(List> converters) { diff --git a/src/main/java/run/halo/app/service/PostService.java b/src/main/java/run/halo/app/service/PostService.java index 4a8a84f8f99ee9511af2fbff43c5d5c98eeaa54a..7cc33b8b67967caf9028f7c069862f333289a613 100755 --- a/src/main/java/run/halo/app/service/PostService.java +++ b/src/main/java/run/halo/app/service/PostService.java @@ -193,4 +193,22 @@ public interface PostService extends CrudService { */ @NonNull Page convertToListVo(@NonNull Page postPage); + + /** + * Lists all posts by post status. + * + * @param status post status must not be null + * @return a list of post + */ + @NonNull + List listAllBy(@NonNull PostStatus status); + + /** + * Filters post content if the password is not blank. + * + * @param post original post must not be null + * @return filtered post + */ + @NonNull + Post filterIfEncrypt(@NonNull Post post); } diff --git a/src/main/java/run/halo/app/service/impl/PostServiceImpl.java b/src/main/java/run/halo/app/service/impl/PostServiceImpl.java index 549b89c6e5b1eea66299e03d1fce8b3b383fd28a..11968aee674d26be9bf3b9e0b5be0d3603f95ce6 100644 --- a/src/main/java/run/halo/app/service/impl/PostServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/PostServiceImpl.java @@ -416,6 +416,27 @@ public class PostServiceImpl extends AbstractCrudService implemen }); } + @Override + public List listAllBy(PostStatus status) { + Assert.notNull(status, "Post status must not be null"); + + return postRepository.findAllByStatus(status); + } + + @Override + public Post filterIfEncrypt(Post post) { + Assert.notNull(post, "Post must not be null"); + + if (StringUtils.isNotBlank(post.getPassword())) { + String tip = "The post is encrypted by author"; + post.setSummary(tip); + post.setOriginalContent(tip); + post.setFormatContent(tip); + } + + return post; + } + /** * Converts to post minimal output dto. * diff --git a/src/main/java/run/halo/app/web/controller/base/ControllerExceptionHandler.java b/src/main/java/run/halo/app/web/controller/base/ControllerExceptionHandler.java index b4904e999106af4e3e5dd84df970a79b410cd61b..41023fdffbb8124abdf9c3b7699ccb9f0beb9747 100644 --- a/src/main/java/run/halo/app/web/controller/base/ControllerExceptionHandler.java +++ b/src/main/java/run/halo/app/web/controller/base/ControllerExceptionHandler.java @@ -1,5 +1,6 @@ package run.halo.app.web.controller.base; +import org.springframework.web.HttpMediaTypeNotAcceptableException; import run.halo.app.exception.HaloException; import run.halo.app.model.support.BaseResponse; import run.halo.app.utils.ExceptionUtils; @@ -82,6 +83,14 @@ public class ControllerExceptionHandler { return baseResponse; } + @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) + @ResponseStatus(HttpStatus.NOT_ACCEPTABLE) + public BaseResponse handleHttpMediaTypeNotAcceptableException(HttpMediaTypeNotAcceptableException e) { + BaseResponse baseResponse = handleBaseException(e); + baseResponse.setStatus(HttpStatus.NOT_ACCEPTABLE.value()); + return baseResponse; + } + @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public BaseResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { diff --git a/src/main/java/run/halo/app/web/controller/content/ContentFeedController.java b/src/main/java/run/halo/app/web/controller/content/ContentFeedController.java index fe943098780da2f149863046c198822416232d1a..9b3d6caaac476a371106a55271a995d487720e2d 100644 --- a/src/main/java/run/halo/app/web/controller/content/ContentFeedController.java +++ b/src/main/java/run/halo/app/web/controller/content/ContentFeedController.java @@ -1,17 +1,12 @@ package run.halo.app.web.controller.content; -import run.halo.app.model.entity.Post; -import run.halo.app.model.enums.PostStatus; -import run.halo.app.model.enums.PostType; -import run.halo.app.service.OptionService; -import run.halo.app.service.PostService; -import cn.hutool.core.util.StrUtil; import freemarker.template.Template; import freemarker.template.TemplateException; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.http.MediaType; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; @@ -20,11 +15,14 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import run.halo.app.model.entity.Post; import run.halo.app.model.enums.PostStatus; +import run.halo.app.service.OptionService; import run.halo.app.service.PostService; import java.io.IOException; import java.util.List; +import static org.springframework.data.domain.Sort.Direction.DESC; + /** * @author : RYAN0UP * @date : 2019-03-21 @@ -38,6 +36,10 @@ public class ContentFeedController { private final FreeMarkerConfigurer freeMarker; + private final static String UTF_8_SUFFIX = ";charset=UTF-8"; + + private final static String XML_MEDIA_TYPE = MediaType.APPLICATION_XML_VALUE + UTF_8_SUFFIX; + public ContentFeedController(PostService postService, OptionService optionService, FreeMarkerConfigurer freeMarker) { @@ -54,14 +56,11 @@ public class ContentFeedController { * @throws IOException IOException * @throws TemplateException TemplateException */ - @GetMapping(value = {"feed", "feed.xml", "rss", "rss.xml"}, produces = "application/xml;charset=UTF-8") + @GetMapping(value = {"feed", "feed.xml", "rss", "rss.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody public String feed(Model model) throws IOException, TemplateException { - int rssPageSize = optionService.getRssPageSize(); - final Sort sort = new Sort(Sort.Direction.DESC, "postDate"); - final Pageable pageable = PageRequest.of(0, rssPageSize, sort); - model.addAttribute("posts", buildPosts(pageable)); - final Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl"); + model.addAttribute("posts", buildPosts(buildPostPageable(optionService.getRssPageSize()))); + Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -73,14 +72,11 @@ public class ContentFeedController { * @throws IOException IOException * @throws TemplateException TemplateException */ - @GetMapping(value = {"atom", "atom.xml"}, produces = "application/xml;charset=UTF-8") + @GetMapping(value = {"atom", "atom.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody public String atom(Model model) throws IOException, TemplateException { - int pageSize = optionService.getPostPageSize(); - final Sort sort = new Sort(Sort.Direction.DESC, "createTime"); - final Pageable pageable = PageRequest.of(0, pageSize, sort); - model.addAttribute("posts", buildPosts(pageable)); - final Template template = freeMarker.getConfiguration().getTemplate("common/web/atom.ftl"); + model.addAttribute("posts", buildPosts(buildPostPageable(optionService.getPostPageSize()))); + Template template = freeMarker.getConfiguration().getTemplate("common/web/atom.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -92,11 +88,11 @@ public class ContentFeedController { * @throws IOException IOException * @throws TemplateException TemplateException */ - @GetMapping(value = {"sitemap", "sitemap.xml"}, produces = "application/xml;charset=UTF-8") + @GetMapping(value = {"sitemap", "sitemap.xml"}, produces = XML_MEDIA_TYPE) @ResponseBody public String sitemapXml(Model model) throws IOException, TemplateException { model.addAttribute("posts", buildPosts(null)); - final Template template = freeMarker.getConfiguration().getTemplate("common/web/sitemap_xml.ftl"); + Template template = freeMarker.getConfiguration().getTemplate("common/web/sitemap_xml.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } @@ -106,7 +102,7 @@ public class ContentFeedController { * @param model model * @return String */ - @GetMapping(value = "sitemap.html", produces = {"text/html"}) + @GetMapping(value = "sitemap.html", produces = MediaType.TEXT_PLAIN_VALUE) public String sitemapHtml(Model model) { model.addAttribute("posts", buildPosts(null)); return "common/web/sitemap_html"; @@ -120,13 +116,24 @@ public class ContentFeedController { * @throws IOException IOException * @throws TemplateException TemplateException */ - @GetMapping(value = "robots.txt", produces = {"text/plain"}) + @GetMapping(value = "robots.txt", produces = MediaType.TEXT_PLAIN_VALUE) @ResponseBody public String robots(Model model) throws IOException, TemplateException { - final Template template = freeMarker.getConfiguration().getTemplate("common/web/robots.ftl"); + Template template = freeMarker.getConfiguration().getTemplate("common/web/robots.ftl"); return FreeMarkerTemplateUtils.processTemplateIntoString(template, model); } + /** + * Builds page info for post. + * + * @param size page size + * @return page info + */ + @NonNull + private Pageable buildPostPageable(int size) { + return PageRequest.of(0, size, Sort.by(DESC, "createTime")); + } + /** * Build posts for feed * @@ -134,13 +141,10 @@ public class ContentFeedController { * @return List */ private List buildPosts(Pageable pageable) { - final Page postsPage = postService.pageBy(PostStatus.PUBLISHED, pageable).map(post -> { - if (StrUtil.isNotEmpty(post.getPassword())) { - post.setFormatContent("该文章为加密文章"); - post.setSummary("该文章为加密文章"); - } - return post; - }); - return postsPage.getContent(); + if (pageable == null) { + return postService.listAllBy(PostStatus.PUBLISHED); + } + + return postService.pageBy(PostStatus.PUBLISHED, pageable).map(postService::filterIfEncrypt).getContent(); } }