小工具知识网

当前位置: 首页 > 行业知识 > SSM项目前后端分离+IDEA运行环境(含前端源码)(个人博客系统)

行业知识

SSM项目前后端分离+IDEA运行环境(含前端源码)(个人博客系统)

2026-11-13 11:07:43 来源:互联网转载

目录

 后端项目环境配置

1、创建一个SpringBoot项目,添加MyBatis框架和数据库MySQL驱动依赖

2、配置项目文件:application.yml

3、创建数据库表

4、创建分层结构目录

返回统一数据格式 

创建统一数据格式返回类:AjaxResult

创建实现统一数据返回的保底类:ResponseAdvice

统一处理

登录拦截器

配置拦截规则

实现用户的注册功能

步骤一:编写前端发送ajax请求代码

步骤二: 后端接收前端返回ajax数据进行判断

实体类entity

数据持久层mapper

服务层service

控制层Controller

MyBatis 配置文件插入语句

 实现用户的登录功能

前端提交Ajax代码

后端验证过程代码

定义全局变量类AppVariable

数据持久层mapper

数据库配置文件mapper.xml

服务层service

控制层controller

个人信息功能

获取文章数量功能

获取文章数量前端代码

获取文章数量后端代码

实体类包vo

数据持久层ArticleMapper

服务层ArticleService

控制层controller

数据库配置文件ArticleMapper.xml

获取文章列表分类数量功能

获取文章列表分类数量前端代码

获取文章列表分类数量后端代码

创建文章列表分类实体类Articleinfo

控制层ArticleController

删除文章功能

删除文章前端代码

删除文章后端代码

ArticleMapper.xml配置

数据持久层ArticleMapper

服务层ArticleService

控制层ArticleController

注销功能

注销功能前端代码实现

注销功能后端代码实现

控制层UserController

查看详情页功能和实现阅读量功能

查询详情信息和阅读量前端代码

查询详情信息和阅读量后端代码

数据持久层ArticleMapper

ArticleMapper.xml配置信息

服务层ArticleService

控制层ArticleController

添加文章功能

前端JS代码

后端实现代码

修改文章功能

前端代码

后端代码

分页查询文章列表功能

后端代码

前端代码

密码加盐加密

1、原始明文密码存储

2、传统的加密方式:MD5

3、加盐加密算法

手动使用加盐加密实现的代码

加盐加密算法方式二:使用Spring Security 框架 


前端静态页面源码下载地址:https://pan.baidu.com/s/1RHxWTX1xUNJdK1GNVrImsw?pwd=ofep

提取码:ofep

本篇文章记录个人从零搭建个人博客系统总结,主要是介绍后端项目功能实现,前端代码已提前实现就不在本篇文章过多概述。

前端代码静态效果展示:

注册界面 

​

 登录界面

​

博客主页界面 

​

 将前端代码文件导入IDEA创建的SpringBoot项目中的resources目录下面的static目录下

​

 后端项目环境配置

1、创建一个SpringBoot项目,添加MyBatis框架和数据库MySQL驱动依赖

        操作详情见之前博客文章:https://pan.baidu.com/s/1RHxWTX1xUNJdK1GNVrImsw?pwd=ofep

2、配置项目文件:application.yml

# 配置数据库的连接字符串spring:  datasource:    url: jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8&useSSL=false    username: "root"    password: "xzf1314520"    driver-class-name: com.mysql.cj.jdbc.Driver# 配置 mybatis xml 保存路径mybatis:  mapper-locations: classpath:mapper/*Mapper.xml  configuration: # 配置打印MyBatis执行的SQL    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 配置打印日志输出logging:  level:    com:      example:        demo: debug

3、创建数据库表

-- 创建数据库drop database if exists mycnblog;create database mycnblog DEFAULT CHARACTER SET utf8mb4; -- 使用数据数据use mycnblog; -- 创建表[用户表]drop table if exists  userinfo;create table userinfo(    id int primary key auto_increment,    username varchar(100) not null unique,    password varchar(100) not null,    photo varchar(500) default '',    createtime datetime default now(),    updatetime datetime default now(),    `state` int default 1) default charset 'utf8mb4'; -- 创建文章表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)default charset 'utf8mb4'; -- 创建视频表drop table if exists videoinfo;create table videoinfo(  vid int primary key,  `title` varchar(250),  `url` varchar(1000),createtime datetime default now(),updatetime datetime default now(),  uid int)default charset 'utf8mb4'; -- 添加一个用户信息INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES (1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1); -- 文章添加测试数据insert into articleinfo(title,content,uid)    values('Java','Java正文',1);    -- 添加视频insert into videoinfo(vid,title,url,uid) values(1,'java title','http://www.baidu.com',1);

4、创建分层结构目录

数据持久层接口mapper 、服务层service 、控制层controller 、实体类entity 、 项目配置类config 

​

返回统一数据格式 

创建统一数据格式返回类:AjaxResult

1、创建公共包commer 来存放统一的返回格式给前端

2、在公共包commer下创建一个统一数据格式返回的类:AjaxResult

        AjaxResult类包含了状态码、状态码描述信息以及返回的数据结果

3、返回操作成功和失败的结果的方法

4、AjaxResult类实现序列化接口SeriaLizable ,可以实现特殊操作,代码不会进行报错

package com.example.demo.commer;import lombok.Data;import java.io.Serializable;/** 返回统一数据格式* */@Data // 注解:添加get和set方法public class AjaxResult implements Serializable {    // 状态码    private Integer code;    // 状态码描述信息    private String mesg;    // 返回的数据    private Object data;    public static AjaxResult success(Object data){        /*         * 操作成功返回的结果         * */        AjaxResult result = new AjaxResult();        result.setCode(200);        result.setMesg("");        result.setData(data);        return result;    }    public static AjaxResult success(Integer code,Object data){        /*         * 操作成功返回的结果         * */        AjaxResult result = new AjaxResult();        result.setCode(code);        result.setMesg("");        result.setData(data);        return result;    }    public static AjaxResult success(Integer code,String mesg,Object data){        /*         * 操作成功返回的结果         * */        AjaxResult result = new AjaxResult();        result.setCode(code);        result.setMesg(mesg);        result.setData(data);        return result;    }    public static AjaxResult fail(Integer code,String mesg,Object data){        /*        * 返回失败的结果        * */        AjaxResult result = new AjaxResult();        result.setCode(code);        result.setMesg(mesg);        result.setData(null);        return result;    }}

         当创建了统一数据返回格式类,当需要返回统一数据格式时就需要调用AjaxResult类来返回数据。然而在一个项目中许多的人会进行共同协同操作,这时就会发生忘记调用统一数据返回格式类的可能性,因此就需要创建一个在返回数据之前检测是否实现统一数据返回的保底类。

        实现统一数据返回的保底类可以在返回数据之前,检测数据的类型是否为统一的对象,如果不是统一的数据返回格式,就封装成统一的数据格式

创建实现统一数据返回的保底类:ResponseAdvice

在系统的配置类中创建保底类ResponseAdvice

​

package com.example.demo.config;import com.example.demo.commer.AjaxResult;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import lombok.SneakyThrows;import org.springframework.beans.factory.annotation.Autowired;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.web.bind.annotation.ControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/**  实现统一的数据格式的返回保底类*  在返回数据之前进行检测数据是否为统一数据格式,如果不是统一数据格式就封装成统一的数据返回格式* */@ControllerAdvicepublic class ResponseAdvice implements ResponseBodyAdvice {    @Autowired    private ObjectMapper objectMapper;    /*    * 开关,如果为true,则会调用beforeBodyWrite方法    * */    @Override    public boolean supports(MethodParameter returnType, Class converterType) {        return true;    }   /*   * 对数据格式进行封装和效验   * */    @Override    @SneakyThrows // 抛出异常的注解    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {        if(body instanceof AjaxResult){            return body;        }        if(body instanceof String ){                return objectMapper.writeValueAsString(AjaxResult.success(body));        }        return AjaxResult.success(body);    }}

统一处理

统一处理的作用就是实现统一异常处理、统一的数据返回格式以及统一登录验证拦截的实现

登录拦截器

登录拦截器需要实现接口HandlerInterceptor 并且重写 preHandle方法

在config包下面创建登录拦截类LoginInterceptor

package com.example.demo.config;import com.example.demo.commer.AppVariable;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 {    /*    * true -> 用户已登录    * false -> 用户未登录    * */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        HttpSession session = request.getSession();        if(session != null && session.getAttribute(AppVariable.USER_SESSION_KEY) != null){            // 用户已登录            return true;        }            // 用户未登录 需要跳转到登录界面        response.sendRedirect("/login.html");        return false;    }}

配置拦截规则

在编写完登录拦截器后,需要设置拦截规则,说明哪些是需要拦截的,哪些是不需要拦截的

在config包下面创建配置拦截规则类AppConfig,  实现接口WebMvcConfigurer 并且重写addInterceptors方法

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.WebMvcConfigurer;/** 配置拦截规则* */@Configuration // 拦截注解public class AppConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {       registry.addInterceptor(new LoginInterceptor())               .addPathPatterns("/**") // 拦截所有接口               .excludePathPatterns("/css/**")  // 不拦截css文件下所有目录               .excludePathPatterns("/editor.md/**") // 不拦截editor.md文件下所有目录               .excludePathPatterns("/img/**") // 不拦截img文件下所有目录               .excludePathPatterns("/js/**") // 不拦截js文件下所有目录               .excludePathPatterns("/login.html") // 不拦截 登录页面 文件下所有目录               .excludePathPatterns("/reg.html") // 不拦截 注册页面 文件下所有目录               //.excludePathPatterns("/blog_list.html") //不拦截 博客所有人 文件下所有目录               .excludePathPatterns("/blog_content.html") // 不拦截 博客列表 文件下所有目录               .excludePathPatterns("/art/detail")  // 不拦截 文章详情页面               .excludePathPatterns("/art/listbypage") // 不拦截 文章主页分页页面               .excludePathPatterns("/art/incr-rcount") // 不拦截阅读文章量加1               .excludePathPatterns("/user/login") //不拦截登录接口               .excludePathPatterns("/user/getuserbyid") // 不拦截查询文章详情页的用户id               .excludePathPatterns("/user/reg"); // 不拦截注册接口    }}

实现用户的注册功能

实现用户的注册功能包括两个步骤:

1、前端用户向后端发送ajax请求

2、后端接收前端返回ajax数据进行判断

步骤一:编写前端发送ajax请求代码

在前端reg.html页面编写效验和请求ajax代码

        // 提交注册事件 使用jQuery        function mysub(){        //1.非空效验            var username = jQuery("#username");            var password = jQuery("#password");            var password2 = jQuery("#password2");            if(username.val() ==""){                alert("请先输入用户名");                return;            }            if(password.val() ==""){                alert("请先输入密码");                 return;            }            if(password2.val() ==""){                 alert("请先输入确认密码");                 return;            }        //2.判断两次密码是否一致        if(password.val() !=password2.val()){                alert("两次输入密码不一致,请检查");                return;        }        //3.ajax 提交请求        jQuery.ajax({            url:"/user/reg",            method:"POST",            data:{"username":username.val(),"password":password.val()},            success:function(result){                //响应的结果                if(result != null && result.code == 200 && result.data == 1){                        //执行成功                       if(confirm("注册成功,是否跳转到登录界面?")){                            location.href="/login.html";                       }                } else{                        //执行失败                        alert("注册失败,请稍后再试");                }            }        });    }            

步骤二: 后端接收前端返回ajax数据进行判断

实体类entity
package com.example.demo.entity;import lombok.Data;import java.time.LocalDateTime;@Datapublic class Userinfo {    /*    * 创建实体类对象    * */    private Integer id;    private String username;    private String password;    private String photo;    private LocalDateTime createtime;    private LocalDateTime updatetime;    private Integer state;}
数据持久层mapper
package com.example.demo.mapper;import com.example.demo.entity.Userinfo;import org.apache.ibatis.annotations.Mapper;@Mapperpublic interface UserMapper {    // 传递实体类对象,方便后续维护参数的修改    // 注册    public int reg(Userinfo userinfo);}
服务层service
package com.example.demo.service;import com.example.demo.entity.Userinfo;import com.example.demo.mapper.UserMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class UserService {    @Autowired    private UserMapper userMapper;    public  int reg(Userinfo userinfo){        return userMapper.reg(userinfo);    }}
控制层Controller
package com.example.demo.controller;import com.example.demo.commer.AjaxResult;import com.example.demo.entity.Userinfo;import com.example.demo.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/user")public class UserController {    @Autowired    private UserService userService;    @RequestMapping("/reg")    public AjaxResult reg(Userinfo userinfo){        // 非空效验,判断前端返回参数是否非空及有效性效验        //若前端返回Ajax参数为空则返回Ajax失败参数        if(userinfo == null || !StringUtils.hasLength(userinfo.getUsername()) ||                !StringUtils.hasLength(userinfo.getPassword()) ){            return AjaxResult.fail(-1,"非法参数");        }        //返回ajax成功参数        return AjaxResult.success(userService.reg(userinfo));    }}
MyBatis 配置文件插入语句

UserMapping.xml

                insert into userinfo(username,password) values(#{username},#{password)      

​

验证注册功能是否能够按照我们的要求实现,运行项目,输入http://localhost:8080/reg.html来访问我们的注册界面

​

当注册成功后可以选择是否跳转登录界面,此时查询数据库看是否已经有数据插入数据库中

​

 实现用户的登录功能

        用户登录功能与注册功能逻辑差不多,都是先进行前端 提交ajax数据请求给后端,在进行效验,其中后端进行数据库查询判断用户名或者密码是否存在且正确。

前端提交Ajax代码

        function mysub(){            // 1、非空效验            var username = jQuery("#username");            var password = jQuery("#password");            if(username == null){                alert("请输入用户名");                username.focus();                return;            }            if(password == null){                alert("请输入密码");                username.focus();                return;            }            // 2、ajax请求登录接口            jQuery.ajax({                url:"/user/login",                method:"POST",                data:{"username":username.val(),"password":password.val()},                success:function(result){                    if(result != null && result.code == 200 && result.data != null){                        // 登录成功则将跳转到博客主界面                        location.href ="myblog_list.html";                    }else{                        alert("登录失败!用户名或密码错误,请重新输入");                    }                }            });        }    

后端验证过程代码

后端在验证登录过程中,如果登录成功就需要将用户存储到session中,此时就先定义一个全局变量 ,用来表示用户的session

定义全局变量类AppVariable
package com.example.demo.commer;/* * 全局变量 * */public class AppVariable {    // 用户session 的key    public static final String USER_SESSION_KEY = "USER_SESSION_KEY";}
数据持久层mapper

根据用户名来查询用户对象,返回给服务层service来调用

 // 根据用户查询userinfo 对象    Userinfo getUsername(@Param("username") String username);
数据库配置文件mapper.xml

根据前端传递的ajax用户名,在数据库中查询是否存在该用户名

         select * from userinfo where username=#{username}    
服务层service

服务层拿到数据持久层传递的用户名并返回给控制层controller

 //登录方法    public Userinfo getUsername(String username){        return userMapper.getUsername(username);    }
控制层controller

1、控制层先进行前端ajax数据进行非空效验,

2、拿到前端传递的用户名数据再去数据库查询是否存在该用户名和密码

3、将从数据库查询到的密码与前端返回的密码进行比对,若不同则将data置为null,返回给前端

4、比对相同的话则将用户信息存入session中进行保存记录,然后将密码置为空(隐藏敏感信息,保证信息安全),把数据返回给前端

 // 登录效验    @RequestMapping("/login")    public AjaxResult login(HttpServletRequest request,String username, String password){        // 1、非空效验        //若前端返回Ajax参数为空则返回Ajax失败参数        if(!StringUtils.hasLength(username)  || !StringUtils.hasLength(password)){            return AjaxResult.fail(-1,"非法参数");        }        // 2、查询数据库        Userinfo userinfo = userService.getUsername(username);        if(userinfo != null && userinfo.getId() > 0){            // 有效的用户            // 判断两个密码是否相同            if(password.equals(userinfo.getPassword())){                //登录成功                // 将用户存储在session中                HttpSession session = request.getSession();                session.setAttribute(AppVariable.USER_SESSION_KEY,userinfo);                //返回前端之前,隐藏密码等敏感信息                userinfo.setPassword("");                return AjaxResult.success(userinfo);            }        }        return AjaxResult.success(0,null);    }

运行项目,输入登录界面进行效果验证,之前注册用户名为张三、密码为123,如果登录成功的话则将跳转到博客列表主界面

​

 ​

个人信息功能

        在个人信息中可以查询最新文章数量和文章列表分类数量、删除文章和注销用户功能,在实现这些功能的前提是需要前端向后端发送ajax请求来得到数据。

获取文章数量功能

获取文章数量前端代码

        // 获取最新文章数量        function showInfo(){            jQuery.ajax({                url:"/user/showinfo",                method:"POST",                data:{},                success:function(result){                    if(result != null && result.code == 200){                        jQuery("#username").text(result.data.username); // 用户名id                        jQuery("#artCount").text(result.data.artCount); // 文章数量                    }else{                        alert("个人信息加载失败,请重新刷新");                    }                }            });        }        showInfo();    

获取文章数量后端代码

在公共类commer下创建一个类记录当前登录用户的session

​

package com.example.demo.commer;import com.example.demo.entity.Userinfo;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;/** * 当前用户登录相关的操作 */public class UserSessionUtils {    /**     * 得到当前的登录用户     */    public static Userinfo getUser(HttpServletRequest request){        HttpSession session = request.getSession(false);        if(session != null && session.getAttribute(AppVariable.USER_SESSION_KEY) != null){            // 说明用户已经正常登录            return (Userinfo) session.getAttribute(AppVariable.USER_SESSION_KEY);        }        return null;    }}
实体类包vo

新创建实体包vo,在包下面创建实体类UserinfoVO  继承于实体类Userinfo

新添加一个实体属性:此人发表的文章总数

package com.example.demo.entity.vo;import com.example.demo.entity.Userinfo;import lombok.Data;@Datapublic class UserinfoVO extends Userinfo {    private Integer artCount; // 此人发表的文章总数}
数据持久层ArticleMapper
package com.example.demo.mapper;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;@Mapperpublic interface ArticleMapper {    int getArtCountByUid(@Param("uid") Integer uid);}
服务层ArticleService
package com.example.demo.service;import com.example.demo.mapper.ArticleMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class ArticleService {    @Autowired    private ArticleMapper articleMapper;    public int getArtCountByUid(Integer uid){        return articleMapper.getArtCountByUid(uid);    }}
控制层controller
// 获取用户id    @RequestMapping("/showinfo")    public AjaxResult showinfo(HttpServletRequest request){        UserinfoVO userinfoVO = new UserinfoVO();        // 1.得到当前的登录用户 (从session中获取)        Userinfo userinfo = UserSessionUtils.getUser(request);        if(userinfo == null){            return AjaxResult.fail(-1,"非法请求");        }        // Spring 提供的深拷贝方法        BeanUtils.copyProperties(userinfo,userinfoVO);        // 2.得到用户发表文章的总数        userinfoVO.setArtCount(articleService.getArtCountByUid(userinfo.getId()));        return AjaxResult.success(userinfoVO);    }
数据库配置文件ArticleMapper.xml
            select count(*) from articleinfo where uid=#{uid}    

实现效果:

​

 ​

获取文章列表分类数量功能

获取文章列表分类数量前端代码

// 获取我的文章列表数量        function getMyArtList(){                jQuery.ajax({                    url:"/art/myList",                    method:"post",                    data:{},                    success:function(result){                        if(result != null && result.code == 200){                            // 有两种情况:发表了文章和从未发表过任何文章                            if(result.data != null && result.data.length > 0){                                // 此用户发表了文章                                var artListDiv = "";                                for(var i=0; i暂无文章");                            }                        }else{                                                      alert("查询文章列表出错,请重试")                        }                    }                });        }        getMyArtList();

获取文章列表分类数量后端代码

创建文章列表分类实体类Articleinfo
package com.example.demo.entity;import com.fasterxml.jackson.annotation.JsonFormat;import lombok.Data;import java.time.LocalDateTime;@Datapublic class Articleinfo {    /**     * 文章列表实体属性     */    private  Integer id;    private String title;    private String content;    // 设置时间格式化    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")    private LocalDateTime createtime;    // 设置时间格式化    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")    private LocalDateTime updatetime;    private Integer uid;    private Integer rcount;    private Integer state;}
控制层ArticleController
package com.example.demo.controller;import com.example.demo.commer.AjaxResult;import com.example.demo.commer.UserSessionUtils;import com.example.demo.entity.Articleinfo;import com.example.demo.entity.Userinfo;import com.example.demo.service.ArticleService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import java.util.List;@RequestMapping("/art")@RestControllerpublic class ArticleController {    @Autowired    public ArticleService articleService;    @RequestMapping("/myList")    public AjaxResult  getMyList(HttpServletRequest request){        Userinfo userinfo = UserSessionUtils.getUser(request);        if(userinfo == null){            return AjaxResult.fail(-1,"非法请求");        }        List list = articleService.getMyList(userinfo.getId());        return AjaxResult.success(list);    }}

实现效果:

​

删除文章功能

删除文章前端代码

 // 删除文章        function myDel(id){            if(confirm("确定是否需要删除")){                jQuery.ajax({                    url:"art/del",                    method:"post",                    data:{"id":id},                    success:function(result){                        if(result != null && result.code == 200 && result.data == 1){                            alert("删除成功");                            // 刷新页面                            location.href = location.href;                        }else{                            alert("删除失败");                        }                    }                });            }        }

删除文章后端代码

ArticleMapper.xml配置
            delete from articleinfo where id = #{id} and uid = #{uid}    
数据持久层ArticleMapper
 //  删除文章   int del(@Param("id") Integer id,@Param("uid") Integer uid);
服务层ArticleService
 // 删除文章    public int del(Integer id,Integer uid){        return articleMapper.del(id,uid);    }
控制层ArticleController
//删除文章    @RequestMapping("/del")    public AjaxResult del(HttpServletRequest request,Integer id){        if(id == null || id  1){                    params = location.search.substring(1);                    var paramArr = params.split("&");                    for(var i=0;i 0 && result.code == 200){                            jQuery("#username").text(result.data.username);                            jQuery("#artCount").text(result.data.artCount);                        }else{                            alert("查询用户失败");                        }                    }                });            }            // 阅读量加1            function updateRCount(){                // 先得到文章 id                var id = getUrlValue("id");                if(id != ""){                     jQuery.ajax({                        url:"/art/incr-rcount",                        method:"post",                        data:{"id":id},                        success:function(result){}                     });                }                           }            updateRCount()                 

查询详情信息和阅读量后端代码

数据持久层ArticleMapper
   // 文章详情页    Articleinfo getDetail(@Param("id") Integer id);    // 实现阅读量加1    int incrmentRCount(@Param("id") Integer id);
ArticleMapper.xml配置信息
            select * from articleinfo where id=#{id}                update articleinfo set rcount = rcount+1 where id=#{id}    
服务层ArticleService
 //  查询文章详情    public Articleinfo getDetail(Integer id){        return articleMapper.getDetail(id);    }    // 实现阅读量加1    public int incrmentRCount (Integer id){        return articleMapper.incrmentRCount(id);    }
控制层ArticleController
// 查询文章详情信息    @RequestMapping("/detail")    public AjaxResult getDetail(Integer id){        if(id == null && id 0){            return AjaxResult.success(articleService.incrmentRCount(id));        }        return AjaxResult.fail(-1,"未知错误");    }

实现效果:

点击查看全文按钮就可以进入文章详情页,查看文章详情以及文章的阅读量

​

​

添加文章功能

前端JS代码

        var editor;        function initEdit(md){            // 编辑器设置            editor = editormd("editorDiv", {                // 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉.                width: "100%",                // 高度 100% 意思是和父元素一样高. 要在父元素的基础上去掉标题编辑区的高度                height: "calc(100% - 50px)",                // 编辑器中的初始内容                markdown: md,                // 指定 editor.md 依赖的插件路径                path: "editor.md/lib/",                saveHTMLToTextarea: true //            });        }        initEdit("# 在这里写下一篇博客"); // 初始化编译器的值        // 提交        function mysub(){            if(comfirm("确认提交?")){                // 1、非空效验                var title = jQuery("#title");                if(title.val() == ""){                    alert("请先输入标题!");                    title.focus();                    return;                }                if(editor.getValue() == ""){                    alert("请先输入正文!");                                     return;                }              //2、请求后端进行博客添加操作                jQuery.ajax({                    url:"/art/add",                    method:"post",                    data:{"title":title.val(),"content":editor.getValue()},                    success:function(result){                        if(result!= null && result.code == 200 && result.data ==1){                            if(confirm("文章添加成功! 是否继续添加文章?")){                                // 刷新当前页面                                location.href = location.href;                            }else{                                location.href= "myblog_list.html";                            }                        }else{                            alert("文章添加失败!");                        }                    }                });                 alert(editor.getValue()); // 获取值            // editor.setValue("#123") // 设置值            }                    }

后端实现代码

数据库配置文件

            insert into articleinfo(title,content,uid) values(#{title},#{content},#{uid})    

数据持久层

 // 实现添加文章    int add(Articleinfo articleinfo);

服务层

 // 实现添加文章功能    public int add(Articleinfo articleinfo){        return articleMapper.add(articleinfo);    }

控制层

// 实现添加文章功能    @RequestMapping("/add")    public AjaxResult add(HttpServletRequest request, Articleinfo articleinfo){        // 1、非空效验        if(articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle())                ||!StringUtils.hasLength(articleinfo.getContent())){            // 非法参数            return AjaxResult.fail(-1,"非法参数");        }         // 2、数据库添加操作        // a. 得到当前登录用户的uid        Userinfo userinfo = UserSessionUtils.getUser(request);        if(userinfo  == null || userinfo.getId()  1){                    params = location.search.substring(1);                    var paramArr = params.split("&");                    for(var i=0;i    

上一篇:文档怎么上传到服务器?

下一篇:揭秘爱情表白秘籍,轻松俘获心仪之人的秘籍宝典!