Spring Boot技术栈博客企业前后端
(2-2 -用Gradle编译项目&)
2-2 -用Gradle编译项目&
gradle编译项目
(3-3 -编写程序代码及测试用例&)
3-3 -编写程序代码及测试用例&
Application.java
package com.waylau.spring.boot.blog;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
HelloController.java
package com.waylau.spring.boot.blog.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Hello World 控制器.
*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello World! Welcome to visit waylau.com!";
}
}
ApplicationTests.java
package com.waylau.spring.boot.blog;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Test
public void contextLoads() {
}
}
MainController.java
package com.waylau.spring.boot.blog.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.waylau.spring.boot.blog.domain.Authority;
import com.waylau.spring.boot.blog.domain.User;
import com.waylau.spring.boot.blog.service.AuthorityService;
import com.waylau.spring.boot.blog.service.UserService;
/**
* 主页控制器.
*/
@Controller
public class MainController {
private static final Long ROLE_USER_AUTHORITY_ID = 2L;
@Autowired
private UserService userService;
@Autowired
private AuthorityService authorityService;
@GetMapping("/")
public String root() {
return "redirect:/index";
}
@GetMapping("/index")
public String index() {
return "index";
}
/**
* 获取登录界面
* @return
*/
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/login-error")
public String loginError(Model model) {
model.addAttribute("loginError", true);
model.addAttribute("errorMsg", "登陆失败,账号或者密码错误!");
return "login";
}
@GetMapping("/register")
public String register() {
return "register";
}
/**
* 注册用户
* @param user
* @param result
* @param redirect
* @return
*/
@PostMapping("/register")
public String registerUser(User user) {
List authorities = new ArrayList();
authorities.add(authorityService.getAuthorityById(ROLE_USER_AUTHORITY_ID));
user.setAuthorities(authorities);
userService.saveUser(user);
return "redirect:/login";
}
@GetMapping("/search")
public String search() {
return "search";
}
}
application.properties
server.port=8080
debug=true
# THYMELEAF
spring.thymeleaf.encoding=UTF-8
# 热部署静态文件
spring.thymeleaf.cache=false
# 使用HTML5标准
spring.thymeleaf.mode=HTML5
# DataSource
spring.datasource.url=jdbc:mysql://localhost/blog?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
BlogController.java
package com.waylau.spring.boot.blog.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 主页控制器.
*
*/
@Controller
@RequestMapping("/blogs")
public class BlogController {
@GetMapping
public String listBlogs(@RequestParam(value="order",required=false,defaultValue="new") String order,
@RequestParam(value="tag",required=false) Long tag) {
System.out.print("order:" +order + ";tag:" +tag );
return "redirect:/index?order="+order+"&tag="+tag;
}
}
package com.waylau.spring.boot.blog.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.waylau.spring.boot.blog.vo.Menu;
/**
* 用户控制器.
*
*/
@Controller
@RequestMapping("/admins")
public class AdminController {
/**
* 获取后台管理主页面
* @return
*/
@GetMapping
public ModelAndView listUsers(Model model) {
List list = new ArrayList();
list.add(new Menu("用户管理", "/users"));
list.add(new Menu("角色管理", "/roles"));
list.add(new Menu("博客管理", "/blogs"));
list.add(new Menu("评论管理", "/commits"));
model.addAttribute("list", list);
return new ModelAndView("/admins/index", "model", model);
}
}
UserspaceController.java
restful请求url,requestParam
package com.waylau.spring.boot.blog.controller;
import java.util.List;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
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.data.domain.Sort.Direction;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.waylau.spring.boot.blog.domain.Blog;
import com.waylau.spring.boot.blog.domain.User;
import com.waylau.spring.boot.blog.service.BlogService;
import com.waylau.spring.boot.blog.service.UserService;
import com.waylau.spring.boot.blog.util.ConstraintViolationExceptionHandler;
import com.waylau.spring.boot.blog.vo.Response;
/**
* 用户主页空间控制器.
*
*/
@Controller
@RequestMapping("/u")
public class UserspaceController {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private UserService userService;
@Autowired
private BlogService blogService;
@GetMapping("/{username}")
public String userSpace(@PathVariable("username") String username, Model model) {
User user = (User)userDetailsService.loadUserByUsername(username);
model.addAttribute("user", user);
return "redirect:/u/" + username + "/blogs";
}
@GetMapping("/{username}/profile")
@PreAuthorize("authentication.name.equals(#username)")
public ModelAndView profile(@PathVariable("username") String username, Model model) {
User user = (User)userDetailsService.loadUserByUsername(username);
model.addAttribute("user", user);
return new ModelAndView("/userspace/profile", "userModel", model);
}
/**
* 保存个人设置
* @param user
* @param result
* @param redirect
* @return
*/
@PostMapping("/{username}/profile")
@PreAuthorize("authentication.name.equals(#username)")
public String saveProfile(@PathVariable("username") String username,User user) {
User originalUser = userService.getUserById(user.getId());
originalUser.setEmail(user.getEmail());
originalUser.setName(user.getName());
// 判断密码是否做了变更
String rawPassword = originalUser.getPassword();
PasswordEncoder encoder = new BCryptPasswordEncoder();
String encodePasswd = encoder.encode(user.getPassword());
boolean isMatch = encoder.matches(rawPassword, encodePasswd);
if (!isMatch) {
originalUser.setEncodePassword(user.getPassword());
}
userService.saveUser(originalUser);
return "redirect:/u/" + username + "/profile";
}
/**
* 获取编辑头像的界面
* @param username
* @param model
* @return
*/
@GetMapping("/{username}/avatar")
@PreAuthorize("authentication.name.equals(#username)")
public ModelAndView avatar(@PathVariable("username") String username, Model model) {
User user = (User)userDetailsService.loadUserByUsername(username);
model.addAttribute("user", user);
return new ModelAndView("/userspace/avatar", "userModel", model);
}
/**
* 保存头像
* @param username
* @param model
* @return
*/
@PostMapping("/{username}/avatar")
@PreAuthorize("authentication.name.equals(#username)")
public ResponseEntity saveAvatar(@PathVariable("username") String username, @RequestBody User user) {
String avatarUrl = user.getAvatar();
User originalUser = userService.getUserById(user.getId());
originalUser.setAvatar(avatarUrl);
userService.saveUser(originalUser);
return ResponseEntity.ok().body(new Response(true, "处理成功", avatarUrl));
}
@GetMapping("/{username}/blogs")
public String listBlogsByOrder(@PathVariable("username") String username,
@RequestParam(value="order",required=false,defaultValue="new") String order,
@RequestParam(value="category",required=false ) Long category,
@RequestParam(value="keyword",required=false,defaultValue="" ) String keyword,
@RequestParam(value="async",required=false) boolean async,
@RequestParam(value="pageIndex",required=false,defaultValue="0") int pageIndex,
@RequestParam(value="pageSize",required=false,defaultValue="10") int pageSize,
Model model) {
User user = (User)userDetailsService.loadUserByUsername(username);
model.addAttribute("user", user);
if (category != null) {
System.out.print("category:" +category );
System.out.print("selflink:" + "redirect:/u/"+ username +"/blogs?category="+category);
return "/u";
}
Page page = null;
if (order.equals("hot")) { // 最热查询
Sort sort = new Sort(Direction.DESC,"reading","comments","likes");
Pageable pageable = new PageRequest(pageIndex, pageSize, sort);
page = blogService.listBlogsByTitleLikeAndSort(user, keyword, pageable);
}
if (order.equals("new")) { // 最新查询
Pageable pageable = new PageRequest(pageIndex, pageSize);
page = blogService.listBlogsByTitleLike(user, keyword, pageable);
}
List list = page.getContent(); // 当前所在页面数据列表
model.addAttribute("order", order);
model.addAttribute("page", page);
model.addAttribute("blogList", list);
return (async==true?"/userspace/u :: #mainContainerRepleace":"/userspace/u");
}
/**
* 获取博客展示界面
* @param id
* @param model
* @return
*/
@GetMapping("/{username}/blogs/{id}")
public String getBlogById(@PathVariable("username") String username,@PathVariable("id") Long id, Model model) {
// 每次读取,简单的可以认为阅读量增加1次
blogService.readingIncrease(id);
boolean isBlogOwner = false;
// 判断操作用户是否是博客的所有者
if (SecurityContextHolder.getContext().getAuthentication() !=null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated()
&& !SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString().equals("anonymousUser")) {
User principal = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal !=null && username.equals(principal.getUsername())) {
isBlogOwner = true;
}
}
model.addAttribute("isBlogOwner", isBlogOwner);
model.addAttribute("blogModel",blogService.getBlogById(id));
return "/userspace/blog";
}
/**
* 删除博客
* @param id
* @param model
* @return
*/
@DeleteMapping("/{username}/blogs/{id}")
@PreAuthorize("authentication.name.equals(#username)")
public ResponseEntity deleteBlog(@PathVariable("username") String username,@PathVariable("id") Long id) {
try {
blogService.removeBlog(id);
} catch (Exception e) {
return ResponseEntity.ok().body(new Response(false, e.getMessage()));
}
String redirectUrl = "/u/" + username + "/blogs";
return ResponseEntity.ok().body(new Response(true, "处理成功", redirectUrl));
}
/**
* 获取新增博客的界面
* @param model
* @return
*/
@GetMapping("/{username}/blogs/edit")
public ModelAndView createBlog(Model model) {
model.addAttribute("blog", new Blog(null, null, null));
return new ModelAndView("/userspace/blogedit", "blogModel", model);
}
/**
* 获取编辑博客的界面
* @param model
* @return
*/
@GetMapping("/{username}/blogs/edit/{id}")
public ModelAndView editBlog(@PathVariable("username") String username,@PathVariable("id") Long id, Model model) {
model.addAttribute("blog", blogService.getBlogById(id));
return new ModelAndView("/userspace/blogedit", "blogModel", model);
}
/**
* 保存博客
* @param username
* @param blog
* @return
*/
@PostMapping("/{username}/blogs/edit")
@PreAuthorize("authentication.name.equals(#username)")
public ResponseEntity saveBlog(@PathVariable("username") String username, @RequestBody Blog blog) {
User user = (User)userDetailsService.loadUserByUsername(username);
blog.setUser(user);
try {
blogService.saveBlog(blog);
} catch (ConstraintViolationException e) {
return ResponseEntity.ok().body(new Response(false, ConstraintViolationExceptionHandler.getMessage(e)));
} catch (Exception e) {
return ResponseEntity.ok().body(new Response(false, e.getMessage()));
}
String redirectUrl = "/u/" + username + "/blogs/" + blog.getId();
return ResponseEntity.ok().body(new Response(true, "处理成功", redirectUrl));
}
}
AdminController.java
package com.waylau.spring.boot.blog.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.waylau.spring.boot.blog.vo.Menu;
/**
* 用户控制器.
*
*/
@Controller
@RequestMapping("/admins")
public class AdminController {
/**
* 获取后台管理主页面
* @return
*/
@GetMapping
public ModelAndView listUsers(Model model) {
List list = new ArrayList();
list.add(new Menu("用户管理", "/users"));
list.add(new Menu("角色管理", "/roles"));
list.add(new Menu("博客管理", "/blogs"));
list.add(new Menu("评论管理", "/commits"));
model.addAttribute("list", list);
return new ModelAndView("/admins/index", "model", model);
}
}
UserController.java
package com.waylau.spring.boot.blog.controller;
import java.util.ArrayList;
import java.util.List;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.waylau.spring.boot.blog.domain.Authority;
import com.waylau.spring.boot.blog.domain.User;
import com.waylau.spring.boot.blog.service.AuthorityService;
import com.waylau.spring.boot.blog.service.UserService;
import com.waylau.spring.boot.blog.util.ConstraintViolationExceptionHandler;
import com.waylau.spring.boot.blog.vo.Response;
/**
* 用户控制器.
*
*/
@RestController
@RequestMapping("/users")
@PreAuthorize("hasAuthority('ROLE_ADMIN')") // 指定角色权限才能操作方法
public class UserController {
@Autowired
private UserService userService;
@Autowired
private AuthorityService authorityService;
/**
* 查询所用用户
* @return
*/
@GetMapping
public ModelAndView list(@RequestParam(value="async",required=false) boolean async,
@RequestParam(value="pageIndex",required=false,defaultValue="0") int pageIndex,
@RequestParam(value="pageSize",required=false,defaultValue="10") int pageSize,
@RequestParam(value="name",required=false,defaultValue="") String name,
Model model) {
Pageable pageable = new PageRequest(pageIndex, pageSize);
Page page = userService.listUsersByNameLike(name, pageable);
List list = page.getContent(); // 当前所在页面数据列表
model.addAttribute("page", page);
model.addAttribute("userList", list);
return new ModelAndView(async==true?"users/list :: #mainContainerRepleace":"users/list", "userModel", model);
}
/**
* 获取 form 表单页面
* @param user
* @return
*/
@GetMapping("/add")
public ModelAndView createForm(Model model) {
model.addAttribute("user", new User(null, null, null, null));
return new ModelAndView("users/add", "userModel", model);
}
/**
* 新建用户
* @param user
* @param result
* @param redirect
* @return
*/
@PostMapping
public ResponseEntity create(User user, Long authorityId) {
List authorities = new ArrayList();
authorities.add(authorityService.getAuthorityById(authorityId));
user.setAuthorities(authorities);
if(user.getId() == null) {
user.setEncodePassword(user.getPassword()); // 加密密码
}else {
// 判断密码是否做了变更
User originalUser = userService.getUserById(user.getId());
String rawPassword = originalUser.getPassword();
PasswordEncoder encoder = new BCryptPasswordEncoder();
String encodePasswd = encoder.encode(user.getPassword());
boolean isMatch = encoder.matches(rawPassword, encodePasswd);
if (!isMatch) {
user.setEncodePassword(user.getPassword());
}else {
user.setPassword(user.getPassword());
}
}
try {
userService.saveUser(user);
} catch (ConstraintViolationException e) {
return ResponseEntity.ok().body(new Response(false, ConstraintViolationExceptionHandler.getMessage(e)));
}
return ResponseEntity.ok().body(new Response(true, "处理成功", user));
}
/**
* 删除用户
* @param id
* @return
*/
@DeleteMapping(value = "/{id}")
public ResponseEntity delete(@PathVariable("id") Long id, Model model) {
try {
userService.removeUser(id);
} catch (Exception e) {
return ResponseEntity.ok().body( new Response(false, e.getMessage()));
}
return ResponseEntity.ok().body( new Response(true, "处理成功"));
}
/**
* 获取修改用户的界面,及数据
* @param user
* @return
*/
@GetMapping(value = "edit/{id}")
public ModelAndView modifyForm(@PathVariable("id") Long id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return new ModelAndView("users/edit", "userModel", model);
}
}
MainController.java
package com.waylau.spring.boot.blog.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.waylau.spring.boot.blog.domain.Authority;
import com.waylau.spring.boot.blog.domain.User;
import com.waylau.spring.boot.blog.service.AuthorityService;
import com.waylau.spring.boot.blog.service.UserService;
/**
* 主页控制器.
*
*/
@Controller
public class MainController {
private static final Long ROLE_USER_AUTHORITY_ID = 2L;
@Autowired
private UserService userService;
@Autowired
private AuthorityService authorityService;
@GetMapping("/")
public String root() {
return "redirect:/index";
}
@GetMapping("/index")
public String index() {
return "index";
}
/**
* 获取登录界面
* @return
*/
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/login-error")
public String loginError(Model model) {
model.addAttribute("loginError", true);
model.addAttribute("errorMsg", "登陆失败,账号或者密码错误!");
return "login";
}
@GetMapping("/register")
public String register() {
return "register";
}
/**
* 注册用户
* @param user
* @param result
* @param redirect
* @return
*/
@PostMapping("/register")
public String registerUser(User user) {
List authorities = new ArrayList();
authorities.add(authorityService.getAuthorityById(ROLE_USER_AUTHORITY_ID));
user.setAuthorities(authorities);
userService.saveUser(user);
return "redirect:/login";
}
@GetMapping("/search")
public String search() {
return "search";
}
}
(13-2 -后台实现&)
13-2 -后台实现&
User.java JPA校验
package com.waylau.spring.boot.blog.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* User 实体
*
*/
@Entity // 实体
public class User implements UserDetails, Serializable {
private static final long serialVersionUID = 1L;
@Id // 主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
private Long id; // 用户的唯一标识
@NotEmpty(message = "姓名不能为空")
@Size(min=2, max=20)
@Column(nullable = false, length = 20) // 映射为字段,值不能为空
private String name;
@NotEmpty(message = "邮箱不能为空")
@Size(max=50)
@Email(message= "邮箱格式不对" )
@Column(nullable = false, length = 50, unique = true)
private String email;
@NotEmpty(message = "账号不能为空")
@Size(min=3, max=20)
@Column(nullable = false, length = 20, unique = true)
private String username; // 用户账号,用户登录时的唯一标识
@NotEmpty(message = "密码不能为空")
@Size(max=100)
@Column(length = 100)
private String password; // 登录时密码
@Column(length = 200)
private String avatar; // 头像图片地址
@ManyToMany(cascade = CascadeType.DETACH, fetch = FetchType.EAGER)
@JoinTable(name = "user_authority", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id"))
private List authorities;
protected User() { // JPA 的规范要求无参构造函数;设为 protected 防止直接使用
}
public User(String name, String email,String username,String password) {
this.name = name;
this.email = email;
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Collection
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?