基于javaweb+mysql的springboot简单博客管理系统(java+springboot+html+maven+mysql)
私信源码获取及调试交流
运行环境
Java≥8、MySQL≥5.7
开发工具
eclipse/idea/myeclipse/sts等均可配置运行
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的SpringBoot简单博客管理系统(java+springboot+html+maven+mysql)
项目介绍
本项目为前后台管理系统,包括博主与游客两种角色; 博主角色包含以下功能: 博主登录,发博客,博主可以删除博客等功能。 游客角色包含以下功能: 首页,查看博客,添加评论,搜索-标签筛选等功能。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
5.数据库:MySql 5.7版本;
技术栈
-
后端:SpringBoot
-
前端:HTML+CSS+JavaScript+jsp
使用说明
- 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件; 2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行; 3. 将项目中application.yml配置文件中的数据库配置改为自己的配置; 4. 运行项目,输入localhost:8080/ 登录
public Message() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Boolean getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(Boolean deleteFlag) {
this.deleteFlag = deleteFlag;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@GetMapping("/createBlog")
public String createBlog(HttpServletRequest request) {
return "create.html";
}
@PostMapping("/saveBlog")
public String saveBlog(
Blog blog,
HttpServletRequest request) {
blogService.saveBlog(blog);
return "redirect:/";
}
@PostMapping("/saveMessage")
public String saveMessage(
Message message,
HttpServletRequest request) {
blogService.saveMessage(message);
return "redirect:/detail?id=" + message.getBlogId();
}
@GetMapping("/logout")
public String logout(HttpServletRequest request) {
request.getSession().removeAttribute("user");
return "redirect:/";
}
@GetMapping("/login")
public String login(@RequestParam(required = false) String userName,
@RequestParam(required = false) String password,
HttpServletRequest request) {
if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)) {
return "login.html";
}
//进行登录业务
//根据用户名密码查询用户
User user = blogService.login(userName, password);
private UserDao userDao;
@Override
public PageQuery<Blog> pageBlog(long pageNumber, long pageSize, String keyword, String category) {
LambdaQuery<Blog> query = blogDao.createLambdaQuery()
.andEq(Blog::getDeleteFlag, false);
if (!StringUtils.isEmpty(keyword)) {
query.andLike(Blog::getTitle, "%" + keyword.trim() + "%");
}
if (!StringUtils.isEmpty(category)) {
query.andEq(Blog::getCategory, category);
}
if (pageNumber > 0 && pageSize > 0) {
return query.desc(Blog::getCreateTime).page(pageNumber, pageSize);
}
return null;
}
@Override
public PageQuery<Message> pageMsg(Long blogId, long pageNumber, long pageSize) {
if (pageNumber < 1 || pageSize < 1 || blogId == null) {
return null;
}
return messageDao.createLambdaQuery()
.andEq(Message::getBlogId, blogId)
.andEq(Message::getDeleteFlag, false)
.desc(Message::getCreateTime)
.page(pageNumber, pageSize);
}
@Override
public Blog getBlogById(Long blogId) {
return blogDao.createLambdaQuery().andEq(Blog::getId, blogId).single();
}
@Override
public void saveMessage(Message message) {
Date now = new Date();
message.setCreateTime(now);
message.setUpdateTime(now);
message.setDeleteFlag(false);
messageDao.createLambdaQuery().insert(message);
}
@Override
public void saveBlog(Blog blog) {
Date now = new Date();
blog.setCreateTime(now);
blog.setUpdateTime(now);
blog.setDeleteFlag(false);
blogDao.createLambdaQuery().insertSelective(blog);
}
.andEq(User::getUserName, userName)
.andEq(User::getPassword, password)
.andEq(User::getDeleteFlag, false)
.single();
}
@Override
public void deleteBlog(long id) {
blogDao.deleteById(id);
}
}
@Configuration
public class BeetlConfig {
//模板根目录 ,比如 "templates"
@Value("${beetl.templatesPath}") String templatesPath;
@Value("${blog.title}") String title;
@Bean
public GroupTemplate getGroupTemplate(BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
GroupTemplate gt = beetlGroupUtilConfiguration.getGroupTemplate();
Map<String,Object> shared = new HashMap<>();
shared.put("blogSiteTitle", title);
shared.put("blogCreateUser", "Gavin");
gt.setSharedVars(shared);
return gt;
}
@Bean
public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() {
private Date updateTime;
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(Integer deleteFlag) {
this.deleteFlag = deleteFlag;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
Long thM = date.getTime() + (30*60*1000);
Long oneH = date.getTime() + (60*60*1000);
if(now.getTime() < fiveM){
return "刚刚";
}
if(now.getTime() < thM){
return "半小时前";
}
if(now.getTime() < oneH){
return "一小时前";
}
SimpleDateFormat sdf = new SimpleDateFormat(objects[1].toString());
return sdf.format(date);
}
}
public interface BlogService {
PageQuery<Blog> pageBlog(long pageNumber, long pageSize, String keyword,String category);
/***
* 查询留言内容
* @param blogId
* @param pageNumber
* @param pageSize
* @return
*/
PageQuery<Message> pageMsg(Long blogId, long pageNumber, long pageSize);
Blog getBlogById(Long blogId);
void saveMessage(Message message);
/***
* 保存博客
* @param blog
*/
void saveBlog(Blog blog);
List<String> listCategory();
User login(String userName, String password);
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
<span class="meta">${@com.ibeetl.blog.function.PrintTimeUtil.printTime(page.list[i].createTime,"yyyy-MM-dd HH:mm:ss")}</span>
<hr>
</header>
</article>
</div>
<%if((i+1) < page.list.~size){%>
<div class="col-md-6 col-sm-6">
<article class=" blog-teaser">
<header>
<img src="${page.list[i+1].img}" alt="">
<h3><a href="${ctxPath}/detail?id=${page.list[i].id!}">
<%
title = page.list[i+1].title;
if(isNotEmpty(title)&&strutil.length(title)>11){%>
${strutil.subStringTo(title,0,11)}...
<%}else{%>
${title!"无标题"}
<%}%>
</a></h3>
<span class="meta">
${@com.ibeetl.blog.function.PrintTimeUtil.printTime(page.list[i+1].createTime,"yyyy-MM-dd HH:mm:ss")}</span>
<hr>
</header>
</article>
</div>
<%}%>
</div>
<%}%>
<#page page="${page}" condition='${"&keyword="+keyword!+"&category="+category!}'/>
<% } %>
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="Flat Dark Web Login Form Responsive Templates, Iphone Widget Template, Smartphone login forms,Login form, Widget Template, Responsive Templates, a Ipad 404 Templates, Flat Responsive Templates" />
<link href="${ctxPath}/css/login_style.css" rel='stylesheet' type='text/css' />
</head>
<body>
<script>$(document).ready(function(c) {
$('.close').on('click', function(c){
$('.login-form').fadeOut('slow', function(c){
$('.login-form').remove();
}
public interface BlogDao extends BaseDao<Blog> {
}
public interface UserDao extends BaseDao<User> {
}
<%
layout("/common/layout.html",{title:"首页"}){
%>
<% for(var i = 0;i< page.list.~size;i=i+2){%>
<div class="row">
<div class="col-md-6 col-sm-6">
<article class=" blog-teaser">
<header>
<img src="${page.list[i].img}" alt="">
<h3><a href="${ctxPath}/detail?id=${page.list[i].id!}">
<%
var title = page.list[i].title;
if(isNotEmpty(title)&&strutil.length(title)>11){%>
${strutil.subStringTo(title,0,11)}...
<%}else{%>
${title!"无标题"}
<%}%>
</a></h3>
<span class="meta">${@com.ibeetl.blog.function.PrintTimeUtil.printTime(page.list[i].createTime,"yyyy-MM-dd HH:mm:ss")}</span>
<hr>
</header>
</article>
</div>
<%if((i+1) < page.list.~size){%>
<div class="col-md-6 col-sm-6">
<article class=" blog-teaser">
<header>
<img src="${page.list[i+1].img}" alt="">
<h3><a href="${ctxPath}/detail?id=${page.list[i].id!}">
<%
<% for(var i = 0;i< page.list.~size;i=i+2){%>
<div class="row">
<div class="col-md-6 col-sm-6">
<article class=" blog-teaser">
<header>
<img src="${page.list[i].img}" alt="">
<h3><a href="${ctxPath}/detail?id=${page.list[i].id!}">
<%
var title = page.list[i].title;
if(isNotEmpty(title)&&strutil.length(title)>11){%>
${strutil.subStringTo(title,0,11)}...
<%}else{%>
${title!"无标题"}
<%}%>
</a></h3>
<span class="meta">${@com.ibeetl.blog.function.PrintTimeUtil.printTime(page.list[i].createTime,"yyyy-MM-dd HH:mm:ss")}</span>
<hr>
</header>
</article>
</div>
<%if((i+1) < page.list.~size){%>
<div class="col-md-6 col-sm-6">
<article class=" blog-teaser">
<header>
<img src="${page.list[i+1].img}" alt="">
<h3><a href="${ctxPath}/detail?id=${page.list[i].id!}">
<%
title = page.list[i+1].title;
if(isNotEmpty(title)&&strutil.length(title)>11){%>
${strutil.subStringTo(title,0,11)}...
<%}else{%>
${title!"无标题"}
<%}%>
</a></h3>
<span class="meta">
${@com.ibeetl.blog.function.PrintTimeUtil.printTime(page.list[i+1].createTime,"yyyy-MM-dd HH:mm:ss")}</span>
<hr>
</header>
</article>
BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
//获取Spring Boot 的ClassLoader
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(loader==null){
loader = BeetlConfig.class.getClassLoader();
}
ClasspathResourceLoader cploder = new ClasspathResourceLoader(loader,
templatesPath);
beetlGroupUtilConfiguration.setResourceLoader(cploder);
beetlGroupUtilConfiguration.init();
//如果使用了优化编译器,涉及到字节码操作,需要添加ClassLoader
beetlGroupUtilConfiguration.getGroupTemplate().setClassLoader(loader);
return beetlGroupUtilConfiguration;
}
@Bean(name = "beetlViewResolver")
public BeetlSpringViewResolver getBeetlSpringViewResolver(BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
beetlSpringViewResolver.setOrder(0);
beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
return beetlSpringViewResolver;
}
}
@Table(name = "blog")
public class Blog {
private Long id;
private String content;
private Boolean deleteFlag;
private String img;
private String category;
private String title;
private Date createTime;
private Date updateTime;
public Blog() {
Long oneH = date.getTime() + (60*60*1000);
if(now.getTime() < fiveM){
return "刚刚";
}
if(now.getTime() < thM){
return "半小时前";
}
if(now.getTime() < oneH){
return "一小时前";
}
SimpleDateFormat sdf = new SimpleDateFormat(objects[1].toString());
return sdf.format(date);
}
}
public interface BlogService {
PageQuery<Blog> pageBlog(long pageNumber, long pageSize, String keyword,String category);
/***
* 查询留言内容
* @param blogId
* @param pageNumber
* @param pageSize
* @return
*/
PageQuery<Message> pageMsg(Long blogId, long pageNumber, long pageSize);
Blog getBlogById(Long blogId);
void saveMessage(Message message);
/***
* 保存博客
* @param blog
*/
void saveBlog(Blog blog);
List<String> listCategory();
User login(String userName, String password);
void deleteBlog(long id);
}
@Service
public class BlogServiceImpl implements BlogService {
@Autowired
private BlogDao blogDao;
@Autowired
private MessageDao messageDao;
@Autowired
private UserDao userDao;
@Override
public PageQuery<Blog> pageBlog(long pageNumber, long pageSize, String keyword, String category) {
LambdaQuery<Blog> query = blogDao.createLambdaQuery()
.andEq(Blog::getDeleteFlag, false);
if (!StringUtils.isEmpty(keyword)) {
query.andLike(Blog::getTitle, "%" + keyword.trim() + "%");
}
if (!StringUtils.isEmpty(category)) {
query.andEq(Blog::getCategory, category);
}
if (pageNumber > 0 && pageSize > 0) {
return query.desc(Blog::getCreateTime).page(pageNumber, pageSize);
}
return null;
}
@Override
public PageQuery<Message> pageMsg(Long blogId, long pageNumber, long pageSize) {
if (pageNumber < 1 || pageSize < 1 || blogId == null) {
return null;
@Configuration
public class DBConfig {
@Bean(name = "datasource")
public DataSource datasource(Environment env) {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
ds.setUsername(env.getProperty("spring.datasource.username"));
ds.setPassword(env.getProperty("spring.datasource.password"));
ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
return ds;
}
}
public class PrintTimeUtil {
public static String printTime(Date date,String format){
Date now = new Date();
Long fiveM = date.getTime() + (5*60*1000);
Long thM = date.getTime() + (30*60*1000);
Long oneH = date.getTime() + (60*60*1000);
if(now.getTime() < fiveM){
return "刚刚";
}
if(now.getTime() < thM){
return "半小时前";
}
if(now.getTime() < oneH){
return "一小时前";
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
}
public interface MessageDao extends BaseDao<Message> {
try {
System.setProperty("java.awt.headless", "false");
java.awt.Desktop.getDesktop().browse(new java.net.URI(url));//自动打开浏览器
} catch (Exception e) {
System.out.println("自动打开浏览器失败");
}
}
}
public class PrintTime implements Function {
@Override
public String call(Object[] objects, Context context) {
Date date = (Date) objects[0];
Date now = new Date();
Long fiveM = date.getTime() + (5*60*1000);
Long thM = date.getTime() + (30*60*1000);
Long oneH = date.getTime() + (60*60*1000);
if(now.getTime() < fiveM){
return "刚刚";
}
if(now.getTime() < thM){
return "半小时前";
}
if(now.getTime() < oneH){
return "一小时前";
}
SimpleDateFormat sdf = new SimpleDateFormat(objects[1].toString());
return sdf.format(date);
}
}
this.img = img;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
@Table(name = "message")
public class Message {
private Long id;
private Long blogId;
private Boolean deleteFlag;
private String content;
private String nickName;
private Date createTime;
<%}else{%>
${title!"无标题"}
<%}%>
</a></h3>
<span class="meta">
${@com.ibeetl.blog.function.PrintTimeUtil.printTime(page.list[i+1].createTime,"yyyy-MM-dd HH:mm:ss")}</span>
<hr>
</header>
</article>
</div>
<%}%>
</div>
<%}%>
<#page page="${page}" condition='${"&keyword="+keyword!+"&category="+category!}'/>
<% } %>
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="Flat Dark Web Login Form Responsive Templates, Iphone Widget Template, Smartphone login forms,Login form, Widget Template, Responsive Templates, a Ipad 404 Templates, Flat Responsive Templates" />
<link href="${ctxPath}/css/login_style.css" rel='stylesheet' type='text/css' />
</head>
<body>
<script>$(document).ready(function(c) {
$('.close').on('click', function(c){
$('.login-form').fadeOut('slow', function(c){
$('.login-form').remove();
});
});
});
</script>
<!--SIGN UP-->
<h1>登录</h1>
<div class="login-form">
<div class="close" onclick="location.href='/'"> </div>
<div class="head-info">