基于Spring Boot的论坛项目笔记

记录论坛项目中的一些重要功能的实现

git托管代码

到项目文件夹下打开终端:
在这里插入图片描述这个时候第一次push需要网址:

$ git init //初始化文件为本地仓库
$ git add .
$ git commit -m "提交信息"
$ git remote add origin '远程仓库url'
$ git push -u origin 对应远程分支名

以后修改文件后push上去不需要网址了:

$ git add --all
$ git commit -m "信息"
$ git push

登录功能

登录过程

在这里插入图片描述

github上注册OauthApp

在这里插入图片描述

首页导航栏及登录跳转设置

在这里插入图片描述
在这里插入图片描述当前网页地址,即
在这里插入图片描述
看到已经成功,从github端携带了code,用于获取accesstoken
在这里插入图片描述

  • 对AuthorizeController按照github授权信息进行设置:
@GetMapping("/callback")
    public String callback(@RequestParam(name="code") String code,
                           @RequestParam(name="state") String state,
                           HttpServletResponse response) {
        AccessTokenDTO accessTokenDTO = new AccessTokenDTO();
        accessTokenDTO.setClient_id(clientId);
        accessTokenDTO.setClient_secret(clientSecret);
        accessTokenDTO.setCode(code);
        accessTokenDTO.setRedirect_uri(redirectUri);
        accessTokenDTO.setState(state);
        String accessToken = githubProvider.getAccessToken(accessTokenDTO);
        GithubUser githubUser = githubProvider.getUser(accessToken);
        ...//返回项目根目录
        }
  • accesstoken可以获取指定用户的api,并由json转换为java类,用户信息存放于githubUser中:
    • 代码
public GithubUser getUser(String accessToken){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                    .url("https://api.github.com/user?access_token="+accessToken)
                    .build();

        try {
            Response response = client.newCall(request).execute();
            String string = response.body().string();//Json样式
            GithubUser githubUser = JSON.parseObject(string, GithubUser.class);//将JSON样式的string转换为java的类
            return githubUser;
        } catch (IOException e) {
        }
        return null;
    }
  • 用access_token获取的api
    在这里插入图片描述授权登录过程
    总之,点击登录按钮,调用github的authorize接口,github会跳转到callback地址,并且携带code
    通过code调用github的access_tokenAPI获取access_token,通过github的userAPI携带access_token来获取user信息

记录登录状态

使用数据库保存登录状态。需要自己设置一个value。当登录成功,将此value设置到cookie里面,等传递过来,拿value去数据库里查,将value命名为token。

数据库设置
  • 配置文件文件中设置数据库连接池用户名和密码:
    在这里插入图片描述
  • 新建数据库连接:
    工具栏点database,并设置,其中URL和上图的datasource.url一致:
    在这里插入图片描述建立数据库操作小结:引入h2依赖,建立h2的数据库,建表。引入mybatis依赖,引入jdbc依赖,就可以自动获取hiraki连接池,再在配置文件中以spring.datasource前缀来配置连接池。

数据库用户信息存入和查询

用户信息写入数据库:
if (githubUser != null) {
            User user = new User();
            String token = UUID.randomUUID().toString();
            user.setToken(token);
            user.setName(githubUser.getName());
            user.setAccountId(String.valueOf(githubUser.getId()));
            user.setAvatarUrl(githubUser.getAvatarUrl());
            userService.createOrUpdate(user);
            response.addCookie(new Cookie("token", token));
            //登录成功,写入cookie
            return "redirect:/";
        } else {
            log.error("callback get github error,{}",githubUser);
            //登录失败
            return "redirect:/";
        }

将插入数据库的数据当做登录状态,拿token来验证是否已经登录。

数据库实物存储代替了session。下面手动创建cookie的key和value,并根据key识别出value,去数据库中查询,如果存在,则登录成功,如果不存在,则登录失败。

token在网页前端可查看:
在这里插入图片描述

通过cookie在数据库中查询信息

整个流程:
当访问“/”之前,拦截器prehandle中,遍历cookie,当找到name=token的cookie时,将cookie的value去数据库中查询,若查询到,将数据库中对应此cookie的user数据和未读数写入session。只有登录过,才有token。

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Cookie[] cookies = request.getCookies();
        if (cookies!=null&&cookies.length!=0){
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("token")){
                    String token = cookie.getValue();
                    UserExample userExample = new UserExample();
                    userExample.createCriteria()
                            .andTokenEqualTo(token);
                    List<User> users=userMapper.selectByExample(userExample);
                    if(users.size() != 0){
                        request.getSession().setAttribute("user",users.get(0));
                        Long unreadCount=notificationService.unreadCount(users.get(0).getId());
                        request.getSession().setAttribute("unreadCount",unreadCount);//将未读数信息写入session,便于导航栏和我的回复的未读数
                    }
                    break;
                }
            }
        }
        return true;
    }

前端页面通过session获取用户信息,并显示。

Flyway的使用

Flyway简介

Flyway是独立于数据库的应用、管理并跟踪数据库变更的数据库版本管理工具。用通俗的话讲,Flyway可以像Git管理不同人的代码那样,管理不同人的sql脚本,从而做到数据库同步。

Flyway注意事项

flyway在执行脚本时,会在源数据表中检查checksum值,并确定上次运行到哪一个脚本文件,本次执行时从下一条脚本文件开始执行。所以编写脚本的时候不能修改原有的脚本内容,并且新的脚本版本号要连续。

Flyway使用步骤

1.引入pom依赖以及插件(5.2.4可用)

        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>5.2.4</version>
        </dependency>
        
        <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>5.2.4</version>
                <configuration>
                    <url>jdbc:h2:~/community</url>
                    <user>sa</user>
                    <password>123</password>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.h2database</groupId>
                        <artifactId>h2</artifactId>
                        <version>1.4.199</version>
                    </dependency>
                </dependencies>
            </plugin>

2.建立db/migration/文件名.sql:注意格式:V1后面是双下划线
在这里插入图片描述
3.写入sql语句

create table USER
(
    ID INT AUTO_INCREMENT PRIMARY KEY NOT NULL ,
	ACCOUNT_ID VARCHAR(100),
	NAME VARCHAR(50),
	TOKEN CHAR(36),
	GMT_CREATE BIGINT,
	GMT_MODIFIED BIGINT,
	constraint USER_PK
	primary key (ID)
);

4.保证删库的情况下再在终端执行mvn flyway:migrate,来通过sql文件生成数据库的表。

发布功能

前后端对应关系

页面和html文件以及后端对应关系:

id和label绑定,就是requestParam中“title”
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

spring devtool热部署

  1. 添加devtools依赖
    在这里插入图片描述
  2. 添加插件
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!--fork:如果没有该项配置,整个devtools不会起作用-->
                    <fork>true</fork>
                </configuration>
            </plugin>

2.某快捷键设置热部署自动编译

在这里插入图片描述在这里插入图片描述
注意:设置完这些之后,更改后端代码时,项目会自动重启。

为了更改静态页面时,浏览器能实时地变化,需要添加liveReload,并点击图标。
在这里插入图片描述

抽取公共元素

将公共元素抽成一个html文件,用于多处文件的使用
在这里插入图片描述
将需要插入的地方通过以下语句插入:

<div th:insert="~{navigation :: nav}"></div>

提交隐藏属性

当提交发布问题的表单时,“hidden”使得id不会在前端显现出来
在这里插入图片描述

集成mybatis generator

当需要更新查询等功能时,不需要每次都修改自定义的mapper文件。将自定义的mapper文件换成generator产生的mapper文件

为了防止数据库表结构改变时,mapper要重新写的问题,引入了Mybatis generator插件

  1. 引入generator插件
    在这里插入图片描述

  2. 通过resources下配置generatorConfig.xml,当需要生成某mapper时,就在配置文件增添如下的语句:
    在这里插入图片描述
    3.执行终端命令:

mvn flyway:migrate  //对数据库进行变更
mvn -Dmybatis.generator.overwrite=true mybatis-generator:generate //对xml和mapper进行变更

生成了mapper.xml(包括增删改查),类和mapper接口
在这里插入图片描述
在这里插入图片描述

异常处理

通用上下文的异常

通过@ControllerAdvice和@ExceptionHandler处理上下文的业务异常
在这里插入图片描述
用此类拦截MVC可以处理的异常,而对于拦截不到的异常,需要自定义一个controller来处理。

自定义异常处理

通过实现ErrorController的类来自定义异常界面。
在这里插入图片描述而异常信息的上下文传递,则通过exception包下的三个类来实现:
在这里插入图片描述

解决增加阅读数的并发情况

当多人同时点击问题时,要考虑问题被阅读数增加时的并发情况,保证问题增加数目正确。
通过QuestionExtMapper接口和QuestionExtMapper.xml的方法处理并发。xml文件有如下关键incView方法:

 <update id="incView" parameterType="life.majiang.community.model.Question">
   update QUESTION
   set
   VIEW_COUNT=VIEW_COUNT+#{viewCount,jdbcType=INTEGER}
   where id = #{id}
  </update>

VIEW_COUNT在当前VIEW_COUNT上的基础上相加,从而处理并发问题。

发布问题上传图片功能

  1. publish.html添加上传图片的参数:
<script type="text/javascript">
                    $(function() {
                        var editor = editormd("question-editor", {
                             width  : "100%",
                             height : 350,
                             path: "/js/lib/",
                             delay:0,
                             watch:false,
                             imageUpload: true,
                             imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
                             imageUploadURL: "/file/upload",
                        });
                    });
                </script>
  1. 写一个FileController,请求的参数地址和imageUploadURL地址一样
    在这里插入图片描述
  2. Ucloud创建存储空间:

在这里插入图片描述 . 4. 创建令牌
在这里插入图片描述5. 设置一个UcloudProvider配置BucketName和publicKey,privateKey等参数。

搜索功能

  1. 在导航类里添加搜索输入框的name
    在这里插入图片描述在这里插入图片描述

  2. 为导航栏搜索表单提供get请求到根目录
    在这里插入图片描述

  3. “/”目录的controller添加参数“search”,且分页方法添加带有search参数方法的变体。将带有search结果的分页结果写入pagination,并返回index页面。
    在这里插入图片描述

  4. 对于index页面问题的跳转,使得url加上带有search的内容
    在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值