没有办法从零开始也不是胎教的 SpringBoot 框架搭建个人博客项目实现(附代码)

使用SpringBoot 框架搭建个人博客代码附在文末

1、下载环境

  首先在官网 https://start.spring.io/ 下载一个模板到本地,使用Spring Boot 2.4.8版, java 8,下载jar包,同时导入Spring Boot DevTools(热部署)、Lombok(快捷注释)、 Spring Web(网络项目需要用) 三个依赖;下次使用时,解压然后改文件名就可以了

2、安装依赖

  我们创建的时候没有安装mysql 和 mybatis 依赖,我们要安装一个新的插件,来方便添加新的依赖,
首先进入 Settings 然后点击 plugins,在这里市场里(Marketplace) 中 搜索到 EditStarters 然后安 装,安装好后重启IDEA; 如果 Marketplace 刷新不出来,重启一下IDEA就好;此时我们进入pom.xml 中,在这个文件中右键,点击Genrate --> Edit Starters ;如果没有报错,就点击OK,如果出现报 错,说找不到Spring Boot,就重新在右上角的Maven中重新引入一下加载(build)一下项目环境;然后 搜索 mysql 和 mybatis 两个依赖,然后重新加载maven

3、配置aplication.properties文件

debug = false
## 日志保存路径
#logging.file.path = logs/
#logging.logback.rollingpolicy.max-file-size=10MB

# 设置日志等级
logging.level.root = info

# 设置端口号
server.port=8080

# 数据库连接地址
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8&useSSL=true
spring.datasource.name=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# mybatis mapper 路径
mybatis.mapper-locations=classpath:mapper/**Mapper.xml

# 开启mybatis的sql执行日志
logging.level.com.example.demo.mapper=debug

  其中 mybatis mapper 路径 的作用是:配置 **Mapper.xml 文件,该配置文件应该放在 resources 下新建一个mapper文件,这个文件的作用是 拿到对数据库操作的具体方法的映射,这样我们在java文件夹下写具体操作方法时,只需要写一个 该类方法的 接口, 这个接口的具体实现部分则是放在对应类的Mapper.xml文件下,这部分后面举例时详细说。

  • 开启mybatis的sql执行日志 的作用是:令 com.example.demo.mapper 文件夹下的程序与形式以debug的等级去打印日志

4、将所有网页的静态页面准备充分,稍后将根据以下顺序实现功能

  • (0)index.html:导航页面
  • (1)login.html:登陆页面;
  • (2)regin.html:注册页面;reg_err.html:注册失败页面;reg_succerss.html:注册成功页面
  • (3)myblog.list.html:我的文章页面
  • (4)blog_content.html:文章内容页面*
  • (5)blog_edit:添加文章页面

5、一些要用到的工具类

(1)模板类与数据库
  根据在使用servlet做项目的经验,可以知道,登录就需要用户的信息,所以在我们需要一个model模板类,在这个类下存放用户的所有信息(User.java)或是存放文章的所有信息(ArticleInfo.java);其次对应的,如何映射到前端的url,并在后端操作,这是controller类需要解决的问题,针对用户相关的操作就写在controller类下的·在UserController.java类中列举各种具体的操作方法,同样对于文章的具体操作方法就写在controller类下的ArticleInfoController.java下。
  当前我们要实现的是用户的登录功能,首先构建数据库,数据库的模板如下,将下述sql代码导入mysql中执行到数据库中:

-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8;

-- 使用数据数据
use mycnblog;

-- 创建表[用户表]
drop table if exists userinfo;
create table userinfo(
id int primary key auto_increment,
username varchar(100) not null,
password varchar(32) not null,
photo varchar(500) default '',
createtime datetime default now(),
updatetime datetime default now(),
`state` int default 1
);

-- 创建文章表
drop table if exists articleinfo;
create table articleinfo(
id int primary key auto_increment,
title varchar(100) not null,
content text not null,
createtime datetime default now(),
updatetime datetime default now(),
uid int not null,
rcount int not null default 1,
`state` int default 1
);

-- 文章添加测试数据
insert into articleinfo(title,content,uid)
values('Java','Java正文',1);

  有了我们本地有了这个数据库后,接下来要在model模板类根据数据库中的userinfo表和articlinfo表创建User.java和ArticleInfo.java两个模板类,这两个模板类中的成员变量名必须和数据库中的属性名相同,方便后续进行沟通
  User用户信息模板类

package com.example.demo.model;
import lombok.Data;
import java.util.List;
@Data // 加上这个注释,我们就不用写 private 的 get 和 set 方法了
public class User {
   
    private int id;
    private String username;
    private String password;
    private String photo;
    private List<ArticleInfo> alist; // 要知道当前用户有多少文章,则需要这么定义文章表的内容在这里
}

  ArticleInfo文章内容模板类

package com.example.demo.model;
import lombok.Data;
import java.util.Date;
@Data
public class ArticleInfo {
   
    private int id;
    private String title;
    private String content;
    private Date createtime;
    private Date updatetime;
    private int uid;
    private int rcount;
    private String state;
    private User user;
}

(2)一些相关的配置文件(config.java 类)
①:AppFinal.java —— 这里写项目中不会变更的常量 即 final修饰的变量

package com.example.demo.config;
// 保存全局常量
public class AppFinal {
   
// 用户登录后 session 的key名称
public static final String USERINFO_SESSIONKEY = "userinfo";
// 图片存放的路径
public static final String IMAGE_PATH = "/upload/";
}

②:AppConfig.java —— 在这个类中,我们配置url的使用规则与拦截规则(拦截器具体则需要在config类下另外定义)

package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 在这个类中,我们配置url的使用规范,并且可以通过配置拦截器索要拦截的地址
* */
@Configuration  // 代表配置文件的注释
public class AppConfig implements WebMvcConfigurer {
   // 要实现自定义url和连接规则,继承 WebMvcConfigurer 也是不能忘的
    // 自定义url前缀
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
   
        configurer.addPathPrefix("api" , c -> true);
        // 这里使用了λ表达式的方式,这里的意思是,之后我们在网页输入所有的页面的url时都要加上api
        // c -> true 的意思就是 configurer 对象为true,当为false就表示不添加
    }
    
    // 自定义拦截器规则
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
   
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") // 拦截所有的接口
                .excludePathPatterns("/api/user/login") // 不拦截登录接口
                .excludePathPatterns("/api/user/reg") // 不拦截注册接口
                .excludePathPatterns("/login.html") // 不拦截登录页面
                .excludePathPatterns("/regin.html") // 不拦截注册页面
                .excludePathPatterns("/**/**.html") // 不拦截注册页面
                .excludePathPatterns("/**/*.css")
                .excludePathPatterns("/**/*.js")
                .excludePathPatterns("/**/*.jpg")
                .excludePathPatterns("/reg_success.html")
                .excludePathPatterns("/reg_err.html")
                .excludePathPatterns("/**/*.png");
    }
}

③:LoginInterceptor.java: —— 登录拦截器,当用户没有登陆的情况下(网页端没有有效Session信息时),是不能访问到其他任何页面的

package com.example.demo.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
    // HandlerInterceptor 经常用来实现拦截功能,所以我们要继承它
    // 自定义拦截方法,返回结果为 boolean值
    // 为 true表示可以访问后端接口,返回 false 表示无权访问后端接口
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   
        // 判断Session 是否有值
        HttpSession session = request.getSession(false); // false 表示不创建新的session
        if(session != null &&
            session.getAttribute(AppFinal.USERINFO_SESSIONKEY) != null){
   
            // 说明用户已登陆了
            return true;
        }
        return false;
    }
}

④:ErrorAdvice.java —— 自定义异常,将输出异常打包成想要的格式输出(这里打包成json字符串的格式,就可以将错误返回给前端)

package com.example.demo.config;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
@ControllerAdvice // 规范出现异常时的返回数据格式
public class ErrorAdvice {
   
    @ExceptionHandler(RuntimeException.class) // 自定义运行时异常的格式
    @ResponseBody
    public Object err2(Exception e){
   
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", "-2");
        map.put("data", "");
        map.put("msg", e.getMessage());
        return map;
    }
    @ExceptionHandler(NullPointerException.class) // 自定义空指针异常的输出格式
    @ResponseBody
    public Object err3(Exception e) {
   
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", "-3");
        map.put("data", "");
        map.put("msg", "空指针异常");
        return map;
    }
    @ExceptionHandler
    @ResponseBody
    public Object err(Exception e) {
   
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", "-1");
        map.put("data", "");
        map.put("msg", e.getMessage());
        return map;
    }
}

⑤:MyResponseBodyAdvice —— 打包返回给前端的数据(这个在项目使用中近乎是模板一样的)

package com.example.demo.config;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
@ControllerAdvice // 增强返回格式的的类, 要继承 ResponseBodyAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
   
    // 必须都要重写 ResponseBodyAdvice 的两个方法
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
   
        return true;
    }
    @Override
    public Object beforeBodyWrite(Object o,
                                  MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
   
        HashMap<String, Object> map = new HashMap<>();
        map.put("status", 0);  // 返回给前端的标识
        map.put("data", o);     // o 对象就是 数据对象部分
        map.put("msg","");
        return map;
    }
}

(3)在Spring中,要通过通过连接数据库对数据库进行增删查改是不用像servlet项目那样使用JDBC,这里使用的是MyBatis,在一开始的aplication.properties文件中,我们已经定义了本机数据库的相关信息,在那里面有一个 mybatis mapper 路径 的属性,这里就需要使用Spring中的Mapper映射的方法去修改数据库。
  具体逻辑为: 以注册为例,UserController 中的 regin 方法的路由地址为"/reg",则在与controller同级的文件夹下需要有一个新的mapper类,在mapper类下有各个具体操作的子类接口,这里的话就是UserMapper接口,在UserMapper下只写方法但不写具体实现,通过在resources文件夹下创建一个新的文件夹UserMapper.xml,这个文件就是用来配置具体的数据库操作逻辑,它是和UserMapper.java这个接口互通的,在UserMapper.java定义接口方法,到Mapper.xml文件中去具体执行。
  在UserMapper.java接口类中写映射的接口

package com.example.demo.mapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper // 用来映射 mapper的配置文件
public interface UserMapper {
   
    // 添加用户(注册功能)
    public int addUser(User user);
}

  去UserMapper.xml中写具体修改数据库的SQL语句

<?xml version="
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值