文章目录
- 一、为什么使用token口令
- 二、登录注册功能
- 2.1 登录表单提交
- 后端代码:
- 2.2 根据token获取完整用户信息
- 代码实现:
- 2.3 注册时用户名占用校验
- 代码实现:
- 2.4 注册表单提交
- 代码实现:
- 三、头条首页功能
- 3.1 查询所有头条分类
- 3.2 分页带条件查询所有头条
- 代码实现:
- 3.3 查看头条详情
- 代码实现:
- 四、头条发布修改和删除
- 4.1 登录校验
- 代码实现:
- 4.2 提交发布头条(新增
- 代码实现:
- 4.3 修改头条回显
- 4.4 保存修改
- 代码实现:
- 4.5 删除头条
- 总结
- 2.1 登录表单提交
一、为什么使用token口令
为什么使用 token 口令 而不使用 cookie和session
- cookie和session 对于高并发项目不合适
- token:
二、登录注册功能
2.1 登录表单提交
需求描述:
输入 用户名 密码 验证登录,根据输入的用户名 和 密码 提示不同的响应信息
URI:
user/login
请求方式:
POST
请求参数:
{ "username":"dougwake", //用户名 "userPwd":"123456" //明文密码 }
响应示例:
- 登录成功
- 用户名输入有误:
- 密码错误:
后端代码:
2.1.1 Controller 层
package com.doug.headline.controller;
import com.doug.headline.common.Result;
import com.doug.headline.common.ResultCodeEnum;
import com.doug.headline.dao.NewsUserDao;
import com.doug.headline.pojo.NewsUser;
import com.doug.headline.service.NewsUserService;
import com.doug.headline.service.impl.NewsUserServiceImpl;
import com.doug.headline.util.JwtHelper;
import com.doug.headline.util.MD5Util;
import com.doug.headline.util.WebUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/user/*")
public class NewsUserController extends BaseController {
private NewsUserService newsUserService = new NewsUserServiceImpl();
/**
* 接收前端请求参数 进行登录校验
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 接收前端传递过来的JSON串 (即请求参数)
NewsUser newsUser = WebUtil.readJson(req, NewsUser.class);
// 调用业务层代码 查找用户名是否存在
NewsUser loginNewsUser = newsUserService.findByUsername(newsUser.getUsername());
Result result = null;
if (null != loginNewsUser) {
// 用户名存在 -> 进一步判断 密码是否正确(先将明文密码转成MD5 再与已存密码对比)
if (loginNewsUser.getUserPwd().equals(MD5Util.encrypt(newsUser.getUserPwd()))) {
// 响应结果 是键值对形式 所以用map
Map<String, Object> data = new HashMap<>();
// 创建token
String token = JwtHelper.createToken(loginNewsUser.getUid().longValue());
data.put("token", token);
result = Result.ok(data);
} else {
// 密码有误
result = Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
}
} else {
// 查找为空 用户名不存在 返回自定义用户名错误业务码
result = Result.build(null, ResultCodeEnum.USERNAME_ERROR);
}
// 响应结果
WebUtil.writeJson(resp, result);
}
}
2.1.2 service
public interface NewsUserService {
/**
* 根据用户名,获得查询的用户信息
* @param username 要查找的用户名
* @return 如果找到返回NewsUser对象,找不到返回null
*/
NewsUser findByUsername(String username);
}
public class NewsUserServiceImpl implements NewsUserService {
private NewsUserDao newsUserDao = new NewsUserDaoImpl();
@Override
public NewsUser findByUsername(String username) {
return newsUserDao.findByUsername(username);
}
}
2.1.3 dao
public interface NewsUserDao {
/**
* 根据用户名,获得查询的用户信息
* @param username 要查找的用户名
* @return 如果找到返回NewsUser对象,找不到返回null
*/
NewsUser findByUsername(String username);
}
public class NewsUserDaoImpl extends BaseDao implements NewsUserDao {
@Override
public NewsUser findByUsername(String username) {
String sql = """
select
uid,username,user_pwd userPwd,nick_name nickName
from
news_user
where
username = ?;
""";
List<NewsUser> newsUserList = baseQuery(NewsUser.class, sql, username);
// 如果找到,返回集合中的第一个数据(其实就一个)
if(null != newsUserList && newsUserList.size() > 0){
return newsUserList.get(0);
}
return null;
}
}
2.2 根据token获取完整用户信息
需求描述:
客户端发送请求,提交token请求头,后端根据token请求头获取登录用户的详细信息并响应给客户端进行存储
URI:
user/getUserInfo
请求方式:
GET
请求头
token: ...
响应示例
- 成功获取
- 获取失败
代码实现:
2.2.1 Controller
private NewsUserService newsUserService = new NewsUserServiceImpl();
/**
* 接收token,根据token查询完整用户信息
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getUserInfo(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = req.getHeader("token");
Result result = Result.build(null, ResultCodeEnum.NOTLOGIN);
// token 存在
if(null != token){
// token 没有到期
if(!JwtHelper.isExpiration(token)){
Integer uid = JwtHelper.getUserId(token).intValue();
// 通过token的uid 找对象
NewsUser newsUser = newsUserService.findByUid(uid);
newsUser.setUserPwd("");
HashMap<String, Object> data = new HashMap<>();
data.put("loginUser",newsUser);
result = Result.ok(data);
}
}
WebUtil.writeJson(resp,result);
}
2.2.2 Service
/**
* 根据用户id查询用户信息
* @param uid 要查询的用户id
* @return 找到返回NewsUser对象,找不到返回null
*/
NewsUser findByUid(Integer uid);
@Override
public NewsUser findByUid(Integer uid) {
return newsUserDao.finByUid(uid);
}
2.2.3 Dao
NewsUser finByUid(Integer uid);
@Override
public NewsUser finByUid(Integer uid) {
String sql = """
select
uid,username,user_pwd userPwd,nick_name nickName
from
news_user
where
uid = ?;
""";
List<NewsUser> newsUserList = baseQuery(NewsUser.class, sql, uid);
// 如果找到,返回集合中的第一个数据(其实就一个)
return null != newsUserList && newsUserList.size() > 0 ? newsUserList.get(0):null;
}
2.3 注册时用户名占用校验
用户在注册时输入用户名时,立刻将用户名发送给后端,后端根据用户名查询用户名是否可用并做出响应
URI
user/checkUserName
请求方式:
POST
请求参数:
username=DougWake
响应示例:
- 用户名校验通过
- 用户名被占用
代码实现:
/**
* 注册时校验用户名是否占用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void checkUserName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
NewsUser newsUser = newsUserService.findByUsername(username);
Result result = null;
if(null == newsUser){
result = Result.ok(null);
}else{
result = Result.build(null,ResultCodeEnum.USERNAME_USED);
}
WebUtil.writeJson(resp,result);
}
2.4 注册表单提交
客户端将新用户信息发送给服务端,服务端将新用户存入数据库,存入之前做用户名是否被占用校验,校验通过响应成功提示,否则响应失败提示
URI :
user/regist
请求方式:
POST
请求参数 :
{
"username":"GavinGroves",
"userPwd":"0123456",
"nickName":"加文"
}
响应示例:
- 注册成功:
- 用户名占用:(第二次注册)
代码实现:
2.4.1 Controller
/**
* 用户注册
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
NewsUser newsUser = WebUtil.readJson(req, NewsUser.class);
NewsUser usedUser = newsUserService.findByUsername(newsUser.getUsername());
Result result = null;
if(null != usedUser){
result = Result.build(null,ResultCodeEnum.USERNAME_USED);
}else{
newsUserService.registUser(newsUser);
result = Result.ok(null);
}
WebUtil.writeJson(resp,result);
}
2.4.2 Service
/**
* 注册用户信息,注册成功返回大于0的整数,失败返回0
* @param newsUser 要添加的新对象
* @return
*/
int registUser(NewsUser newsUser);
@Override
public int registUser(NewsUser newsUser) {
// 密码明文转密文
newsUser.setUserPwd(MD5Util.encrypt(newsUser.getUserPwd()));
return newsUserDao.insertNewsUser(newsUser);
}
2.4.3 Dao
/**
* 将用户信息存入数据库
* @param newsUser 插入新的用户对象
* @return
*/
int insertNewsUser(NewsUser newsUser);
public int insertNewsUser(NewsUser newsUser) {
String sql = "insert into news_user values(DEFAULT,?,?,?)";
return baseUpdate(sql, newsUser.getUsername(), newsUser.getUserPwd(), newsUser.getNickName());
}
三、头条首页功能
3.1 查询所有头条分类
进入新闻首页,查询所有分类并动态展示新闻类别栏位
URI:
portal/findAllTypes
请求方式:GET
- 响应示例:
{
"code": 200,
"message": "success",
"data": [
{
"tid": 1,
"tname": "新闻"
},
{
"tid": 2,
"tname": "体育"
},
{
"tid": 3,
"tname": "娱乐"
},
{
"tid": 4,
"tname": "科技"
},
{
"tid": 5,
"tname": "其他"
}
]
}
- Controller
package com.doug.headline.controller;
import com.doug.headline.common.Result;
import com.doug.headline.pojo.NewsType;
import com.doug.headline.service.NewsTypeService;
import com.doug.headline.service.impl.NewsTypeServiceImpl;
import com.doug.headline.util.WebUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* @Author: Gavin
* @Date: 2024-02-02 17:10
* @Description: 门户 控制器 即 当用户没有登录时候 所看到的页面(首页)
*/
@WebServlet("/portal/*")
public class PortalController extends BaseController {
private NewsTypeService typeService = new NewsTypeServiceImpl();
/**
* 查询所有头条类型 业务接口实现
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void findAllTypes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<NewsType> newsTypeList = typeService.findAllTypes();
WebUtil.writeJson(resp,Result.ok(newsTypeList));
}
}
- service
public interface NewsTypeService {
/**
* 查询全部新闻类型
* @return 新闻类型数据
*/
List<NewsType> findAllTypes();
}
public class NewsTypeServiceImpl implements NewsTypeService {
private NewsTypeDao typeDao= new NewsTypeDaoImpl();
@Override
public List<NewsType> findAllTypes() {
return typeDao.findAllTypes();
}
}
- dao
public interface NewsTypeDao {
/**
* 查询全部新闻类型
* @return 新闻类型数据
*/
List<NewsType> findAllTypes();
}
public class NewsTypeDaoImpl extends BaseDao implements NewsTypeDao {
@Override
public List<NewsType> findAllTypes() {
String sql = "select tid,tname from news_type";
return baseQuery(NewsType.class,sql);
}
}
3.2 分页带条件查询所有头条
- 客户端向服务端发送查询关键字,新闻类别,页码数,页大小
- 服务端根据条件搜索分页信息,返回含页码数,页大小,总页数,总记录数,当前页数据等信息,并根据时间降序,浏览量降序排序
uri:
portal/findNewsPage
请求方式:
POST
- 请求参数:
{
"keyWords":"马斯克", // 搜索标题关键字
"type":0, // 新闻类型
"pageNum":1, // 页码数(当前页码)
"pageSize":"10" // 页大小(一页10条显示数据
}
- 响应示例:
{
"code":"200",
"message":"success"
"data":{
"pageInfo":{
"pageData":[ // 本页的数据
{
"hid":"1", // 新闻id
"title":"尚硅谷宣布 ... ...", // 新闻标题
"type":"1", // 新闻所属类别编号
"pageViews":"40", // 新闻浏览量
"pastHours":"3" , // 发布时间已过小时数
"publisher":"1" // 发布用户ID
},
{
"hid":"1", // 新闻id
"title":"尚硅谷宣布 ... ...", // 新闻标题
"type":"1", // 新闻所属类别编号
"pageViews":"40", // 新闻浏览量
"pastHours":"3", // 发布时间已过小时数
"publisher":"1" // 发布用户ID
},
{
"hid":"1", // 新闻id
"title":"尚硅谷宣布 ... ...", // 新闻标题
"type":"1", // 新闻所属类别编号
"pageViews":"40", // 新闻浏览量
"pastHours":"3", // 发布时间已过小时数
"publisher":"1" // 发布用户ID
}
],
"pageNum":1, //页码数
"pageSize":10, // 页大小
"totalPage":20, // 总页数
"totalSize":200 // 总记录数
}
}
}
代码实现:
3.2.1 controller
@WebServlet("/portal/*")
public class PortalController extends BaseController {
private NewsTypeService typeService = new NewsTypeServiceImpl();
private NewsHeadlineService headlineService = new NewsHeadlineServiceImpl();
/**
* 分页带条件查询新闻
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void findNewsPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HeadlineQueryVo headlineQueryVo = WebUtil.readJson(req, HeadlineQueryVo.class);
//查询分页五项数据
Map<String,Object> pageInfo = headlineService.findPage(headlineQueryVo);
//将分页五项数据放入
Map<String, Object> pageInfoMap = new HashMap<>();
pageInfoMap.put("pageInfo",pageInfo);
WebUtil.writeJson(resp,Result.ok(pageInfoMap));
}
3.2.2 service
public interface NewsHeadlineService {
/**
* 分页查询头条新闻方法
* @param headlineQueryVo
* @return
*/
Map<String, Object> findPage(HeadlineQueryVo headlineQueryVo);
}
public class NewsHeadlineServiceImpl implements NewsHeadlineService {
private NewsHeadLineDao headLineDao = new NewsHeadlineDaoImpl();
@Override
public Map<String, Object> findPage(HeadlineQueryVo headlineQueryVo) {
// 准备一个map,用于装分页的五项数据
Map<String, Object> pageInfo = new HashMap<>();
// 分页查询本页数据新闻
List<HeadlinePageVo> pageData = headLineDao.findPageList(headlineQueryVo);
// 当前 页码数
int pageNum = headlineQueryVo.getPageNum();
// 页大小
int pageSize = headlineQueryVo.getPageSize();
// 总记录数
int totalSize = headLineDao.findPageCount(headlineQueryVo);
// 总页数(多出一条数据的情况 +1页上去
int totalPage = totalSize % pageSize == 0 ? totalSize / pageSize : totalSize / pageSize + 1;
pageInfo.put("pageData",pageData);
pageInfo.put("pageNum",pageNum);
pageInfo.put("pageSize",pageSize);
pageInfo.put("totalPage",totalPage);
pageInfo.put("totalSize",totalSize);
return pageInfo;
}
}
3.2.3 dao
public interface NewsHeadLineDao {
/**
* 根据查询条件,查询当前页数据
* @param headlineQueryVo
* @return
*/
List<HeadlinePageVo> findPageList(HeadlineQueryVo headlineQueryVo);
/**
* 根据查询条件,查询满足条件的记录数
* @param headlineQueryVo
* @return
*/
int findPageCount(HeadlineQueryVo headlineQueryVo);
}
package com.doug.headline.dao.impl;
import com.doug.headline.dao.BaseDao;
import com.doug.headline.dao.NewsHeadLineDao;
import com.doug.headline.pojo.vo.HeadlinePageVo;
import com.doug.headline.pojo.vo.HeadlineQueryVo;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class NewsHeadlineDaoImpl extends BaseDao implements NewsHeadLineDao {
@Override
public List<HeadlinePageVo> findPageList(HeadlineQueryVo headlineQueryVo) {
List params = new ArrayList();
String sql = """
select
hid,
title,
type,
page_views pageViews,
TIMESTAMPDIFF(HOUR,create_time,now()) pastHours,
publisher
from
news_headline
where
is_deleted = 0
""";
if(headlineQueryVo.getType() != 0){
sql = sql.concat(" and type = ? ");
params.add(headlineQueryVo.getType());
}
if(headlineQueryVo.getKeyWords() != null && !headlineQueryVo.getKeyWords().equals("")){
sql = sql.concat(" and title like ? ");
params.add("%"+headlineQueryVo.getKeyWords()+"%");
}
// 按时间升序 浏览量降序
sql = sql.concat(" order by pastHours ASC , page_views DESC ");
// 分页显示
sql = sql.concat(" limit ?,? ");
params.add((headlineQueryVo.getPageNum()-1)*headlineQueryVo.getPageSize());
params.add(headlineQueryVo.getPageSize());
return baseQuery(HeadlinePageVo.class,sql,params.toArray());
}
@Override
public int findPageCount(HeadlineQueryVo headlineQueryVo) {
// 拼接动态 SQL,拼接参数
List args = new LinkedList<>();
String sql = "select count(1) from news_headline where is_deleted = 0";
StringBuilder sqlBuffer = new StringBuilder(sql);
String keyWords = headlineQueryVo.getKeyWords();
//判断并动态拼接条件
if(null != keyWords && keyWords.length() > 0){
sqlBuffer.append(" and title like ? ");
args.add("%" + keyWords + "%");
}
// 判断并动态拼接条件
Integer type = headlineQueryVo.getType();
if(null != type && type!=0){
sqlBuffer.append(" and type = ? ");
args.add(type);
}
// 参数转数组
Object[] argsArr = args.toArray();
System.out.println(sqlBuffer.toString());
Long totalSize = baseQueryObject(Long.class, sqlBuffer.toString(), argsArr);
return totalSize.intValue();
}
}
3.3 查看头条详情
- 用户点击"查看全文"时,向服务端发送新闻id
- 后端根据新闻id查询完整新闻文章信息并返回
- 后端要同时让新闻的浏览量+1
URI :
portal/showHeadlineDetail
请求方式 :POST
请求参数:hid = 1
响应示例:
{
"code":"200",
"message":"success",
"data":{
"headline":{
"hid":"1", // 新闻id
"title":"马斯克宣布 ... ...", // 新闻标题
"article":"... ..." // 新闻正文
"type":"1", // 新闻所属类别编号
"typeName":"科技", // 新闻所属类别
"pageViews":"40", // 新闻浏览量
"pastHours":"3" , // 发布时间已过小时数
"publisher":"1" , // 发布用户ID
"author":"张三" // 新闻作者
}
}
}
代码实现:
3.3.1 controller
/**
* 查询单个新闻详情
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void showHeadlineDetail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取要查询的详情新闻id
Integer hid = Integer.valueOf(req.getParameter("hid"));
// 封装data内容
HashMap<String, Object> headlineInfo = new HashMap<>();
// 查询新闻详情的vo
HeadlineDetailVo headlineDetailVo = headlineService.findHeadlineByHid(hid);
Result result = null;
if(null != headlineDetailVo){
headlineInfo.put("headline",headlineDetailVo);
result = Result.ok(headlineInfo);
}
WebUtil.writeJson(resp,result);
}
3.3.2 service
/**
* 根据hid 查看单个新闻详情
* @param hid
* @return
*/
HeadlineDetailVo findHeadlineByHid(Integer hid);
@Override
public HeadlineDetailVo findHeadlineByHid(Integer hid) {
// 修改新闻信息浏览量+1
headLineDao.increasePageViews(hid);
// 查询新闻详情
return headLineDao.findHeadlineInfoByHid(hid);
}
3.3.3 dao
/**
* 根据 hid 查看详细新闻
* @param hid 新闻对应ID
* @return
*/
HeadlineDetailVo findHeadlineInfoByHid(Integer hid);
/**
* 新闻浏览量+1
* @param hid
* @return
*/
int increasePageViews(Integer hid);
@Override
public HeadlineDetailVo findHeadlineInfoByHid(Integer hid) {
String sql = """
select
h.hid,
h.title,
h.article,
h.type,
h.page_views as pageViews,
TIMESTAMPDIFF(HOUR,create_time,now()) pastHours,
h.publisher,
t.tname as typeName,
u.nick_name as author
from
news_headline h
left join
news_type t
on
h.type = t.tid
left join
news_user u
on
h.publisher = u.uid
where
h.hid = ?
""";
List<HeadlineDetailVo> headlineDetailVoList = baseQuery(HeadlineDetailVo.class, sql, hid);
if (null != headlineDetailVoList && headlineDetailVoList.size() > 0) {
return headlineDetailVoList.get(0);
}
return null;
}
@Override
public int increasePageViews(Integer hid) {
String sql = "update news_headline set page_views = page_views +1 where hid = ?";
return baseUpdate(sql, hid);
}
四、头条发布修改和删除
4.1 登录校验
- 客户端在进入发布页前、发布新闻前、进入修改页前、修改前、删除新闻前先向服务端发送请求携带token请求头
- 后端接收token请求头后,校验用户登录是否过期并做响应
- 前端根据响应信息提示用户进入登录页还是进入正常业务页面
URI :
user/checkLogin
请求 : GET
请求头: token: … …
- 响应:
- 登录未过期
{
"code":"200",
"message":"success",
"data":{}
}
-
- 登录已过期
{
"code":"504",
"message":"loginExpired",
"data":{}
}
代码实现:
4.1.1 controller
/**
* 前端自行校验token登录是否过期
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void checkLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = req.getHeader("token");
Result result = Result.build(null, ResultCodeEnum.NOTLOGIN);
//token 不等于空 且 没有过期
if(null != token){
if(!JwtHelper.isExpiration(token)){
result = Result.ok(null);
}
}
WebUtil.writeJson(resp,result);
}
4.1.2 登录过滤器
/**
* @Author: Gavin
* @Date: 2024-02-07 21:58
* @Description: 过滤器自动校验请求是否过期(过滤所有/headline/*下的方法
*/
@WebFilter("/headline/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
String token = request.getHeader("token");
//boolean flag = false;
// token 不为空 且 没有过期
//if(null != token){
// boolean expiration = JwtHelper.isExpiration(token);
// if(!expiration){
// flag = true;
// }
//}
boolean flag = null != token && (!JwtHelper.isExpiration(token));
if(flag){
//放行 请求响应
filterChain.doFilter(servletRequest,servletResponse);
}else{
WebUtil.writeJson((HttpServletResponse) servletResponse, Result.build(null, ResultCodeEnum.NOTLOGIN));
}
}
}
4.1.3 web.xml中配置登录校验过滤器
<!--登录校验过滤器-->
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.doug.headline.filters.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/headline/*</url-pattern>
</filter-mapping>
4.2 提交发布头条(新增
- 用户在客户端输入发布的新闻信息完毕后
- 发布前先请求后端的登录校验接口验证登录
- 登录通过则提交新闻信息
- 后端将新闻信息存入数据库
URI :
headline/publish
请求方式 :POST
请求头 : token: … …
- 请求参数:
{
"title":"道格维克 ... ...", // 文章标题
"article":"... ...", // 文章内容
"type":"1" // 文章类别
}
- 响应示例:
- 响应发布
{
"code":"200",
"message":"success",
"data":{}
}
-
- 失去登录状态发布失败
{
"code":"504",
"message":"loginExpired",
"data":{}
}
代码实现:
4.2.1 controller
package com.doug.headline.controller;
import com.doug.headline.common.Result;
import com.doug.headline.pojo.NewsHeadline;
import com.doug.headline.service.NewsHeadlineService;
import com.doug.headline.service.impl.NewsHeadlineServiceImpl;
import com.doug.headline.util.JwtHelper;
import com.doug.headline.util.WebUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/headline/*")
public class NewsHeadlineController extends BaseController {
private NewsHeadlineService headlineService = new NewsHeadlineServiceImpl();
/**
* 发布新闻
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void publish(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 读取新闻信息
NewsHeadline newsHeadline = WebUtil.readJson(req, NewsHeadline.class);
// 通过token获取发布者ID
String token = req.getHeader("token");
Long userId = JwtHelper.getUserId(token);
newsHeadline.setPublisher(userId.intValue());
// 将新闻存入数据库
headlineService.addNewsHeadline(newsHeadline);
WebUtil.writeJson(resp, Result.ok(null));
}
}
4.2.2 seriver
/**
* 新增头条新闻
* @param newsHeadline
* @return
*/
int addNewsHeadline(NewsHeadline newsHeadline);
/**
* 发布新闻
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void publish(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 读取新闻信息
NewsHeadline newsHeadline = WebUtil.readJson(req, NewsHeadline.class);
// 通过token获取发布者ID
String token = req.getHeader("token");
Long userId = JwtHelper.getUserId(token);
newsHeadline.setPublisher(userId.intValue());
// 将新闻存入数据库
headlineService.addNewsHeadline(newsHeadline);
WebUtil.writeJson(resp, Result.ok(null));
}
4.2.3 dao
/**
* 增加新闻头条
* @param newsHeadline
* @return
*/
int addNewsHeadline(NewsHeadline newsHeadline);
@Override
public int addNewsHeadline(NewsHeadline newsHeadline) {
String sql = """
insert into
news_headline
values(DEFAULT,?,?,?,?,0,NOW(),NOW(),0)
""";
return baseUpdate(sql,
newsHeadline.getTitle(),
newsHeadline.getArticle(),
newsHeadline.getType(),
newsHeadline.getPublisher());
}
添加成功:
4.3 修改头条回显
- 前端先调用登录校验接口,校验登录是否过期
- 登录校验通过后 ,则根据新闻id查询新闻的完整信息并响应给前端
URI :
headline/findHeadlineByHid
请求方式:POST
请求参数:hid=1
- 响应实例:
- 查询成功
{
"code":"200",
"message":"success",
"data":{
"headline":{
"hid":"1",
"title":"马斯克宣布",
"article":"... ... ",
"type":"2"
}
}
}
4.3.1 controller
/**
* 修改新闻信息
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void findHeadlineByHid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Integer hid = Integer.valueOf(req.getParameter("hid"));
HeadlineDetailVo headlineByHid = headlineService.findHeadlineByHid(hid);
HashMap<String, Object> headlineMap = new HashMap<>();
Result result = null;
if(null != headlineByHid){
headlineMap.put("headline",headlineByHid);
result = Result.ok(headlineMap);
}
WebUtil.writeJson(resp,result);
}
4.4 保存修改
- 客户端将新闻信息修改后,提交前先请求登录校验接口校验登录状态
- 登录校验通过则提交修改后的新闻信息,后端接收并更新进入数据库
URI:
headline/update
请求方式:post
- 请求参数:
{
"hid":"1",
"title":"道格维克 ... ...",
"article":"... ...",
"type":"2"
}
- 响应实例:
修改成功:
{
"code":"200",
"message":"success",
"data":{}
}
修改失败:
{
"code":"504",
"message":"loginExpired",
"data":{}
}
代码实现:
4.4.1 controller
/**
* 修改新闻信息
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
NewsHeadline newsHeadline = WebUtil.readJson(req, NewsHeadline.class);
headlineService.updateHeadline(newsHeadline);
WebUtil.writeJson(resp,Result.ok(null));
}
4.4.2 service
/**
* 修改新闻信息
* @param newsHeadline
* @return
*/
int updateHeadline(NewsHeadline newsHeadline);
@Override
public int updateHeadline(NewsHeadline newsHeadline) {
return headLineDao.updateHeadlineInfo(newsHeadline);
}
4.4.3 dao
/**
* 修改新闻信息
* @param newsHeadline
* @return
*/
int updateHeadlineInfo(NewsHeadline newsHeadline);
@Override
public int updateHeadlineInfo(NewsHeadline newsHeadline) {
String sql = "update news_headline set title = ?,article = ?,type = ? ,update_time = now() where hid = ?";
return baseUpdate(sql, newsHeadline.getTitle(),
newsHeadline.getArticle(),
newsHeadline.getType(),
newsHeadline.getHid());
}
4.5 删除头条
- 将要删除的新闻id发送给服务端
- 服务端校验登录是否过期,未过期则直接删除,过期则响应登录过期信息
URI :
headline/removeByHid
请求方式:POST
请求参数:hid=1
- 响应实例:
删除成功
{
"code":"200",
"message":"success",
"data":{}
}
删除失败
{
"code":"504",
"message":"loginExpired",
"data":{}
}
- controller:
/**
* 删除对应Hid的新闻
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void removeByHid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Integer hid = Integer.parseInt(req.getParameter("hid"));
headlineService.removeByHid(hid);
WebUtil.writeJson(resp,Result.ok(null));
}
- service
/**
* 删除单个新闻
* @param hid 新闻hid
* @return
*/
int removeByHid(Integer hid);
@Override
public int removeByHid(Integer hid) {
return headLineDao.removeByHid(hid);
}
- dao
/**
* 删除对应hid的新闻
* @param hid
* @return
*/
int removeByHid(Integer hid);
@Override
public int removeByHid(Integer hid) {
String sql = "update news_headline set is_deleted = 1, update_time = NOW() where hid = ?";
return baseUpdate(sql, hid);
}