diff --git a/src/main/java/com/fstack/config/GlobalExceptionHandler.java b/src/main/java/com/fstack/config/GlobalExceptionHandler.java index 7d0850e62e334f2f8645cc85f6994af3b7f9383f..7806a28743f92789ec5c4633a510558e9daa68fc 100644 --- a/src/main/java/com/fstack/config/GlobalExceptionHandler.java +++ b/src/main/java/com/fstack/config/GlobalExceptionHandler.java @@ -3,28 +3,17 @@ package com.fstack.config; import com.fstack.common.ApiResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Enumeration; -/** - * @author Hu Jie - * @date 2019/04/23 10:21 AM - */ -@ControllerAdvice +@RestControllerAdvice public class GlobalExceptionHandler { private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); - /** - * 捕获具体指定外的所有异常 - * - * @param ex - * @param request - * @param response - */ @ExceptionHandler(value = Exception.class) public ApiResponse handle(Exception ex, HttpServletRequest request, HttpServletResponse response) { logger.error("***** GlobalException Start *****"); diff --git a/src/main/java/com/fstack/constant/CommentConstant.java b/src/main/java/com/fstack/constant/CommentConstant.java new file mode 100644 index 0000000000000000000000000000000000000000..fcefe6d3c2d24264d6f1274669c4507fbe971a9f --- /dev/null +++ b/src/main/java/com/fstack/constant/CommentConstant.java @@ -0,0 +1,11 @@ +package com.fstack.constant; + +public class CommentConstant { + + + public static final int COMMENT_LENGTH_MAX = 1024; + public static final int COMMENT_LENGTH_MIN = 1; + + private CommentConstant() { + } +} diff --git a/src/main/java/com/fstack/constant/PostConstant.java b/src/main/java/com/fstack/constant/PostConstant.java index fa5c48160b9d79fa7297d6987ff1ae9a498274be..feee95b8c43fcde91daddf1bb0dc37b5f2442e69 100644 --- a/src/main/java/com/fstack/constant/PostConstant.java +++ b/src/main/java/com/fstack/constant/PostConstant.java @@ -6,7 +6,7 @@ package com.fstack.constant; */ public class PostConstant { - public static final int TITLE_LENGTH_MAX = 30; + public static final int TITLE_LENGTH_MAX = 150; public static final int TITLE_LENGTH_MIN = 3; public static final int BODY_LENGTH_MAX = 65535; diff --git a/src/main/java/com/fstack/constant/StorageConstant.java b/src/main/java/com/fstack/constant/StorageConstant.java index 95762f632c6a96ea5c2dbe857fe89254861e9dfc..d53099d0f569682d2899e14be7cd3f620177d3c1 100644 --- a/src/main/java/com/fstack/constant/StorageConstant.java +++ b/src/main/java/com/fstack/constant/StorageConstant.java @@ -7,8 +7,7 @@ package com.fstack.constant; */ public class StorageConstant { private StorageConstant() {} - //default avatar - public static final String DEFAULT_AVATAR_FILENAME = "default.jpg"; + //base path define public static final String BASE_DIRECTORY_NAME = "FsForumData"; diff --git a/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java b/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java index 679cd710017cbc1a38e48f181b08b69dbf0f035c..28fa66f36ed411fd5faf036b7a0d006ed407b3cf 100644 --- a/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java @@ -26,7 +26,7 @@ public class CategoryServiceImpl implements CategoryService { public Map getNewPostPageWithCategoryName(String categoryName) { Map attributes = new HashMap<>(); Category category = this.categoryMapper.findByName(categoryName); - attributes.put("title", i18nUtil.getMessage("")); + attributes.put("title", i18nUtil.getMessage("post.new")); PostDto newPostForm = new PostDto(); newPostForm.setCategory(category.getName()); attributes.put("postDto", newPostForm); diff --git a/src/main/java/com/fstack/service/impl/PostServiceImpl.java b/src/main/java/com/fstack/service/impl/PostServiceImpl.java index d9f260d6ad8cfc8e749db77e9bba83721fc272ba..ed6c3a9d74ab3b054438d6c567b76e666de3af23 100644 --- a/src/main/java/com/fstack/service/impl/PostServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/PostServiceImpl.java @@ -104,6 +104,7 @@ public class PostServiceImpl implements PostService { // find category String categoryName = newPostForm.getCategory().replace(",", ""); Category category = this.categoryMapper.findByName(categoryName); + if (null == category) category = this.categoryMapper.findByName("default"); // construct new post Post post = new Post(); post.setTitle(newPostForm.getTitle()); diff --git a/src/main/java/com/fstack/service/impl/UserServiceImpl.java b/src/main/java/com/fstack/service/impl/UserServiceImpl.java index b0268f11bf82099972c0aaecc2994d52409d87df..2752c14648e41c8ac2b17df5305bb97cff758a83 100644 --- a/src/main/java/com/fstack/service/impl/UserServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/UserServiceImpl.java @@ -59,7 +59,7 @@ public class UserServiceImpl implements UserService { @Override public int save(User user) { user.setPassword(passwordEncoder.encode(user.getPassword())); - user.setAvatarLocation(StorageConstant.DEFAULT_AVATAR_FILENAME); + user.setAvatarLocation("/avatar/admin/timg.jpg"); return userMapper.save(user); } @@ -162,9 +162,8 @@ public class UserServiceImpl implements UserService { user.setEmail(userDto.getEmail()); user.setDateCreated(new Timestamp(System.currentTimeMillis())); user.setRoles(User.USER); - if (userDto.getUsername().startsWith("IT")) user.activated(true); - else user.activated(false); - // save new user and get number of affected row + user.activated(false); + user.setAvatarLocation("/avatar/admin/timg.jpg"); int affectedRow = userMapper.save(user); // publish registration event diff --git a/src/main/java/com/fstack/validator/NewCommentFormValidator.java b/src/main/java/com/fstack/validator/NewCommentFormValidator.java index d1f79b205c915d4e58c49f6eb0d057c0adfdbb2f..28353cf8ff0df3e7936e03ab5aa69106d1930a59 100644 --- a/src/main/java/com/fstack/validator/NewCommentFormValidator.java +++ b/src/main/java/com/fstack/validator/NewCommentFormValidator.java @@ -1,5 +1,35 @@ package com.fstack.validator; -public class NewCommentFormValidator { +import com.fstack.constant.CommentConstant; +import com.fstack.persistence.model.Comment; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +@Component +public class NewCommentFormValidator implements Validator { + + @Autowired + private MessageSource messageSource; + + @Override + public boolean supports(Class clazz) { + return Comment.class.equals(clazz); + } + + @Override + public void validate(Object object, Errors errors) { + Comment newComment = (Comment) object; + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "comment", "NotEmpty"); + if (newComment.getBody() != null && !newComment.getBody().isEmpty()) { + if (newComment.getBody().length() < CommentConstant.COMMENT_LENGTH_MIN || newComment.getBody().length() > CommentConstant.COMMENT_LENGTH_MAX) { + errors.rejectValue("comment", "comment.length", messageSource.getMessage("comment.length", null, null)); + } + } + + } } diff --git a/src/main/java/com/fstack/web/controller/PostController.java b/src/main/java/com/fstack/web/controller/PostController.java index 63d71e50b6250deea7a84161fac5013b5c2b5008..c6eb891c15f76985e263e76c3ad508ff766db1fb 100644 --- a/src/main/java/com/fstack/web/controller/PostController.java +++ b/src/main/java/com/fstack/web/controller/PostController.java @@ -4,6 +4,7 @@ import java.util.Map; import javax.validation.Valid; +import com.fstack.validator.NewCommentFormValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -30,103 +31,112 @@ import com.fstack.web.dto.PostDto; @Controller public class PostController { - private static final Logger logger = LoggerFactory.getLogger(PostController.class); - - @Autowired - private PostService postService; - - @Autowired - private CategoryService categoryService; - - @Autowired - private CommentService commentService; - - @Autowired - private NewPostFormValidator newPostValidator; - - @Autowired - ApplicationEventPublisher eventPublisher; - - @RequestMapping(value = "/post/list", method = RequestMethod.GET) - public String index(Model model) { - Map attributes = postService.findPosts(); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAttribute(attributes); - return "fragments/posts-list"; - } - - @RequestMapping(value = "/post/{postId}", method = RequestMethod.GET) - public String getPost(Model model, @PathVariable Long postId) { - if (null == postId) { - throw new BadRequestException("Path variable postId cound not be null."); - } - Map attributes = this.postService.findPostDetailsAndCommentsByPostId(postId); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/post"; - } - - @RequestMapping(value = "/new/{categoryName}", method = RequestMethod.GET) - public String displayNewPostPageWithCategory(Model model, @PathVariable String categoryName) { - if (null == categoryName) { - throw new BadRequestException("Path variable postId cound not be null."); - } - Map attributes = this.categoryService.getNewPostPageWithCategoryName(categoryName); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/new-post"; - } - - @RequestMapping(value = "/new", method = RequestMethod.GET) - public String displayNewPostPage(Model model) { - Map attributes = this.categoryService.getNewPostPageWithCategorySelect(); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/new-post"; - } - - @RequestMapping(value = "/new", method = RequestMethod.POST) - public String processNewPost(@Valid @ModelAttribute("postDto") PostDto postDto, BindingResult bindingResult, - Model model) { - if (null == postDto) { - throw new BadRequestException("NewPostForm cound not be null."); - } - Post post = this.postService.createNewPost(postDto); - if (null == post) { - throw new ResourceNotFoundException("New post object can't be created."); - } - // post form validation - this.newPostValidator.validate(post, bindingResult); - if (bindingResult.hasErrors()) { - logger.info("BindingResult has errors >> " + bindingResult.getFieldError()); - return "forum/new-post"; - } else { - this.postService.save(post); - } - return "redirect:/"; - } - - @RequestMapping(value = "/post/{postId}", method = RequestMethod.POST) - public String processNewComment(@PathVariable Long postId, - @Valid @ModelAttribute("commentDto") CommentDto commentDto) { - if (null == postId && null == commentDto) { - throw new BadRequestException("Path variable postId and newCommentForm cound not be null."); - } - Comment comment = this.commentService.createNewCommentOnPost(postId, commentDto); - if (null == comment) { - throw new ResourceNotFoundException("New comment object can't be created."); - } - // comment form validation here ... - this.commentService.save(comment); - return "redirect:/post/{postId}"; - } + private static final Logger logger = LoggerFactory.getLogger(PostController.class); + + @Autowired + private PostService postService; + + @Autowired + private CategoryService categoryService; + + @Autowired + private CommentService commentService; + + @Autowired + private NewPostFormValidator newPostValidator; + + @Autowired + private NewCommentFormValidator newCommentFormValidator; + + @Autowired + ApplicationEventPublisher eventPublisher; + + @RequestMapping(value = "/post/list", method = RequestMethod.GET) + public String index(Model model) { + Map attributes = postService.findPosts(); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAttribute(attributes); + return "fragments/posts-list"; + } + + @RequestMapping(value = "/post/{postId}", method = RequestMethod.GET) + public String getPost(Model model, @PathVariable Long postId) { + if (null == postId) { + throw new BadRequestException("Path variable postId cound not be null."); + } + Map attributes = this.postService.findPostDetailsAndCommentsByPostId(postId); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/post"; + } + + @RequestMapping(value = "/new/{categoryName}", method = RequestMethod.GET) + public String displayNewPostPageWithCategory(Model model, @PathVariable String categoryName) { + if (null == categoryName) { + throw new BadRequestException("Path variable postId cound not be null."); + } + Map attributes = this.categoryService.getNewPostPageWithCategoryName(categoryName); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/new-post"; + } + + @RequestMapping(value = "/new", method = RequestMethod.GET) + public String displayNewPostPage(Model model) { + Map attributes = this.categoryService.getNewPostPageWithCategorySelect(); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/new-post"; + } + + @RequestMapping(value = "/new", method = RequestMethod.POST) + public String processNewPost(@Valid @ModelAttribute("postDto") PostDto postDto, BindingResult bindingResult, + Model model) { + if (null == postDto) { + throw new BadRequestException("NewPostForm cound not be null."); + } + Post post = this.postService.createNewPost(postDto); + if (null == post) { + throw new ResourceNotFoundException("New post object can't be created."); + } + // post form validation + this.newPostValidator.validate(post, bindingResult); + if (bindingResult.hasErrors()) { + logger.info("BindingResult has errors >> " + bindingResult.getFieldError()); + return "forum/new-post"; + } else { + this.postService.save(post); + } + return "redirect:/"; + } + + @RequestMapping(value = "/post/{postId}", method = RequestMethod.POST) + public String processNewComment(@PathVariable Long postId, + @Valid @ModelAttribute("commentDto") CommentDto commentDto, BindingResult bindingResult) { + if (null == postId && null == commentDto) { + throw new BadRequestException("Path variable postId and newCommentForm cound not be null."); + } + Comment comment = this.commentService.createNewCommentOnPost(postId, commentDto); + if (null == comment) { + throw new ResourceNotFoundException("New comment object can't be created."); + } + // comment form validation + this.newCommentFormValidator.validate(comment, bindingResult); + if (bindingResult.hasErrors()) { + logger.info("BindingResult has errors >> " + bindingResult.getFieldError()); + throw new BadRequestException(bindingResult.getFieldError().getDefaultMessage()); + } else { + this.commentService.save(comment); + } + return "redirect:/post/{postId}"; + } } \ No newline at end of file diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index cf0bb0b738b32751cae0cb4f227f07d9c2e6a924..4275b23833f5093c4e35ddc56ac80e07a36bab21 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -31,13 +31,17 @@ spring.redis.lettuce.pool.max-wait=-1ms # ============================== # SMTP Email # ============================== -spring.mail.default-encoding=UTF-8 -spring.mail.host = smtp.163.com +spring.mail.default-encoding= UTF-8 +spring.mail.host= smtp.163.com +spring.mail.port= 465 +spring.mail.properties.mail.smtp.socketFactory.port = 465 +spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory +spring.mail.properties.mail.smtp.socketFactory.fallback = false spring.mail.username = look7788ab@163.com spring.mail.password = look7788ab -spring.mail.properties.mail.smtp.auth=true -spring.mail.properties.mail.smtp.starttls.enable=true -spring.mail.properties.mail.smtp.starttls.required=true +spring.mail.properties.mail.smtp.auth= true +spring.mail.properties.mail.smtp.starttls.enable= true +spring.mail.properties.mail.smtp.starttls.required= true # ============================== # service base URL for confirmation link diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 7c9960feae0345539a15834722b0090008fd33cf..3e3a6d6978cfbef75835e45951680f7d00a65110 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -31,13 +31,17 @@ spring.redis.lettuce.pool.max-wait=-1ms # ============================== # SMTP Email # ============================== -spring.mail.default-encoding=UTF-8 -spring.mail.host = smtp.163.com +spring.mail.default-encoding= UTF-8 +spring.mail.host= smtp.163.com +spring.mail.port= 465 +spring.mail.properties.mail.smtp.socketFactory.port = 465 +spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory +spring.mail.properties.mail.smtp.socketFactory.fallback = false spring.mail.username = look7788ab@163.com spring.mail.password = look7788ab -spring.mail.properties.mail.smtp.auth=true -spring.mail.properties.mail.smtp.starttls.enable=true -spring.mail.properties.mail.smtp.starttls.required=true +spring.mail.properties.mail.smtp.auth= true +spring.mail.properties.mail.smtp.starttls.enable= true +spring.mail.properties.mail.smtp.starttls.required= true # ============================== # service base URL for confirmation link diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties new file mode 100644 index 0000000000000000000000000000000000000000..664f81d908dd5e074d8ba36e200ccab83e2e6688 --- /dev/null +++ b/src/main/resources/application-pro.properties @@ -0,0 +1,57 @@ +# ============================== +# MySQL connection config +# ============================== +spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver +spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fs_forum?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.username = fstack +spring.datasource.password = fstack +spring.datasource.type=com.zaxxer.hikari.HikariDataSource +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.maximum-pool-size=15 +spring.datasource.hikari.auto-commit=true +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.pool-name=fang +spring.datasource.hikari.max-lifetime=1800000 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.connection-test-query=SELECT 1 + +# ============================== +# Redis configuration +# ============================== +spring.redis.database=0 +spring.redis.host=192.168.1.130 +spring.redis.port=6379 +spring.redis.password=123456 +spring.redis.timeout=5000ms +spring.redis.lettuce.pool.max-idle=10 +spring.redis.lettuce.pool.min-idle=5 +spring.redis.lettuce.pool.max-active=20 +spring.redis.lettuce.pool.max-wait=-1ms + +# ============================== +# SMTP Email +# ============================== +spring.mail.default-encoding= UTF-8 +spring.mail.host= smtp.163.com +spring.mail.port= 465 +spring.mail.properties.mail.smtp.socketFactory.port = 465 +spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory +spring.mail.properties.mail.smtp.socketFactory.fallback = false +spring.mail.username = look7788ab@163.com +spring.mail.password = look7788ab +spring.mail.properties.mail.smtp.auth= true +spring.mail.properties.mail.smtp.starttls.enable= true +spring.mail.properties.mail.smtp.starttls.required= true + +# ============================== +# service base URL for confirmation link +# ============================== +service.url=http://forum.polysys.cn/ + +# ============================== +# File upload configuration +# ============================== +spring.servlet.multipart.max-file-size=500KB +spring.servlet.multipart.max-request-size =500KB + +enable.swagger=false \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ee0979bdff5f75099f9aeff864526d1a919a3b0e..2c807f08e53d440fad8d8bf62113b73b5548f8cd 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ server.port=9999 -spring.profiles.active= local +spring.profiles.active= pro server.servlet.context-path= / spring.aop.proxy-target-class=true # ============================== diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index f56f6c8c262c9d43f14793d30e16795d94a7b02e..7ac937a76b91218f3ed4e66fc396690b85466617 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -6,6 +6,11 @@ userForm.email.invalid=This is an invalid Email. userForm.email.duplicate=This Email already exists. userForm.password.length=Try one with at least 5 characters. userForm.password.diff=These passwords don't match. +message.badCredentials=badCredentials +auth.message.disabled=User is disabled +auth.message.expired=User account has expired # new post messages -post.title.length=Title of new post must use 3 and 30 characters. -post.body.length=Title of new post must use 3 and 30 characters. +post.title.length=Title of new post must use 3 and 150 characters. +post.body.length=Body of new post must use 3 and 65535 characters. +# new comment messages +comment.length=Comment of new post must use 1 to 1024 characters.