基于javaweb+mysql的springboot个人博客系统(java+springboot+springsecurity+thymeleaf+html+mysql+redis)
运行环境
Java≥8、MySQL≥5.7
开发工具
eclipse/idea/myeclipse/sts等均可配置运行
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的SpringBoot个人博客系统(java+springboot+springsecurity+thymeleaf+html+mysql+redis)
项目介绍
本系统是一个个人博客的管理系统,用户可以注册账号并登陆系统查看发布的文章并进行阅读评论等 本系统主要有三种用户: 1、游客角色主要功能: 没有登陆的用户,可以查询文章,但是无法进行评论,系统中的所有文章可以通过内容搜索,可以通过分类搜索也可以通过标签就行搜索 2、注册用户主要功能 可以对所有的文章进行阅读以及评论等功能,可以对文章进行赞赏(支付宝或者微信付钱) 3、管理员主要功能: 拥有注册用户的所有权限,管理分类以及发布文章和管理标签等,友链管理,时间轴管理等
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 4.数据库:MySql 5.7版本; 5.是否Maven项目:是;
技术栈
SpringBoot+SpringSecurity+Mybatis+Mysql+Redis+Thymeleaf+JQuery
使用说明
- 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件; 2. 使用IDEA/Eclipse/MyEclipse导入项目,导入成功后请执行maven clean;maven install命令,然后运行; 3. 将项目中application.yml配置文件中的数据库配置改为自己的配置; 4. 运行项目,项目运行成功后,访问地址localhost:8080 管理员账号密码:zhangpeng98aliyun.com/mt2680324 用户账号密码:zhangpengaliyun.com/mt2680324
e.printStackTrace ();
attributes.addFlashAttribute ("message","服务器出现异常");
}
return "redirect:showAll";
}
}
@Controller
@RequestMapping("/admin/comment")
public class AdminCommentController {
@Autowired
private CommentService commentService;
@RequestMapping("/showAll")
public String showAll(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "6") Integer pageSize,
@RequestParam(name = "content", required = false, defaultValue = "") String content,
@RequestParam(name = "email", required = false, defaultValue = "") String email,
@RequestParam(name = "blogId", required = false, defaultValue = "-1") Long blogId,
Model model) {
if (blogId == -1){
blogId = null;
}
if (result.hasErrors ()){
return "admin/Tags-update";
}
Boolean update = TagService.update (tag);
if (update){
attributes.addFlashAttribute ("message","修改成功!");
} else {
attributes.addFlashAttribute ("message","修改失败!");
}
return "redirect:showAll";
}
@RequestMapping("/deleteById")
public String deleteById(Integer id, RedirectAttributes attributes){
//调用service层删除标签
Boolean aBoolean = TagService.deleteById (id);
if (aBoolean){
attributes.addFlashAttribute ("message","删除成功!");
} else {
attributes.addFlashAttribute ("message","删除失败,有博客属于该标签,不能删除!");
}
return "redirect:showAll";
}
}
@Controller
return "blog";
}
@RequestMapping("/getHotBlogs")
public String getHotBlogs(Model model){
List<Blog> blogs = blogService.selectHotBlogs (); //根据查看的次数降序获取4个
model.addAttribute ("blogs",blogs);
return "commons :: hotBlogs";
}
}
@Controller
@RequestMapping("/admin/type")
public class AdminTypeController {
@Autowired
private TypeService typeService;
@RequestMapping("/showAll")
public ModelAndView showAll(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize,
@RequestParam(name = "name", required = false, defaultValue = "") String name){
ModelAndView mv = new ModelAndView ();
//调用service层获取数据
List<Type> types = typeService.selectAllByLikeName (pageNum, pageSize, name);
//使用pageInfo包装查询后的结果,封装了详细的查询数据,其中参数5是页码导航连续显示的页数
PageInfo<Type> pageInfo = new PageInfo<> (types,5);
mv.addObject ("pageInfo",pageInfo);
@Controller
@RequestMapping("/admin/time")
public class AdminTimeController {
@Autowired
private TimeService timeService;
@RequestMapping("/showAll")
public String showAll(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize, Model model){
show (pageNum, pageSize, model);
return "admin/times";
}
public void show(Integer pageNum, Integer pageSize, Model model){
List<Time> times = timeService.selectAll (pageNum, pageSize);
PageInfo<Time> pageInfo = new PageInfo<> (times, 8);
model.addAttribute ("pageInfo", pageInfo);
}
@RequestMapping("/showAll/search")
public String search(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize, Model model){
show (pageNum, pageSize, model);
return "admin/times :: timeList";
}
@RequestMapping("/toAdd")
public String toAdd(){
return "admin/times-input";
}
@RequestMapping("/add")
public String add(Time time, RedirectAttributes attributes){
time.setCreateTime (new Date ());
try {
timeService.save (time);
attributes.addFlashAttribute ("message","添加成功!");
} catch (Exception e) {
e.printStackTrace ();
attributes.addFlashAttribute ("message","服务器出现异常");
}
return "redirect:showAll";
}
@RequestMapping("/toUpdate")
@RequestMapping("/showAll/search")
public String search(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "6") Integer pageSize,
@RequestParam(name = "nickname", required = false, defaultValue = "") String nickname, Model model) {
show (pageNum, pageSize, nickname, model);
return "admin/syslogs :: syslogList";
}
@RequestMapping("/deleteById")
public String deleteById(String id, RedirectAttributes attributes) {
try {
sysLogService.delete (id);
attributes.addFlashAttribute ("message", "删除成功!");
} catch (Exception e) {
attributes.addFlashAttribute ("message", "删除失败,服务器异常!");
e.printStackTrace ();
}
return "redirect:showAll";
}
@RequestMapping("/deleteBySelect")
public String deleteBySelect(@RequestParam(name = "ids") List<String> ids, RedirectAttributes attributes) {
try {
sysLogService.deleteSelect (ids);
attributes.addFlashAttribute ("message", "删除成功!");
} catch (Exception e) {
attributes.addFlashAttribute ("message", "删除失败,服务器异常!");
e.printStackTrace ();
}
return "redirect:showAll";
}
}
user.setHeadPortrait (uploadPath);
//改变数据库中的地址
userService.updateHeadPortrait (user.getId (), user.getHeadPortrait ());
if (!oldPath.contains ("default.jpg")) { //不删除默认头像
//更换成功后删除之前的头像
File file1 = new File (oldPath);
if (file1.exists ()) {
file1.delete ();
}
}
} catch (IOException e) {
e.printStackTrace ();
map.put ("code", 1);
}
return map;
}
//注册
@ResponseBody
@RequestMapping("/register")
public Map<String, Object> register(UserInfo userInfo, HttpServletRequest request) {
//用于存储返回响应的信息
Map<String, Object> map = new HashMap<> ();
userInfo.setCreateTime (new Date ());
//默认头像
userInfo.setHeadPortrait ("/upload/default.jpg");
userInfo.setStatus (true);
userInfo.setUpdateTime (new Date ());
boolean register = userService.register (userInfo);
if (register) {
// String message = "你好," + userInfo.getNickname () + "! <a href='http://59.110.60.4:80/user/active?email=" + userInfo.getEmail () + "'>点击激活</a>";
// SendEmailUtil.sendMessage (userInfo.getEmail (), message);
map.put ("flag", true);
} else {
map.put ("flag", false);
map.put ("reg_error", "邮箱已存在");
}
return map;
}
@Controller
@RequestMapping("/front/type")
public class FrontTypeController {
@Autowired
private TypeService typeService;
@Autowired
private BlogService blogService;
@RequestMapping("/showAll")
public String showAll(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize ,
@RequestParam(name = "id", required = false, defaultValue = "-1")Integer id, Model model){
List<Type> types = typeService.selectAllTypesWithCount (); //获取所有类别按照其下面的博客数量排序
model.addAttribute ("types",types);
if (id == -1){
id = types.get (0).getId ();
}
model.addAttribute ("typeId",id);
PageInfo<Blog> pageInfo = blogService.selectByTypeId (pageNum, pageSize, id);
model.addAttribute ("pageInfo",pageInfo);
return "types";
}
@RequestMapping("/showAll/search")
public String search(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize ,
@RequestParam(name = "id", required = false, defaultValue = "-1")Integer id, Model model){
model.addAttribute ("typeId",id);
PageInfo<Blog> pageInfo = blogService.selectByTypeId (pageNum, pageSize, id);
model.addAttribute ("pageInfo",pageInfo);
return "types :: blogList";
}
public void show(Integer pageNum, Integer pageSize, String email, Model model){
List<UserInfo> userInfos = userService.selectAll (pageNum, pageSize, email);
PageInfo<UserInfo> pageInfo = new PageInfo<> (userInfos,8);
model.addAttribute ("pageInfo",pageInfo);
model.addAttribute ("email",email);
}
@RequestMapping("/showAll/search")
public String search(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "2") Integer pageSize,
@RequestParam(name = "email", required = false, defaultValue = "") String email, Model model) {
show (pageNum, pageSize, email, model);
return "admin/users :: userList";
}
@RequestMapping("/updateStatus")
public String updateStatus(String email, RedirectAttributes attributes) {
UserInfo userInfo = userService.findByEmail (email);
Boolean status = userInfo.getStatus ();
try {
userService.updateStatus (email, !status);
attributes.addFlashAttribute ("message","状态修改成功!");
} catch (Exception e) {
attributes.addFlashAttribute ("message","状态修改失败,服务器异常!");
e.printStackTrace ();
}
return "redirect:showAll";
}
}
ModelAndView mv = new ModelAndView ();
//调用service层获取数据
List<Tag> tags = TagService.selectAllByLikeName (pageNum, pageSize, name);
//使用pageInfo包装查询后的结果,封装了详细的查询数据,其中参数5是页码导航连续显示的页数
PageInfo<Tag> pageInfo = new PageInfo<> (tags,5);
mv.addObject ("pageInfo",pageInfo);
mv.addObject ("name",name);
mv.setViewName ("admin/tags");
return mv;
}
@RequestMapping("/toAdd")
public String toAdd(Model model){
model.addAttribute ("tag",new Tag ());
return "admin/tags-input";
}
@RequestMapping("/add")
public String add(@Valid Tag tag, BindingResult result, RedirectAttributes attributes){
Tag tag1 = TagService.selectByName (tag.getName ());
if (tag1 != null){
result.rejectValue ("name","nameError","不能添加重复的标签名称");
}
if (result.hasErrors ()){
return "admin/Tags-input";
}
//调用service层保存标签
Boolean save = TagService.save (tag);
if (save){
attributes.addFlashAttribute ("message","添加成功!");
} else {
attributes.addFlashAttribute ("message","添加失败!");
}
return "redirect:showAll";
}
message.setUserInfo (userInfo);
message.setCreateTime (new Date ());
if (message.getParentMessage ().getId () == -1) {
message.getParentMessage ().setId (null);
}
messageService.saveMessage (message);
return "redirect:showAllMessages";
}
@RequestMapping("/showAllMessages")
public String showAllMessages(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "6") Integer pageSize,
Model model) {
showAll (pageNum, pageSize, model);
return "messages :: messageList";
}
}
@Component
public class ImageCodeAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Override
@RequestMapping("/updateNickname")
@ResponseBody
public Map<String, Object> updateNickname(String nickname){
Map<String, Object> map = new HashMap<> ();
UserInfo user = (UserInfo) SecurityContextHolder.getContext ().getAuthentication ().getPrincipal ();
Long id = user.getId ();
try {
userService.updateNickname(id, nickname);
user.setNickname (nickname);
map.put ("flag",true);
map.put ("msg","修改成功");
} catch (Exception e) {
map.put ("flag",false);
map.put ("msg","修改失败!服务器异常");
e.printStackTrace ();
}
return map;
}
//去更新密码页面
@RequestMapping("/toUpdatePassword")
public String toUpdatePassword(){
return "user/update-password";
}
//更新密码
@RequestMapping("/updatePassword")
@ResponseBody
public Map<String, Object> updatePassword(String password){
Map<String, Object> map = new HashMap<> ();
UserInfo user = (UserInfo) SecurityContextHolder.getContext ().getAuthentication ().getPrincipal ();
Long id = user.getId ();
try {
userService.updatePassword (id, password);
user = null;
map.put ("flag",true);
@Aspect
@Component
public class BlogAspectLog {
@Autowired
private SysLogService sysLogService;
private Date visitTime; //访问时间
private Class clazz; //访问的类
private Method method; //访问的方法
@Pointcut("execution(* com.zp.blog.web.*.*.*(..)) && !execution(* com.zp.blog.web.back.AdminSysLogController.*(..)) && !execution(* com.zp.blog.web.comment.*.*(..))")
public void pt() {
}
@Before("pt()")
public void doBefore(JoinPoint joinPoint) throws NoSuchMethodException {
visitTime = new Date (); //获取访问时间
clazz = joinPoint.getTarget ().getClass (); //获取访问的类
String methodName = joinPoint.getSignature ().getName (); //获取访问的方法的名称
//获取方法参数
Object[] args = joinPoint.getArgs ();
//通过反射获取Method
if (args == null || args.length == 0) {
method = clazz.getMethod (methodName); //获取无参的方法
} else {
Class[] classes = new Class[args.length];
@RequestMapping("/register")
public Map<String, Object> register(UserInfo userInfo, HttpServletRequest request) {
//用于存储返回响应的信息
Map<String, Object> map = new HashMap<> ();
userInfo.setCreateTime (new Date ());
//默认头像
userInfo.setHeadPortrait ("/upload/default.jpg");
userInfo.setStatus (true);
userInfo.setUpdateTime (new Date ());
boolean register = userService.register (userInfo);
if (register) {
// String message = "你好," + userInfo.getNickname () + "! <a href='http://59.110.60.4:80/user/active?email=" + userInfo.getEmail () + "'>点击激活</a>";
// SendEmailUtil.sendMessage (userInfo.getEmail (), message);
map.put ("flag", true);
} else {
map.put ("flag", false);
map.put ("reg_error", "邮箱已存在");
}
return map;
}
//邮箱激活
@RequestMapping("/active")
public String active(String email, RedirectAttributes attributes) {
UserInfo userInfo = userService.findByEmail (email);
Boolean status = userInfo.getStatus ();
try {
userService.updateStatus (email, !status);
attributes.addFlashAttribute ("flag", true);
attributes.addFlashAttribute ("msg", "激活成功!");
} catch (Exception e) {
e.printStackTrace ();
attributes.addFlashAttribute ("flag", false);
attributes.addFlashAttribute ("msg", "激活失败!服务器异常");
}
return "redirect:login";
}
//去忘记密码页面
@RequestMapping("/forget")
public String forget() {
return "user/forget";
}
@RequestMapping("/forget/sendCode")
@ResponseBody
public Map<String, Object> sendCode(String email, Model model) {
Map<String, Object> map = new HashMap<> ();
//生成6位激活码
String activeCode = RandomUtil.randomString (6);
@RequestParam(name = "pageSize", required = false, defaultValue = "6") Integer pageSize,
@RequestParam(name = "content", required = false, defaultValue = "") String content,
@RequestParam(name = "email", required = false, defaultValue = "") String email,
Model model) {
show (pageNum, pageSize, content, email, model);
return "admin/messages :: messageList";
}
@RequestMapping("/deleteById")
public String deleteById(Integer id, RedirectAttributes attributes){
try {
messageService.deleteById(id);
attributes.addFlashAttribute ("message","删除成功!");
} catch (Exception e) {
attributes.addFlashAttribute ("message","删除失败,服务器异常!");
e.printStackTrace ();
}
return "redirect:showAll";
}
}
@Controller
@RequestMapping("/admin/syslog")
public class AdminSysLogController {
@Autowired
private TypeService typeService;
@RequestMapping("/showAll")
public ModelAndView showAll(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize,
@RequestParam(name = "name", required = false, defaultValue = "") String name){
ModelAndView mv = new ModelAndView ();
//调用service层获取数据
List<Type> types = typeService.selectAllByLikeName (pageNum, pageSize, name);
//使用pageInfo包装查询后的结果,封装了详细的查询数据,其中参数5是页码导航连续显示的页数
PageInfo<Type> pageInfo = new PageInfo<> (types,5);
mv.addObject ("pageInfo",pageInfo);
mv.addObject ("name",name);
mv.setViewName ("admin/types");
return mv;
}
@RequestMapping("/toAdd")
public String toAdd(Model model){
model.addAttribute ("type",new Type ());
return "admin/types-input";
}
@RequestMapping("/add")
public String add(@Valid Type type, BindingResult result, RedirectAttributes attributes){
Type type1 = typeService.selectByName (type.getName ());
if (type1 != null){
result.rejectValue ("name","nameError","不能添加重复的类别名称");
}
if (result.hasErrors ()){
return "admin/types-input";
}
//调用service层保存类别
Boolean save = typeService.save (type);
public String search(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "6") Integer pageSize,
@RequestParam(name = "content", required = false, defaultValue = "") String content,
@RequestParam(name = "email", required = false, defaultValue = "") String email,
@RequestParam(name = "blogId", required = false, defaultValue = "-1") Long blogId,
Model model) {
if (blogId == -1){
blogId = null;
}
show (pageNum, pageSize, content, email, blogId, model);
return "admin/comments :: commentList";
}
@RequestMapping("/deleteById")
public String deleteById(Integer id, RedirectAttributes attributes){
try {
commentService.deleteById(id);
attributes.addFlashAttribute ("message","删除成功!");
} catch (Exception e) {
attributes.addFlashAttribute ("message","删除失败,服务器异常!");
e.printStackTrace ();
}
return "redirect:showAll";
}
}
@Controller
@RequestMapping("/admin/message")
public class AdminMessageController {
@Autowired
private MessageService messageService;
@RequestMapping("/showAll")
}
@RequestMapping("/getHotBlogs")
public String getHotBlogs(Model model){
List<Blog> blogs = blogService.selectHotBlogs (); //根据查看的次数降序获取4个
model.addAttribute ("blogs",blogs);
return "commons :: hotBlogs";
}
}
@Controller
@RequestMapping("/admin/type")
public class AdminTypeController {
@Autowired
private TypeService typeService;
@RequestMapping("/showAll")
public ModelAndView showAll(@RequestParam(name = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "5") Integer pageSize,
@RequestParam(name = "name", required = false, defaultValue = "") String name){
ModelAndView mv = new ModelAndView ();
//调用service层获取数据
List<Type> types = typeService.selectAllByLikeName (pageNum, pageSize, name);
//使用pageInfo包装查询后的结果,封装了详细的查询数据,其中参数5是页码导航连续显示的页数
PageInfo<Type> pageInfo = new PageInfo<> (types,5);
mv.addObject ("pageInfo",pageInfo);
mv.addObject ("name",name);
mv.setViewName ("admin/types");
return mv;
}
@RequestMapping("/toAdd")