实现后台管理员的登入功能
UserRepository
public interface UserRepository extends JpaRepository<User, Long> { User findByUsernameAndPassword(String username, String password); }
UserService
public interface UserService { User checkUser(String username, String password); }
UserServiceImpl
@Service public class UserServiceImpl implements UserService{ @Autowired private UserRepository userRepository; @Override public User checkUser(String username, String password) { User user = userRepository.findByUsernameAndPassword(username, password); return user; } }
将user放入session需要将重要信息消除,以防被截取,例如第18行中将密码消除再放入session中
LoginController
@Controller @RequestMapping("/admin") public class LoginController { @Autowired private UserService userService; @GetMapping public String loginPage() { return "admin/login"; } @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password, HttpSession session, RedirectAttributes redirectAttributes) { User user = userService.checkUser(username, password); if(user != null) { user.setPassword(null); session.setAttribute("user", user); return "admin/index"; } redirectAttributes.addFlashAttribute("message", "用户名或密码错误"); return "redirect:/admin"; } @GetMapping("/logout") public String logout(HttpSession session) { session.removeAttribute("user"); return "redirect:/admin"; } }
防止有人撞库获取我们管理员的用户密码,我们采取MD5对我们的密码进行加密后存入数据库中
MD5Util
public class MD5Util { public static String code(String str){ try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(str.getBytes()); byte[] byteDigest = md.digest(); int i; StringBuffer buf = new StringBuffer(""); for (int offset = 0; offset < byteDigest.length; offset++){ i = byteDigest[offset]; if (i<0) i += 256; if (i<16) buf.append("0"); buf.append(Integer.toHexString(i)); } //32位加密 return buf.toString(); //64位加密 //return buf.toString().substring(8,24); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } }
@Service public class UserServiceImpl implements UserService{ @Autowired private UserRepository userRepository; @Override public User checkUser(String username, String password) { User user = userRepository.findByUsernameAndPassword(username, MD5Util.code(password)); return user; } }
如果有用户获取了我们的管理员管理界面路径,即使未登录时也可以使用对应的路径名访问我们的管理员界面,显然是不安全的。所以我们要使用登录拦截器来防止这种情况发生,当用户未登录时,访问我们的管理员管理界面都会被重定向到管理员登录界面。
LoginInterceptor
public class LoginInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getSession().getAttribute("user") == null){ response.sendRedirect("/admin"); return false; } return true; } }
WebConfig
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/admin/**") .excludePathPatterns("/admin") .excludePathPatterns("/admin/login"); } }
TypeService
public interface TypeService { Type saveType(Type type); Type getType(Long id); Page<Type> listType(Pageable pageable); Type updateType(Long id, Type type); void deleteType(Long id); Type getTypeByName(String name); }
TypeServiceImpl
@Service public class TypeServiceImpl implements TypeService{ @Autowired private TypeRepository typeRepository; @Transactional @Override public Type saveType(Type type) { return typeRepository.save(type); } @Transactional @Override public Type getType(Long id) { return typeRepository.getOne(id); } @Transactional @Override public Page<Type> listType(Pageable pageable) { return typeRepository.findAll(pageable); } @Transactional @Override public Type updateType(Long id, Type type) { Type t = typeRepository.getOne(id); if(t == null) throw new NotFoundException("不存在该类型"); BeanUtils.copyProperties(type, t); return typeRepository.save(t); } @Transactional @Override public void deleteType(Long id) { typeRepository.deleteById(id); } @Transactional @Override public Type getTypeByName(String name) { return typeRepository.findByName(name); } }
TypeRepository
public interface TypeRepository extends JpaRepository<Type, Long> { Type findByName(String name); }
TypeController
@Controller @RequestMapping("/admin") public class TypeController { @Autowired private TypeService typeService; @GetMapping("/types") public String list(@PageableDefault(size = 10, sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable, Model model) { model.addAttribute("page", typeService.listType(pageable)); return "/admin/types"; } @GetMapping("/types/input") public String input(Model model) { model.addAttribute("type", new Type()); return "/admin/types-input"; } @GetMapping("/types/{id}/input") public String editInput(@PathVariable Long id, Model model) { model.addAttribute("type", typeService.getType(id)); return "/admin/types-input"; } @Transactional @PostMapping("/types") public String post(@Valid Type type, BindingResult result, RedirectAttributes attributes) { Type type1 = typeService.getTypeByName(type.getName()); if(type1 != null) { result.rejectValue("name", "nameError", "该分类已存在"); } if(result.hasErrors()) { return "/admin/types-input"; } Type t = typeService.saveType(type); if (t == null){ attributes.addFlashAttribute("message","新增失败"); }else { attributes.addFlashAttribute("message","新增成功"); } return "redirect:/admin/types"; } @Transactional @PostMapping("/types/{id}") public String editPost(@Valid Type type, @PathVariable Long id, BindingResult result, RedirectAttributes attributes) { Type type1 = typeService.getTypeByName(type.getName()); if(type1 != null) { result.rejectValue("name", "nameError", "该分类已存在"); } if(result.hasErrors()) { return "/admin/types-input"; } Type t = typeService.updateType(id, type); if (t == null){ attributes.addFlashAttribute("message","更新失败"); }else { attributes.addFlashAttribute("message","更新成功"); } return "redirect:/admin/types"; } @GetMapping("/types/{id}/delete") public String delete(@PathVariable Long id, RedirectAttributes attributes) { typeService.deleteType(id); attributes.addFlashAttribute("message", "删除成功"); return "redirect:/admin/types"; } }
TagRepository
public interface TagRepository extends JpaRepository<Tag, Long> { Tag findByName(String name); }
TagService
public interface TagService { Tag saveTag(Tag tag); Tag getTag(Long id); Page<Tag> listTag(Pageable pageable); Tag updateTag(Long id, Tag tag); void deleteTag(Long id); Tag getTagByName(String name); }
TagServiceImpl
@Service public class TagServiceImpl implements TagService { @Autowired private TagRepository tagRepository; @Transactional @Override public Tag saveTag(Tag tag) { return tagRepository.save(tag); } @Transactional @Override public Tag getTag(Long id) { return tagRepository.getOne(id); } @Transactional @Override public Page<Tag> listTag(Pageable pageable) { return tagRepository.findAll(pageable); } @Transactional @Override public Tag updateTag(Long id, Tag tag) { Tag t = tagRepository.getOne(id); if(t == null) { throw new NotFoundException("不存在该标签"); } BeanUtils.copyProperties(tag, t); return tagRepository.save(t); } @Transactional @Override public void deleteTag(Long id) { tagRepository.deleteById(id); } @Transactional @Override public Tag getTagByName(String name) { return null; } }
TagController
@Controller @RequestMapping("/admin") public class TagController { @Autowired private TagService tagService; @GetMapping("/tags") public String tags(@PageableDefault(size = 10, sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable, Model model) { model.addAttribute("page", tagService.listTag(pageable)); return "/admin/tags"; } @GetMapping("/tags/input") public String input(Model model) { model.addAttribute("tag", new Tag()); return "/admin/tags-input"; } @GetMapping("/tags/{id}/input") public String edit(@PathVariable Long id, Model model) { model.addAttribute("tag", tagService.getTag(id)); return "/admin/tags-input"; } @PostMapping("/tags") public String post(@Valid Tag tag, BindingResult result, RedirectAttributes attributes) { Tag tag1 = tagService.getTagByName(tag.getName()); if (tag1 != null) { result.rejectValue("name", "nameError", "该标签已存在"); } if(result.hasErrors()) { return "/admin/tags-input"; } Tag t = tagService.saveTag(tag); if(t == null) { attributes.addFlashAttribute("message", "新增失败"); }else { attributes.addFlashAttribute("message", "新增成功"); } return "redirect:/admin/tags"; } @PostMapping("/tags/{id}") public String editpost(@Valid Tag tag, @PathVariable Long id, BindingResult result, RedirectAttributes attributes) { Tag tag1 = tagService.getTagByName(tag.getName()); if (tag1 != null) { result.rejectValue("name", "nameError", "该标签已存在"); } if(result.hasErrors()) { return "/admin/tags-input"; } Tag t = tagService.updateTag(id, tag); if(t == null) { attributes.addFlashAttribute("message", "更新失败"); }else { attributes.addFlashAttribute("message", "更新成功"); } return "redirect:/admin/tags"; } @GetMapping("tags/{id}/delete") public String delete(@PathVariable Long id, RedirectAttributes attributes) { tagService.deleteTag(id); attributes.addFlashAttribute("message", "删除成功"); return "redirect:/admin/tags"; } }
BlogService
public interface BlogService { Blog getBlog(Long id); Page<Blog> listBlog(Pageable pageable, BlogQuery blog); Blog saveBlog(Blog blog); Blog updateBlog(Long id, Blog blog); void deleteBlog(Long id); }
因为博客查询功能中提供了按指定条件查询,所以需要实现模糊查询。
其实本质上就是对本身select全部博客的sql语句添加了where条件进行筛选结果。
BlogRepository
继承JpaSpecificationExecuto
r类BlogRepository
public interface BlogRepository extends JpaRepository<Blog, Long>, JpaSpecificationExecutor<Blog> { }
public class BlogQuery { private String title; private Long TypeId; private boolean recommend; public BlogQuery() { } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Long getTypeId() { return TypeId; } public void setTypeId(Long typeId) { TypeId = typeId; } public boolean isRecommend() { return recommend; } public void setRecommend(boolean recommend) { this.recommend = recommend; } }
BlogServiceImpl
的listBlog
方法实现如下@Override public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) { return blogRepository.findAll(new Specification<Blog>() { @Override public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<>(); if (blog.getTitle() != null && !"".equals(blog.getTitle())){ predicates.add(cb.like(root.<String>get("title"),"%"+blog.getTitle()+"%")); } if (blog.getTypeId() != null){ predicates.add(cb.equal(root.<Type>get("type").get("id"),blog.getTypeId())); } if (blog.isRecommend()){ predicates.add(cb.equal(root.<Boolean>get("recommend"),blog.isRecommend())); } cq.where(predicates.toArray(new Predicate[predicates.size()])); return null; } },pageable); }
BlogServiceImpl
@Service public class BlogServiceImpl implements BlogService{ @Autowired private BlogRepository blogRepository; @Override public Blog getBlog(Long id) { return blogRepository.getOne(id); } @Override public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) { return blogRepository.findAll(new Specification<Blog>() { @Override public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<>(); if (blog.getTitle() != null && !"".equals(blog.getTitle())){ predicates.add(cb.like(root.<String>get("title"),"%"+blog.getTitle()+"%")); } if (blog.getTypeId() != null){ predicates.add(cb.equal(root.<Type>get("type").get("id"),blog.getTypeId())); } if (blog.isRecommend()){ predicates.add(cb.equal(root.<Boolean>get("recommend"),blog.isRecommend())); } cq.where(predicates.toArray(new Predicate[predicates.size()])); return null; } },pageable); } @Transactional @Override public Blog saveBlog(Blog blog) { SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm"); if(blog.getId() == null) { blog.setCreateTime(new Date()); blog.setViews(0); } blog.setUpdateTime(new Date()); return blogRepository.save(blog); } @Transactional @Override public Blog updateBlog(Long id, Blog blog) { Blog t = blogRepository.getOne(id); if(t == null) throw new NotFoundException("该博客不存在"); blog.setUpdateTime(new Date()); BeanUtils.copyProperties(blog, t, MyBeanUtils.getNullPropertyNames(blog)); return blogRepository.save(t); } @Transactional @Override public void deleteBlog(Long id) { blogRepository.deleteById(id); } }
BlogController
@Controller @RequestMapping("/admin") public class BlogController { @Autowired private BlogService blogService; @Autowired private TypeService typeService; @Autowired private TagService tagService; @GetMapping("/blogs") public String list(@PageableDefault(size = 10, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable, BlogQuery blog, Model model) { model.addAttribute("types", typeService.listType()); model.addAttribute("page", blogService.listBlog(pageable, blog)); return "/admin/blogs"; } @PostMapping("/blogs/search") public String search(@PageableDefault(size = 10, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable, BlogQuery blog, Model model) { model.addAttribute("page", blogService.listBlog(pageable, blog)); return "/admin/blogs :: blogList"; } @GetMapping("/blogs/input") public String input(Model model) { setTypeAndTag(model); model.addAttribute("blog", new Blog()); return "/admin/blogs-input"; } @GetMapping("/blogs/{id}/input") public String editInput(@PathVariable Long id, Model model) { setTypeAndTag(model); Blog blog = blogService.getBlog(id); blog.initTagIds(); model.addAttribute("blog",blog); return "/admin/blogs-input"; } private void setTypeAndTag(Model model) { model.addAttribute("types", typeService.listType()); model.addAttribute("tags", tagService.listTag()); } @PostMapping("/blogs") public String post(Blog blog, RedirectAttributes attributes, HttpSession session) { blog.setUser((User) session.getAttribute("user")); blog.setType(blog.getType()); blog.setTags(tagService.listTag(blog.getTagIds())); Blog b; if(blog.getId() == null) { b = blogService.saveBlog(blog); }else { b = blogService.updateBlog(blog.getId(), blog); } if (b == null){ attributes.addFlashAttribute("message","操作失败"); }else { attributes.addFlashAttribute("message","操作成功"); } return "redirect:/admin/blogs"; } @GetMapping("/blogs/{id}/delete") public String delete(@PathVariable Long id, RedirectAttributes attributes) { blogService.deleteBlog(id); attributes.addFlashAttribute("message", "删除成功"); return "redirect:/admin/blogs"; } }