【SpringBoot】JavaWeb博客系统

用户登录注册模块的实现【SpringBoot】JavaWeb博客系统——用户登录与注册

JavaWeb简易博客系统

这是一个简易的博客系统,是这学期JavaWeb的期末项目,相对于常用的博客系统而已,还有很多功能尚未完善,例如没有独立的权限管理模块,点赞,收藏,归档,分类、数据统计等功能(这些没完成的部分等课设的应该会视情况而去完善)。该博客系统实现的主要功能看下面的项目介绍。

项目简介

该博客系统前后大概花了十天左右的时间。说实话,写前端真的是一件令人头大的事,十天时间里面,有七天左右在写界面。而且在实现具体功能的时候,也总是在前端部分出现各种莫名奇妙的玄学Bug。

该博客系统主要有以下几个功能:

  1. 用户的登录与注册。
  2. 发表编辑修改博客。
  3. 查阅博客详情以及按关键字对博客标题进行模糊搜索。
  4. 对博客的评论,评论回复时的邮件提醒。
  5. 在留言板进行留言,或者删除留言,留言回复时的邮件提醒。
  6. 个人信息展示以及修改。
  7. 文件服务器,用于保存系统上传的图片等资源。
  8. 后台管理员管理用户,博客、评论、留言的信息。可以查询所有内容以及进行删除操作。

上述功能除了查阅博客详情,搜索博客以及留言板留言可以在游客状态(未登录状态)下进行访问,其余必须为登陆后的用户才有权限操作。

在这里插入图片描述

项目技术介绍

前端:Thymeleaf模板引擎、Semantic UI框架、Jquery框架以及editormd、simditor、cropper,prism,typo等插件

后端:Springboot、持久层采用Mybatis-Plus

数据库:MySQL

项目管理工具:Maven



  1. 使用Thymeleaf模板引擎对前端界面进行渲染,个人觉得使用JSP不利于前端的编写,因为JSP文件浏览器并不能对其渲染,而必须依托于服务器才行,导致有时候改了某些效果之后不方便立即查看。而thymleaf的话对网页整体是没有影响的,可以直接用浏览器打开显示。 除此之外使用Semantic UI实现页面的响应式布局。
  2. 为了保证数据的完整性,在用户注册、个人信息修改以及博客编辑上,采用了Semantic UI提供的api对表单进行校验。
  3. editormd为markdown编辑器插件,用于博客的编写。simditor为富文本编辑器插件用于评论、留言的编写。cropper图片剪切插件,用于剪切图片。prism、typo用于博客详情页面的布局。
  4. 后端使用SpringBoot自动装配web等运行环境,省去ssm框架一堆麻烦的配置。使用Mybatis-Plus 替代mybatis,MP实现了对单表的增删改查,分页等操作。在整个项目中,基本不需要写SQL,只要把查询条件封装好就行。
  5. 用AOP技术把URL请求的参数、方法名以及结果记录到日志中。
  6. 在编辑博客以及修改个人头像的时候,难免需要上传图片信息,所以基于Springboot框架单独实现了一个文件服务器,用于存储图片等资源。该服务器提供了三个API,分别用于editormd、simditor以及本系统的图片上传业务。具体实现可以参考上一篇博客【SpringBoot】如何优雅的实现跨服务器上传文件
  7. 还有一些java的api插件,用于发送邮件等。

数据库设计

在这里插入图片描述
在这里插入图片描述

留言模块的回复用如上图所示的层级关系展示,一条父留言为根节点,之后回复该留言,或者对该留言中的回复进行回复的留言都以兄弟节点的关系形式表示。所以上图的三条留言中,jiang留言(cid=1)的parentMessageId和replyMessageId都为null,因为它是作为根节点的。Jxj留言(cid=2)的parentMessageId和replyMessageId都为1,因为它回复的留言以及根留言都是(cid=1)这条留言。最后jiang4869的这条回复的parentMessageId和replyMessageId分别为(1,2),因为它回复的是jxj的留言,所以replyMessageId为2,它所在的根节点jiang的留言cid=1,所以parentMessageId=1。

项目效果展示

用户登录界面

在这里插入图片描述

用户注册界面

在这里插入图片描述
在这里插入图片描述

登录成功后的首页

在这里插入图片描述

博客列表

在这里插入图片描述

博客编辑界面

在这里插入图片描述

博客详情界面

在这里插入图片描述

个人信息界面

在这里插入图片描述

个人博客管理界面

在这里插入图片描述

个人信息修改界面

在这里插入图片描述

头像上传界面

在这里插入图片描述

留言板

在这里插入图片描述

后台管理界面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目搭建

pom文件的坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.jxj4869</groupId>
    <artifactId>blog</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>blog</name>
    <description>project for blog</description>

    <properties>
        <java.version>1.8</java.version>
        <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
        <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
    </properties>

    <dependencies>

        <!--aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--JDBC-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--jdbc驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <!--代码生成器插件-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.30</version>
        </dependency>

        <!--数据连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.8</version>
        </dependency>

        <!--邮件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>



<!--        &lt;!&ndash;shiro&ndash;&gt;-->
<!--        <dependency>-->
<!--            <groupId>org.apache.shiro</groupId>-->
<!--            <artifactId>shiro-spring</artifactId>-->
<!--            <version>1.4.2</version>-->
<!--        </dependency>-->


        <!--开发工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--日志-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>


        <!--文件上传插件-->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

        <!--Http工具-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.1</version>
        </dependency>



        <!--测试工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置文件

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost4:3306/blog?serverTimezone=UTC&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    initialization-mode: always
    #    schema:
    #      - classpath:sql/user.sql
    #      - classpath:sql/employee.sql
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500



#跨服务器上传文件的地址,与文件服务器的接口对应
file.upload.path.editormd=http://localhost:8888/fileupload/md/
file.upload.path.simditor=http://localhost:8888/fileupload/simditor/
file.upload.path=http://localhost:8888/fileupload/



#文件上传相关参数
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=300MB
spring.servlet.multipart.max-request-size=300MB


#邮件发送的配置
spring.mail.username=youremail
spring.mail.password=password
spring.mail.host=smtp.qq.com

#配置465端口,保证在服务器上正常使用
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.default-encoding=UTF-8
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.port=465
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback = false


#禁用thymeleaf缓存
spring.thymeleaf.cache=false



#开启对隐藏域方法的支持
spring.mvc.hiddenmethod.filter.enabled=true

配置类

DruidConfig.java

package cn.jxj4869.blog.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DruidConfig {

    @ConfigurationProperties("spring.datasource")

    @Bean
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }
}

MybatisPlusConfig.java

package cn.jxj4869.blog.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
}

log4j配置文件

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=log/log.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

SQL脚本

create database blog;
use blog;


create table `blog_user`
(
    `uid`        int           not null primary key auto_increment,
    `userName`   varchar(30)   not null unique,
    `nickName`   nvarchar(100) not null,
    `password` varchar(20) not null,
    `email`      nvarchar(100) unique not null,
    `avatar`     varchar(100)  not null,
    `qq`         varchar(13) default null,
    `createTime` datetime default now(),
    `updateTime` datetime default now()

) charset = utf8;


create table `blog_message`
(
    `mid`             int           not null primary key auto_increment,
    `uid`             int           default null,
    `createTime`      datetime      not null,
    `content`         nvarchar(500) not null,
    `parentMessageId` int  default null,
    `replyMessageId`  int  default null,
    `email`           varchar(30)   not null,
    `userName`        nvarchar(20)  not null,
    `remind`          bool default false,
    constraint foreign key (`uid`) references `blog_user` (`uid`) ON DELETE CASCADE ON UPDATE RESTRICT,
    constraint foreign key (`parentMessageId`) references `blog_message` (`mid`) ON DELETE CASCADE ON UPDATE RESTRICT,
    constraint foreign key (`replyMessageId`) references `blog_message` (`mid`) ON DELETE CASCADE ON UPDATE RESTRICT
) charset = utf8;

create table `blog_blogType`
(
    `id`       int           not null primary key auto_increment,
    `typeName` nvarchar(100) not null
) charset = utf8;



create table `blog_blog`
(

    `bid`          int           not null primary key auto_increment,
    `uid` int not null,
    `title`        nvarchar(200) not null,
    `content`      mediumblob default null,
    `summary`      nvarchar(300) not null,
    `firstPicture` varchar(500)  not null,
    `views`        int        default 0,
    `createTime`   datetime   default now(),
    `updateTime`   datetime   default now(),
    `published`    bool       default true,
    `isComment`    bool       default true,
    `typeId`       int        default null,
    constraint foreign key (`typeId`) references `blog_blogType` (`id`),
    constraint foreign key (`uid`) references `blog_user` (`uid`),
) charset = utf8;




create table `blog_comment`
(
    `cid`             int           not null primary key auto_increment,
    `uid`             int           not null,
    `bid`             int           not null,
    `createTime`      datetime      not null,
    `content`         nvarchar(500) not null,
    `parentCommentId` int  default null,
    `replyCommentId`  int  default null,
    `email`           varchar(30)   not null,
    `remind`          bool default false,
    constraint foreign key (`uid`) references `blog_user` (`uid`) ON DELETE CASCADE ON UPDATE RESTRICT,
    constraint foreign key (`parentCommentId`) references `blog_comment` (`cid`) ON DELETE CASCADE ON UPDATE RESTRICT,
    constraint foreign key (`replyCommentId`) references `blog_comment` (`cid`) ON DELETE CASCADE ON UPDATE RESTRICT,
    constraint foreign key (`bid`) references `blog_blog` (`bid`) ON DELETE CASCADE ON UPDATE RESTRICT

) charset = utf8;

create trigger tri_blogTypeDelete
    before delete
    on `blog_blogType`
    for each row
begin
    declare id int;
    select bt.id into id from blog_blogType bt where bt.id = old.id;
    update `blog_blog` set `typeid`=null where `blog_blog`.typeId = id;
end;

前端插件

均采用最新版本

在这里插入图片描述

文件服务器

部署在Linux系统下。

pom坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.jxj4869</groupId>
    <artifactId>fileuploadserver1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>fileuploadserver1</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置文件

# 文件上传位置  这里是路径是相对于项目而言,可以根据实际情况更改
file.upload.save-path=/root/blog/upload/

#文件访问路径
file.upload.url=/uploads/**

file.save-path=./

server.port=8888


server.tomcat.basedir=/root/blog/upload

#文件大小设置
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=30MB
spring.servlet.multipart.max-request-size=100MB

#用于返回结果的参数
server.localhost=http://localhost:8888

资源映射代码

package cn.jxj4869.fileuploadserver1.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.core.WeakCacheKey;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MySpringMvcConfig implements WebMvcConfigurer {

    @Value("${file.upload.save-path}")
    private String savePath;
    @Value("${file.upload.url}")
    private String url;
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(url).addResourceLocations("file:"+savePath);
    }
}

FileController

package cn.jxj4869.fileuploadserver1.controller;

import cn.jxj4869.fileuploadserver1.domain.Info;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
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.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

import java.util.*;

@Controller
public class FileController {

    @Value("${file.upload.save-path}")
    private String savePath;

    @Value("${server.localhost}")
    private String localhost;



    @RequestMapping("/fileupload")
    @ResponseBody
    private Info fileupload(HttpServletRequest request, @RequestParam("upload") MultipartFile[] uploads) throws IOException {
        System.out.println("文件上传");

        String path="/root/blog/upload";


        File file = new File(path);
        file.setWritable(true,false);
        if (!file.exists()) {
            file.mkdir();
        }

        List<String> list=new LinkedList<>();
        String filepath = localhost + request.getContextPath() + "/uploads/";
        for (MultipartFile upload : uploads) {
            String filename = upload.getOriginalFilename();

            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + "_" + filename;

            upload.transferTo(new File(path, filename));

            list.add( filepath + filename);
        }
        System.out.println("aa");
        Info info = new Info();
        info.put("success", 1);
        info.put("msg", "success");
        info.put("url", list.toArray());
        System.out.println(info.toString());
        return info;

    }



    @RequestMapping("/fileupload/md")
    @ResponseBody
    private Info fileuploadMd(HttpServletRequest request, @RequestParam("upload") MultipartFile[] uploads) throws IOException {
        System.out.println("文件上传");

        String path="/root/blog/upload";


        File file = new File(path);
        file.setWritable(true,false);
        if (!file.exists()) {
            file.mkdir();
        }
        String filepath = localhost + request.getContextPath() + "/uploads/";
        for (MultipartFile upload : uploads) {
            String filename = upload.getOriginalFilename();

            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + "_" + filename;

            upload.transferTo(new File(path, filename));
            filepath = filepath + filename;
        }
        System.out.println("aa");
        Info info = new Info();
        info.put("success", 1);
        info.put("msg", "success");
        info.put("url", filepath);
        System.out.println(info.toString());
        return info;
    }

    @RequestMapping("/fileupload/simditor")
    @ResponseBody
    private Info simditor(HttpServletRequest request, @RequestParam("upload") MultipartFile[] uploads) throws IOException {
        System.out.println("文件上传");

        String path="/root/blog/upload";


        File file = new File(path);
        file.setWritable(true,false);
        if (!file.exists()) {
            file.mkdir();
        }
        List<String> list=new LinkedList<>();
        String filepath = localhost + request.getContextPath() + "/uploads/";
        for (MultipartFile upload : uploads) {
            String filename = upload.getOriginalFilename();

            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + "_" + filename;

            upload.transferTo(new File(path, filename));
           list.add( filepath + filename);
        }
        System.out.println("aa");
        Info info = new Info();
        info.put("success", true);
        info.put("msg", "success");
        info.put("file_path", list.toArray());
        System.out.println(info.toString());
        return info;

    }

}

完整源码

源码已上传到 github

核心功能 文章/图片/视频发布、喜欢、统计阅读次数。 文章标签tag功能、支持按tag分类 文章支持ueditor/markdown编辑器切换(后台配置) 评论功能,支持回复,支持表情。 第三方(微博、QQ)登录。 lucene实现的站内搜索。 响应式布局 支持用户订阅 先看效果图 SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) http://localhost:8080/admin/group/list SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能)SpringBoot开发非常美观的java博客系统(包含后台管理功能) 技术选型: JDK8 数据库MySQL 主框架 (Spring-boot、Spring-data-jpa) 安全权限 Shiro 搜索工具 Lucene 缓存 Ehcache 视图模板 Freemarker 其它 Jsoup、fastjson jQuery、Seajs Bootstrap 前端框架 UEditor/Markdown编辑器 font-Awesome 字体/图标 准备工作(sql文件在项目里面) 安装 Jdk8 安装 Maven 准备 IDE (如果你不看源码,可以忽略下面的步骤,直接通过Maven编译war包:mvn clean package -DskipTests) IDE 需要配置的东西 编码方式设为UTF-8 配置Maven 设置Jdk8 关于这些配置,网上有一大把的资料,所以此处不再重复。 获取代码导入到IDE 下载代码 导入到IDE的时候请选择以Maven的方式导入 项目配置参考 系统配置手册 配置完毕 启动项目,在控制台看到Mblog加载完毕的信息后,表示启动成功 打开浏览器输入:http//localhost/mblog/ (此处仅是示例,具体具体端口因人而异),访问成功即部署完毕 后台管理的地址是 /admin, 如果你是管理员账号点导航栏的头像会看到"后台管理" 启动成功后,你应该去后台的系统配置里配置你的网站信息等。 常见问题总结 进入系统后, 菜单加载不出来, 那应该是你没有导 db_init.sql 点标签显示乱码, 请设置Tomcat的 URIEncoding 为 UTF-8 项目截图 SpringBoot开发非常美观的java博客系统(包含后台管理功能) 转自:https://gitee.com/mtons/mblog SpringBoot开发非常美观的java博客系统(包含后台管理功能) 注意: 一、java main方式运行mblog-web下的BootApplication.java时抛出异常的解决方案 Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. SpringBoot开发非常美观的java博客系统(包含后台管理功能) 注释掉后下面图片的这段后,记得maven要重新reimport SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) 否则maven依赖不生效还是会抛出以上的异常 二、第三方登录点击后无响应,那是因为第三方开放平台回调的url失效导致,需要你去对应的第三方开放平台注册app后获取对应的oauth帐号 SpringBoot开发非常美观的java博客系统(包含后台管理功能) 三、idea以maven项目导入该项目后,发现没有maven的依赖包时,需要对每个maven module进行clear和install,并且注意maven的依赖顺序 SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) 四、访问地址是http://localhost:8080 登录时,帐号,密码只要自己找个密码,然后md5下在更新到db中即可登录成功。 比如:zuidaima 111111,md5后密码是 3931MUEQD1939MQMLM4AISPVNE,md5的java类 SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiangxiaoju

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值