Spring Boot项目学习10之发帖模块

1.帖子的表设计

最显著的三个字段是帖子标题、帖子内容、帖子类别。但是除了这些字段外,还有一些必要的字段。

  • 用户 id
  • 阅读数量
  • 评论数量
  • 收藏数量
  • 发布时间

同时,在发布帖子时,为了防止有人重复提交、重复发帖,提交表单时又加了一个验证码字段。

USE `my_bbs_db`;

DROP TABLE IF EXISTS `tb_post_category`;

CREATE TABLE `tb_post_category` (
  `category_id` int NOT NULL AUTO_INCREMENT COMMENT '分类表主键',
  `category_name` varchar(16) NOT NULL COMMENT '分类的名称',
  `category_rank` int NOT NULL DEFAULT '1' COMMENT '分类的排序值 被使用的越多数值越大',
  `is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除 0=否 1=是',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

insert  into `tb_post_category`(`category_id`,`category_name`,`category_rank`,`is_deleted`,`create_time`) values (1,'提问',10,0,'2021-08-10 14:47:38'),(2,'分享',9,0,'2021-08-10 14:47:38'),(3,'建议',8,0,'2021-08-10 14:47:38'),(4,'讨论',7,0,'2021-08-10 14:47:38'),(5,'动态',6,0,'2021-08-10 14:47:38'),(6,'其它',5,0,'2021-08-10 14:47:38');

DROP TABLE IF EXISTS `tb_bbs_post`;

CREATE TABLE `tb_bbs_post` (
  `post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '帖子主键id',
  `publish_user_id` bigint NOT NULL COMMENT '发布者id',
  `post_title` varchar(64) NOT NULL DEFAULT '' COMMENT '帖子标题',
  `post_content` mediumtext NOT NULL COMMENT '帖子内容',
  `post_category_id` int NOT NULL COMMENT '帖子分类id',
  `post_category_name` varchar(50) NOT NULL COMMENT '帖子分类(冗余字段)',
  `post_status` tinyint NOT NULL DEFAULT '1' COMMENT '0-未审核 1-审核通过 2-审核失败',
  `post_views` bigint NOT NULL DEFAULT '0' COMMENT '阅读量',
  `post_comments` bigint NOT NULL DEFAULT '0' COMMENT '评论量',
  `post_collects` bigint NOT NULL DEFAULT '0' COMMENT '收藏量',
  `last_update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最新修改时间',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
  PRIMARY KEY (`post_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

2.跳转至发帖子功能

2.1Controller 处理跳转

首先新建 BBSPostController.java,该方法用于处理 /addPostPage 请求,由于是新增帖子的操作,所以只需要查询出分类数据供用户进行选择即可。如果是修改帖子的操作则需要进行帖子信息的查询,之后跳转到 templates/jie 目录下的 add.html 中。

@Controller
public class BBSPostController {

    @Resource
    private BBSPostCategoryService bbsPostCategoryService;

    @GetMapping("/addPostPage")
    public String addPostPage(HttpServletRequest request) {
        List<BBSPostCategory> bbsPostCategories = bbsPostCategoryService.getBBSPostCategories();
        if (CollectionUtils.isEmpty(bbsPostCategories)) {
            return "error/error_404";
        }
        //将分类数据封装到request域中
        request.setAttribute("bbsPostCategories", bbsPostCategories);
        return "jie/add";
    }
}

2.2 完成获取帖子分类列表功能

2.2.1 创建帖子分类实体类
/**
 * 帖子分类-实体类
 */
public class BBSPostCategory {
    private Integer categoryId;

    private String categoryName;

    private Integer categoryRank;

    private Byte isDeleted;

    private Date createTime;

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName == null ? null : categoryName.trim();
    }

    public Integer getCategoryRank() {
        return categoryRank;
    }

    public void setCategoryRank(Integer categoryRank) {
        this.categoryRank = categoryRank;
    }

    public Byte getIsDeleted() {
        return isDeleted;
    }

    public void setIsDeleted(Byte isDeleted) {
        this.isDeleted = isDeleted;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", categoryId=").append(categoryId);
        sb.append(", categoryName=").append(categoryName);
        sb.append(", categoryRank=").append(categoryRank);
        sb.append(", isDeleted=").append(isDeleted);
        sb.append(", createTime=").append(createTime);
        sb.append("]");
        return sb.toString();
    }
}
2.2.2 业务层
public interface BBSPostCategoryService {
    /**
     * 获取分类列表
     *
     * @return
     */
    List<BBSPostCategory> getBBSPostCategories();
}
@Service
public class BBSPostCategoryServiceImpl implements BBSPostCategoryService {

    @Autowired
    private BBSPostCategoryMapper bbsPostCategoryMapper;

    @Override
    public List<BBSPostCategory> getBBSPostCategories() {
        return bbsPostCategoryMapper.getBBSPostCategories();
    }
    
}
2.2.3 数据持久层
public interface BBSPostCategoryMapper {
    List<BBSPostCategory> getBBSPostCategories();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.picacho.bbs.dao.BBSPostCategoryMapper">
    <resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSPostCategory">
        <id column="category_id" jdbcType="INTEGER" property="categoryId" />
        <result column="category_name" jdbcType="VARCHAR" property="categoryName" />
        <result column="category_rank" jdbcType="INTEGER" property="categoryRank" />
        <result column="is_deleted" jdbcType="TINYINT" property="isDeleted" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    </resultMap>
    <sql id="Base_Column_List">
        category_id, category_name, category_rank, is_deleted, create_time
    </sql>
    
    <select id="getBBSPostCategories" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from tb_post_category
        where is_deleted = 0 order by category_rank desc
    </select>
</mapper>

2.3 创建帖子

接下来,把编辑页面按照字段来完善一下,将帖子表中需要输入内容的字段填充到页面 DOM 中。
其中帖子标题字段是直接使用的 input 框,帖子详情内容的输入使用的是 wangEditor 编辑器,发布按钮在页面的右上角并绑定了 onclick() 事件,点击后由 addBBSPost() 方法进行处理。最后把富文本编辑器和图片上传插件的初始化代码加进来。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="header::head-fragment('发布帖子')">
</head>
<body>
<div th:replace="header::header-fragment"></div>

<div class="layui-container fly-marginTop">
    <div class="fly-panel" pad20 style="padding-top: 5px;">
        <div class="layui-form layui-form-pane">
            <div class="layui-tab layui-tab-brief" lay-filter="user">
                <ul class="layui-tab-title">
                    <li class="layui-this">发表新帖<!-- 编辑帖子 --></li>
                </ul>
                <div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
                    <div class="layui-tab-item layui-show">
                        <form method="post" id="postForm" onsubmit="return false;" action="##">
                            <div class="layui-row layui-col-space15 layui-form-item">
                                <div class="layui-col-md6">
                                    <label for="postTitle" class="layui-form-label">标题</label>
                                    <div class="layui-input-block">
                                        <input type="text" id="postTitle" name="postTitle" required

                                               autocomplete="off" class="layui-input">
                                    </div>
                                </div>
                                <div class="layui-col-md6">
                                    <label class="layui-form-label">所在专栏</label>
                                    <div class="layui-input-block">
                                        <select name="class" lay-filter="column"
                                                id="postCategoryId">
                                            <option value="0"></option>
                                            <th:block th:unless="${null == bbsPostCategories}">
                                                <th:block th:each="c : ${bbsPostCategories}">
                                                    <option th:value="${c.categoryId}" th:text="${c.categoryName}">提问
                                                    </option>
                                                </th:block>
                                            </th:block>
                                        </select>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-form-item layui-form-text">
                                <div class="layui-input-block">
                                    <div id="wangEditor" name="postContent" required
                                         placeholder="详细描述"
                                         style="height: 260px;"></div>
                                </div>
                            </div>
                            <div class="layui-form-item" style="margin-top: 56px;">
                                <label for="verifyCode" class="layui-form-label">验证码</label>
                                <div class="layui-input-inline">
                                    <input type="text" id="verifyCode" name="verifyCode" required
                                           placeholder="验证码" autocomplete="off" class="layui-input">
                                </div>
                                <div class="layui-form-mid">
                                    <span style="color: #c00;"><img data-tooltip="看不清楚?换一张"
                                                                    th:src="@{/common/captcha}"
                                                                    onclick="this.src='/common/captcha?d='+new Date()*1"
                                                                    alt="单击图片刷新!"></span>
                                </div>
                            </div>
                            <div class="layui-form-item">
                                <button class="layui-btn" lay-filter="*" lay-submit onclick="addBBSPost()">立即发布</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="fly-footer">
    <p>My-BBS社区 2021 &copy; <a href="填写自己的博客" target="_blank">picacho</a></p>
</div>

<script th:src="@{/js/public.js}"></script>
<script th:src="@{/layui/layui.js}"></script>
<!-- wangEditor -->
<script type="text/javascript" src="//unpkg.com/wangeditor/dist/wangEditor.min.js"></script>

<script type="text/javascript">
    layui.use(['layer', 'element', 'jquery', 'form'], function () {
        var layer = layui.layer, $ = layui.$, element = layui.element, form = layui.form;
        var editorD;

        //富文本编辑器,用于帖子详情编辑
        const E = window.wangEditor;
        editorD = new E('#wangEditor')
        // 设置编辑区域高度为 260px
        editorD.config.height = 260
        editorD.config.zIndex = 1
        //配置服务端图片上传地址
        editorD.config.uploadImgServer = '/uploadFiles'
        editorD.config.uploadFileName = 'files'
        //限制图片大小 2M
        editorD.config.uploadImgMaxSize = 2 * 1024 * 1024
        //限制一次最多能传几张图片 一次最多上传 5 个图片
        editorD.config.uploadImgMaxLength = 5
        //隐藏插入网络图片的功能
        editorD.config.showLinkImg = false
        editorD.config.uploadImgHooks = {
            // 图片上传并返回了结果,图片插入已成功
            success: function (xhr) {
                console.log('success', xhr)
            },
            // 图片上传并返回了结果,但图片插入时出错了
            fail: function (xhr, editor, resData) {
                console.log('fail', resData)
            },
            // 上传图片出错,一般为 http 请求的错误
            error: function (xhr, editor, resData) {
                console.log('error', xhr, resData)
            },
            // 上传图片超时
            timeout: function (xhr) {
                console.log('timeout')
            },
            customInsert: function (insertImgFn, result) {
                if (result != null && result.resultCode == 200) {
                    // insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
                    result.data.forEach(img => {
                        insertImgFn(img)
                    });
                } else {
                    alert("error");
                }
            }
        }
        editorD.create();
    });
</script>
</body>
</html>

2.4 测试效果

同样该请求需要在登陆状态下访问,http://localhost:8080/addPostPage。可以看到查询到帖子的分类列表。
在这里插入图片描述

3.完成发帖功能

3.1 帖子实体类

/**
 * 帖子-实体类
 */
public class BBSPost {
    private Long postId;

    private Long publishUserId;

    private String postTitle;

    private Integer postCategoryId;

    private String postCategoryName;

    private Byte postStatus;

    private Long postViews;

    private Long postComments;

    private Long postCollects;

    private Date lastUpdateTime;

    private Date createTime;

    private String postContent;

    public Long getPostId() {
        return postId;
    }

    public void setPostId(Long postId) {
        this.postId = postId;
    }

    public Long getPublishUserId() {
        return publishUserId;
    }

    public void setPublishUserId(Long publishUserId) {
        this.publishUserId = publishUserId;
    }

    public String getPostTitle() {
        return postTitle;
    }

    public void setPostTitle(String postTitle) {
        this.postTitle = postTitle == null ? null : postTitle.trim();
    }

    public Integer getPostCategoryId() {
        return postCategoryId;
    }

    public void setPostCategoryId(Integer postCategoryId) {
        this.postCategoryId = postCategoryId;
    }

    public String getPostCategoryName() {
        return postCategoryName;
    }

    public void setPostCategoryName(String postCategoryName) {
        this.postCategoryName = postCategoryName == null ? null : postCategoryName.trim();
    }

    public Byte getPostStatus() {
        return postStatus;
    }

    public void setPostStatus(Byte postStatus) {
        this.postStatus = postStatus;
    }

    public Long getPostViews() {
        return postViews;
    }

    public void setPostViews(Long postViews) {
        this.postViews = postViews;
    }

    public Long getPostComments() {
        return postComments;
    }

    public void setPostComments(Long postComments) {
        this.postComments = postComments;
    }

    public Long getPostCollects() {
        return postCollects;
    }

    public void setPostCollects(Long postCollects) {
        this.postCollects = postCollects;
    }

    public Date getLastUpdateTime() {
        return lastUpdateTime;
    }

    public void setLastUpdateTime(Date lastUpdateTime) {
        this.lastUpdateTime = lastUpdateTime;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getPostContent() {
        return postContent;
    }

    public void setPostContent(String postContent) {
        this.postContent = postContent == null ? null : postContent.trim();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", postId=").append(postId);
        sb.append(", publishUserId=").append(publishUserId);
        sb.append(", postTitle=").append(postTitle);
        sb.append(", postCategoryId=").append(postCategoryId);
        sb.append(", postCategoryName=").append(postCategoryName);
        sb.append(", postStatus=").append(postStatus);
        sb.append(", postViews=").append(postViews);
        sb.append(", postComments=").append(postComments);
        sb.append(", postCollects=").append(postCollects);
        sb.append(", lastUpdateTime=").append(lastUpdateTime);
        sb.append(", createTime=").append(createTime);
        sb.append(", postContent=").append(postContent);
        sb.append("]");
        return sb.toString();
    }
}

3.2 帖子发布接口

帖子发布接口负责接收前端的 POST 请求并处理其中的参数,接收的参数为用户在帖子编辑页面输入的所有字段内容,字段名称与对应的含义如下:

  • “postTitle”: 帖子标题
  • “postCategoryId”: 帖子类别
  • “postContent”: 帖子内容(wangEditor 编辑器中的内容)
  • “verifyCode”:验证码
3.2.1 BBSPostController控制层

在 BBSPostController 中新增 addPost() 方法,接口的映射地址为 /addPost,请求方法为 POST。

    /**
     * 添加一条帖子数据
     */
    @PostMapping("/addPost")
    @ResponseBody
    public Result addPost(@RequestParam("postTitle") String postTitle,
                          @RequestParam("postCategoryId") Integer postCategoryId,
                          @RequestParam("postContent") String postContent,
                          @RequestParam("verifyCode") String verifyCode,
                          HttpSession httpSession) {
        if (!StringUtils.hasLength(postTitle)) {
            return ResultGenerator.genFailResult("postTitle参数错误");
        }
        if (null == postCategoryId || postCategoryId < 0) {
            return ResultGenerator.genFailResult("postCategoryId参数错误");
        }
        BBSPostCategory bbsPostCategory = bbsPostCategoryService.selectById(postCategoryId);
        if (null == bbsPostCategory) {
            return ResultGenerator.genFailResult("postCategoryId参数错误");
        }
        if (!StringUtils.hasLength(postContent)) {
            return ResultGenerator.genFailResult("postContent参数错误");
        }
        if (postTitle.trim().length() > 32) {
            return ResultGenerator.genFailResult("标题过长");
        }
        if (postContent.trim().length() > 100000) {
            return ResultGenerator.genFailResult("内容过长");
        }
        String kaptchaCode = httpSession.getAttribute(Constants.VERIFY_CODE_KEY) + "";
        if (!StringUtils.hasLength(kaptchaCode) || !verifyCode.equals(kaptchaCode)) {
            return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_VERIFY_CODE_ERROR.getResult());
        }
        BBSUser bbsUser = (BBSUser) httpSession.getAttribute(Constants.USER_SESSION_KEY);
        BBSPost bbsPost = new BBSPost();
        bbsPost.setPublishUserId(bbsUser.getUserId());
        bbsPost.setPostTitle(postTitle);
        bbsPost.setPostContent(postContent);
        bbsPost.setPostCategoryId(postCategoryId);
        bbsPost.setPostCategoryName(bbsPostCategory.getCategoryName());
        if (bbsPostService.savePost(bbsPost) > 0) {
            httpSession.removeAttribute(Constants.VERIFY_CODE_KEY);//清空session中的验证码信息
            return ResultGenerator.genSuccessResult();
        } else {
            return ResultGenerator.genFailResult("请求失败,请检查参数及账号是否有操作权限");
        }
    }

添加接口中,首先会对参数进行校验,之后获取当前登录用户的信息,并将帖子实体的 publishUserId 字段设置好,之后交给业务层代码进行操作。

由于要检查帖子分类的合法性,所以需要通过帖子分类id来查询分类,是否为一个存在的分类。

3.2.2 通过id获取帖子分类功能

业务层

BBSPostCategory selectById(Integer categoryId);
	@Override
    public BBSPostCategory selectById(Integer categoryId) {
        return bbsPostCategoryMapper.selectByPrimaryKey(categoryId);
    }

数据持久层

BBSPostCategory selectByPrimaryKey(Integer categoryId);
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from tb_post_category
        where category_id = #{categoryId,jdbcType=INTEGER}
    </select>
3.2.3 业务层

service 包中新建 BBSPostService 并定义接口方法 savePost()。

public interface BBSPostService {
    /**
     * 保存帖子
     *
     * @param bbsPost
     * @return
     */
    int savePost(BBSPost bbsPost);
}
@Service
public class BBSPostServiceImpl implements BBSPostService {

    @Autowired
    private BBSPostCategoryMapper bbsPostCategoryMapper;
    @Autowired
    private BBSPostMapper bbsPostMapper;
    @Autowired
    private BBSUserMapper bbsUserMapper;

    @Override
    public int savePost(BBSPost bbsPost) {
        BBSUser bbsUser = bbsUserMapper.selectByPrimaryKey(bbsPost.getPublishUserId());
        if (bbsUser == null || bbsUser.getUserStatus().intValue() == 1) {
            //账号已被封禁
            return 0;
        }

        BBSPostCategory bbsPostCategory = bbsPostCategoryMapper.selectByPrimaryKey(bbsPost.getPostCategoryId());
        if (bbsPostCategory == null) {
            //分类数据错误
            return 0;
        }
        return bbsPostMapper.insertSelective(bbsPost);
    }
}

帖子添加接口的业务实现方法操作步骤如下:

  • 根据 publishUserId 查询当前登录用户信息
  • 如果账号不存在或者账号已被封禁则返回错误信息
  • 根据 postCategoryId 查询分类信息
  • 如果分类数据错误返回错误信息
  • 进行入库操作,向帖子表中新增一条记录
  • 将新增结果返回给上层调用方法
3.2.4 数据持久层
public interface BBSPostMapper {
    int insertSelective(BBSPost record);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.picacho.bbs.dao.BBSPostMapper">
    <resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSPost">
        <id column="post_id" jdbcType="BIGINT" property="postId"/>
        <result column="publish_user_id" jdbcType="BIGINT" property="publishUserId"/>
        <result column="post_title" jdbcType="VARCHAR" property="postTitle"/>
        <result column="post_category_id" jdbcType="INTEGER" property="postCategoryId"/>
        <result column="post_category_name" jdbcType="VARCHAR" property="postCategoryName"/>
        <result column="post_status" jdbcType="TINYINT" property="postStatus"/>
        <result column="post_views" jdbcType="BIGINT" property="postViews"/>
        <result column="post_comments" jdbcType="BIGINT" property="postComments"/>
        <result column="post_collects" jdbcType="BIGINT" property="postCollects"/>
        <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    </resultMap>
    <resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="top.picacho.bbs.entity.BBSPost">
        <result column="post_content" jdbcType="LONGVARCHAR" property="postContent"/>
    </resultMap>
    <sql id="Base_Column_List">
        post_id, publish_user_id, post_title, post_category_id, post_category_name,
    post_status, post_views, post_comments, post_collects, last_update_time,
    create_time
    </sql>
    <sql id="Blob_Column_List">
        post_content
    </sql>

    <insert id="insertSelective" parameterType="top.picacho.bbs.entity.BBSPost">
        insert into tb_bbs_post
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="postId != null">
                post_id,
            </if>
            <if test="publishUserId != null">
                publish_user_id,
            </if>
            <if test="postTitle != null">
                post_title,
            </if>
            <if test="postCategoryId != null">
                post_category_id,
            </if>
            <if test="postCategoryName != null">
                post_category_name,
            </if>
            <if test="postStatus != null">
                post_status,
            </if>
            <if test="postViews != null">
                post_views,
            </if>
            <if test="postComments != null">
                post_comments,
            </if>
            <if test="postCollects != null">
                post_collects,
            </if>
            <if test="lastUpdateTime != null">
                last_update_time,
            </if>
            <if test="createTime != null">
                create_time,
            </if>
            <if test="postContent != null">
                post_content,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="postId != null">
                #{postId,jdbcType=BIGINT},
            </if>
            <if test="publishUserId != null">
                #{publishUserId,jdbcType=BIGINT},
            </if>
            <if test="postTitle != null">
                #{postTitle,jdbcType=VARCHAR},
            </if>
            <if test="postCategoryId != null">
                #{postCategoryId,jdbcType=INTEGER},
            </if>
            <if test="postCategoryName != null">
                #{postCategoryName,jdbcType=VARCHAR},
            </if>
            <if test="postStatus != null">
                #{postStatus,jdbcType=TINYINT},
            </if>
            <if test="postViews != null">
                #{postViews,jdbcType=BIGINT},
            </if>
            <if test="postComments != null">
                #{postComments,jdbcType=BIGINT},
            </if>
            <if test="postCollects != null">
                #{postCollects,jdbcType=BIGINT},
            </if>
            <if test="lastUpdateTime != null">
                #{lastUpdateTime,jdbcType=TIMESTAMP},
            </if>
            <if test="createTime != null">
                #{createTime,jdbcType=TIMESTAMP},
            </if>
            <if test="postContent != null">
                #{postContent,jdbcType=LONGVARCHAR},
            </if>
        </trim>
    </insert>
    
</mapper>
3.2.5 Ajax 调用帖子添加接口

在信息录入完成后可以点击页面的立即发布按钮,此时会调用后端接口并进行数据的交互。

window.addBBSPost = function () {
  var postTitle = $("#postTitle").val();
  if (isNull(postTitle)) {
    layer.alert("请输入标题!", {
      title: "提醒",
      skin: "layui-layer-molv",
      icon: 2,
    });
    return;
  }
  var verifyCode = $("#verifyCode").val();
  if (!validLength(verifyCode, 5)) {
    layer.alert("请输入正确的验证码!", {
      title: "提醒",
      skin: "layui-layer-molv",
      icon: 2,
    });
    return;
  }
  var postCategoryId = $("#postCategoryId option:selected").val();
  if (isNull(postCategoryId)) {
    layer.alert("请选择分类!", {
      title: "提醒",
      skin: "layui-layer-molv",
      icon: 2,
    });
    return;
  }

  var postContent = editorD.txt.html();

  if (!validLength(postContent, 100000)) {
    layer.alert("内容超出长度!", {
      title: "提醒",
      skin: "layui-layer-molv",
      icon: 2,
    });
    return;
  }
  var url = "/addPost";
  var data = {
    postTitle: postTitle,
    verifyCode: verifyCode,
    postCategoryId: postCategoryId,
    postContent: postContent,
  };
  $.ajax({
    type: "POST", //方法类型
    url: url,
    data: data,
    success: function (result) {
      if (result.resultCode == 200) {
        window.location.href = "/index";
      } else {
        layer.msg(result.message);
      }
    },
    error: function () {
      layer.alert("操作失败!", {
        title: "提醒",
        skin: "layui-layer-molv",
        icon: 2,
      });
    },
  });
};

该方法逻辑如下:

  • 前端对用户输入的标题、帖子内容、验证码进行简单的正则验证
  • 封装帖子实体的参数
  • 向对应的后端发布帖子接口发送 Ajax 请求
  • 请求成功后提醒用户请求成功并跳转到首页
  • 请求失败则提醒对应的错误信息

4.验证效果

在这里插入图片描述
将帖子内容编辑完成,就可以点击立即发布完成发帖。
在这里插入图片描述
可以看到这个帖子被保存到了数据库了并且跳转到了首页,只是首页还没有制作完成,共用了登陆功能的跳转页面首页。
在这里插入图片描述
项目源码下载地址:源码下载

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
实现在 Android 上的发帖功能,一般需要涉及以下步骤: 1. 创建一个界面,让用户输入发帖内容,并且可以上传图片或者其他附件。 2. 在界面上添加一个“提交”按钮,用户填完信息后可以点击提交按钮。 3. 在提交按钮的点击事件里,将用户填写的信息发送到服务器端。 4. 服务器端收到信息后,将信息存储到数据库中。 5. 返回成功或者失败的消息给客户端,告知用户发帖是否成功。 下面是一个简单的示例代码,仅供参考: 1. 创建一个布局文件,例如 post_layout.xml,用于让用户输入发帖内容和上传图片等附件。 2. 在Activity中加载布局文件,并且监听提交按钮的点击事件。 ```java public class PostActivity extends AppCompatActivity { private EditText mEditText; private Button mSubmitButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.post_layout); mEditText = findViewById(R.id.editText); mSubmitButton = findViewById(R.id.submitButton); mSubmitButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String postContent = mEditText.getText().toString(); // 将postContent发送到服务器端 // 等待服务器端返回成功或者失败的消息 // 根据返回的消息提示用户发帖是否成功 } }); } } ``` 3. 在服务器端,接收到客户端发来的信息,将信息存储到数据库中。 ```java public class PostServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String postContent = request.getParameter("postContent"); // 将postContent存储到数据库中 // 返回成功或者失败的消息给客户端 } } ``` 注意,以上代码仅供参考,具体实现还需要根据实际情况进行调整。同时,还需要注意安全性,例如对用户输入进行合法性校验,防止SQL注入等攻击。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

picacho_pkq

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

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

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

打赏作者

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

抵扣说明:

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

余额充值