JAVAWeb实战(后端篇)

news2024/11/20 14:29:09

因为前后端代码内容过多,这篇只写后端的代码,前端的在另一篇写

项目实战一:

1.创建数据库,表等数据

创建数据库

create database schedule_system

创建表,并添加内容

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;


-- ----------------------------
-- 创建日程表
-- ----------------------------
DROP TABLE IF EXISTS `sys_schedule`;
CREATE TABLE `sys_schedule`  (
  `sid` int NOT NULL AUTO_INCREMENT,
  `uid` int NULL DEFAULT NULL,
  `title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `completed` int(1) NULL DEFAULT NULL,
  PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- 插入日程数据
-- ----------------------------

-- ----------------------------
-- 创建用户表
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `uid` int NOT NULL AUTO_INCREMENT,
  `username` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `user_pwd` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`uid`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- 插入用户数据
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'zhangsan', 'e10adc3949ba59abbe56e057f20f883e');
INSERT INTO `sys_user` VALUES (2, 'lisi', 'e10adc3949ba59abbe56e057f20f883e');

SET FOREIGN_KEY_CHECKS = 1;

2.创建项目并导入一些需要的jar包

2.1项目结构

c1626e4f3e104f6c9129aa384e1281ed.png

2.2导入依赖

 <!--servlet项目所需依赖-->
        <!--
          druid 连接池
          json的一些依赖
          jackson-annotations
          jackson-core
          jackson-databind
          lombok              简化实体类
          mysql-connector     数据库驱动
           jakarta.servlet-api  servlet需要的
          -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.23</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.13.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.13.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.1.0</version>
        </dependency>

2.3创建jdbc.properties文件

jdbc.user=root
jdbc.password=123456
jdbc.url=jdbc:mysql:///schedule_system
jdbc.driver=com.mysql.cj.jdbc.Driver

3.创建实体类

因为我数据库两个表名分别叫sys_schedule和sys_user

所以为了方便起见我的实体表为:SysSchedule和SysUser

属性名称要和数据库表的字段名称最好保持一致

如果数据库表字段名称式驼峰式的 比如 sys_id  实体表属性可以设置为 sysId

将下划线后的那个字母设置为大写

 SysUser实体类


/*
* 1 实体类的类名和表格名称应该对应  (对应不是一致)
* 2 实体类的属性名和表格的列名应该对应
* 3 每个属性都必须是私有的
* 4 每个属性都应该具备 getter setter
* 5 必须具备无参构造器
* 6 应该实现序列化接口( 缓存  分布式项目数据传递 可能会将对象序列化 )
* 7 应该重写类的hashcode和equals方法
* 8 toString是否重写都可以
*
*
* 使用lombok帮助我们生成这些内容 getter setter  全参构造 无参构造 equals  hashcode
*   lombok使用步骤
*       1 检查idea是否已经安装了lombok插件
*       2 检查是否勾选了 enable  annotation processing
*       3 导入lombok的依赖
*
*
* */

@AllArgsConstructor // 添加了全参构造
@NoArgsConstructor  // 添加了无参构造
@Data //getter setter   equals  hashcode toString
public class SysUser implements Serializable {
    private Integer uid;
    private String username;
    private String userPwd;

}

SysSchedule实体类

@AllArgsConstructor
@NoArgsConstructor
@Data
public class SysSchedule implements Serializable {
    private Integer sid;
    private Integer uid;
    private  String title;
    private Integer completed;
}

4.创建全局统一json响应格式

4.1 创建一个枚举类(里面设置一些响应码和响应消息)

public enum ResultCodeEnum {
    SUCCESS(200,"success"),
    USERNAEM_ERROR(501,"usernameError"),
    PASSWORD_ERROR(503,"passwordError"),
    NOTLOGIN(504,"notlogin"),
    USERNAME_USED(505,"usernameUsed");



    private Integer code;
    private String message;
    private ResultCodeEnum(Integer code ,String message){
        this.code= code;
        this.message = message;

    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

4.2创建全局统一json响应格式类

package org.example.common;

//全局统一响应的JSON格式处理类
public class Result <T>{   //因为不确定返回消息是什么类型 ,所以这里声明了<T>
    // 返回码
    private Integer code;
    // 返回消息
    private String message;
    // 返回数据
    private T data;
    public Result(){}
    // 返回数据
    protected static <T> Result<T> build(T data) {   //将data添加进去
        Result<T> result = new Result<T>();
        if (data != null)
            result.setData(data);
        return result;            //返回一个result对象
    }
    public static <T> Result<T> build(T body, Integer code, String message) { //
        Result<T> result = build(body);  // 创建一个result对象,并添加data对象
        result.setCode(code);
        result.setMessage(message);
        return result;
    }
    public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
        Result<T> result = build(body);       //创建result对象并添加data数据
        result.setCode(resultCodeEnum.getCode());  //给响应码添加枚举类中的数据
        result.setMessage(resultCodeEnum.getMessage()); //给响应消息添加枚举类中的数据
        return result;
    }
    /**
     * 操作成功
     * @param data  baseCategory1List
     * @param <T>
     * @return
     */
    public static<T> Result<T> ok(T data){          //返回一个result对象,这是一个操作成功的数据,如果操作成功就执行它
        Result<T> result = build(data);    //创建result对象并添加data数据
        return build(data, ResultCodeEnum.SUCCESS); //调用上面的方法,将枚举类中的ResultCodeEnum.SUCCESS赋值给响应码和响应消息并返回result
    }
    public Result<T> message(String msg){          
        this.setMessage(msg);
        return this;
    }
    public Result<T> code(Integer code){     
        this.setCode(code);
        return this;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}

5.设置一些工具类

5.1MD5加密(固定格式需要的时候复制一下)

public class MD5Util {
    public static String encrypt(String strSrc) {
        try {
            char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            byte[] bytes = strSrc.getBytes();  //使用平台的默认字符集将此 String 编码为 byte 序列,并 将结果存储到一个新的 byte 数组中。
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(bytes);
            bytes = md.digest();
            int j = bytes.length;
            char[] chars = new char[j * 2];
            int k = 0;
            for (int i = 0; i < bytes.length; i++) {
                byte b = bytes[i];
                chars[k++] = hexChars[b >>> 4 & 0xf];
                chars[k++] = hexChars[b & 0xf];
            }
            return new String(chars);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("MD5加密出错");
        }

    }

}

5.2 创建导入jdbc.properties和生成Connection对象的工具类(需要的时候复制就可以)

package org.example.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtil {
    private static ThreadLocal<Connection> threadLocal =new ThreadLocal<>();
    private static DataSource dataSource;
    // 初始化连接池
    static{
        // 可以帮助我们读取.properties配置文件
        Properties properties =new Properties();
        InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            properties.load(resourceAsStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }
    /*1 向外提供连接池的方法*/
    public static DataSource getDataSource(){
        return dataSource;
    }

    /*2 向外提供连接的方法*/
    public static Connection getConnection(){
        Connection connection = threadLocal.get();
        if (null == connection) {
            try {
                connection = dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            threadLocal.set(connection);
        }

        return connection;
    }


    /*定义一个归还连接的方法 (解除和ThreadLocal之间的关联关系) */
    public static void releaseConnection(){
        Connection connection = threadLocal.get();
        if (null != connection) {
            threadLocal.remove();
            // 把连接设置回自动提交的连接
            try {
                connection.setAutoCommit(true);
                // 自动归还到连接池
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

5.3创建WEBUtil工具类(需要的时候复制就可以,用来转化json和将json响应出去的)

package org.example.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.common.Result;

import java.io.BufferedReader;
import java.io.IOException;
import java.text.SimpleDateFormat;

public class WebUtil {
    private static ObjectMapper objectMapper;
    // 初始化objectMapper
    static{
        objectMapper=new ObjectMapper();
        // 设置JSON和Object转换时的时间日期格式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }
    // 从请求中获取JSON串并转换为Object
    public static <T> T readJson(HttpServletRequest request, Class<T> clazz){
        T t =null;
        BufferedReader reader = null;
        try {
            reader = request.getReader();
            StringBuffer buffer =new StringBuffer();
            String line =null;
            while((line = reader.readLine())!= null){
                buffer.append(line);
            }

            t= objectMapper.readValue(buffer.toString(),clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return t;
    }
    // 将Result对象转换成JSON串并放入响应对象
    public static void writeJson(HttpServletResponse response, Result result){
        response.setContentType("application/json;charset=UTF-8");
        try {
            String json = objectMapper.writeValueAsString(result);
            response.getWriter().write(json);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

5.4创建一个统一对数据增删改查的工具类(需要的时候复制粘贴)

package org.example.dao;

import org.example.util.JDBCUtil;

import java.lang.reflect.Field;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class BaseDao {
    public <T> T baseQueryObject(Class<T> clazz, String sql, Object ... args) {
        T t = null;
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        int rows = 0;
        try {
            // 准备语句对象
            preparedStatement = connection.prepareStatement(sql);
            // 设置语句上的参数
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }

            // 执行 查询
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                t = (T) resultSet.getObject(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != resultSet) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
            JDBCUtil.releaseConnection();
        }
        return t;
    }
    // 公共的查询方法  返回的是对象的集合

    public <T> List<T> baseQuery(Class clazz, String sql, Object ... args){
        List<T> list =new ArrayList<>();
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement preparedStatement=null;
        ResultSet resultSet =null;
        int rows = 0;
        try {
            // 准备语句对象
            preparedStatement = connection.prepareStatement(sql);
            // 设置语句上的参数
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

            // 执行 查询
            resultSet = preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();

            // 将结果集通过反射封装成实体类对象
            while (resultSet.next()) {
                // 使用反射实例化对象
                Object obj =clazz.getDeclaredConstructor().newInstance();

                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnLabel(i);
                    Object value = resultSet.getObject(columnName);
                    // 处理datetime类型字段和java.util.Data转换问题
                    if(value.getClass().equals(LocalDateTime.class)){
                        value= Timestamp.valueOf((LocalDateTime) value);
                    }
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(obj,value);
                }

                list.add((T)obj);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null !=resultSet) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            JDBCUtil.releaseConnection();
        }
        return list;
    }

    // 通用的增删改方法
    public int baseUpdate(String sql,Object ... args) {
        // 获取连接
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement preparedStatement=null;
        int rows = 0;
        try {
            // 准备语句对象
            preparedStatement = connection.prepareStatement(sql);
            // 设置语句上的参数
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

            // 执行 增删改 executeUpdate
            rows = preparedStatement.executeUpdate();
            // 释放资源(可选)


        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }

            }
            JDBCUtil.releaseConnection();
        }
        // 返回的是影响数据库记录数
        return rows;
    }
}

6.创建跨域过滤器和登入过滤器

6.1跨域过滤器(需要的时候复制)

未来我们使用框架,फ接用一个@CrossOrigin 就可以解决跨ֿ域了。

package org.example.filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebFilter("/*")
public class CrosFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        System.out.println(request.getMethod());
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT,OPTIONS, DELETE, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
        // 非预检请求,放行即可,预检请求,则到此结束,不需要放行
        if(!request.getMethod().equalsIgnoreCase("OPTIONS")){
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
}

 6.2登入过滤器

没有登入的话不允许访问其他网页,直接重定向到登入界面。

登入成功才可以访问其他网页

public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 参数父转子
        HttpServletRequest request =(HttpServletRequest)  servletRequest;
        HttpServletResponse response  =(HttpServletResponse) servletResponse;
        // 获得session域对象
        HttpSession session = request.getSession();
        // 从session域中获得登录的用户对象
        SysUser sysUser = (SysUser)session.getAttribute("sysUser");
        // 判断用户对象是否为空
        if(null == sysUser){
            // 没登录 到login.html
            response.sendRedirect("/login.html");
        }else{
            // 登录过 放行
            filterChain.doFilter(request,response);
        }
    }
}

 7.三层架构(service,dao,servlet)

7.0创建全局处理servlet类(重点)

//全局处理servlet
public class BaseContoller extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String requestURI = req.getRequestURI(); // /schedule/add
        String[] split = requestURI.split("/");
        String methodName = split[split.length-1];
        // 使用 反射 通过方法名获取下面的方法
        Class aClass = this.getClass();
        // 获取方法
        try {
            Method declaredMethod = aClass.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

            //暴力 破解方法的访问修饰符的限制
            declaredMethod.setAccessible(true);

            // 执行方法
            declaredMethod.invoke(this,req,resp);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

7.1.1 SysUser dao层

SysUserdao 接口

public interface SysUserDao {
    /**
     * 向数据库中增加一条用户记录的方法
     * @param sysUser 要增加的记录的username和user_pwd字段以SysUser实体类对象的形式接收
     * @return 增加成功返回1 增加失败返回0
     */
    int addSysUser(SysUser sysUser);

    /**
     * 根据用户名获得完整用户信息的方法
     * @param username 要查询的用户名
     * @return 如果找到了返回SysUser对象,找不到返回null
     */
    SysUser findByUsername(String username);
}

实现类

这里实现了SysUserdao接口,并且还继承了BaseDao工具类,所以可以直接使用它的方法

public class SysUserDaoImpl extends BaseDao implements SysUserDao {


    //注册账户
    @Override
    public int addSysUser(SysUser sysUser) {
        String sql ="insert into sys_user values(DEFAULT,?,?)";
        return baseUpdate(sql,sysUser.getUsername(),sysUser.getUserPwd());
    }

    //验证账户是否已被占用,登入账户,两个功能
    @Override
    public SysUser findByUsername(String username) {
        String sql ="select uid,username,user_pwd userPwd from sys_user where username = ?";
        List<SysUser> sysUserList = baseQuery(SysUser.class, sql, username);
        return sysUserList!= null && sysUserList.size()>0? sysUserList.get(0): null ;
    }
}

7.1.2service层

SysUserService接口

public interface SysUserService {

    /**
     * 注册用户的方法
     * @param sysUser 要注册的用户名和明文密码以SysUser对象的形式接收
     * @return 注册成功返回1 注册失败返回0
     */
    int regist(SysUser sysUser);

    /**
     * 根据用户名获得完整用户信息的方法
     * @param username 要查询的用户名
     * @return 如果找到了返回SysUser对象,找不到返回null
     */
    SysUser findByUsername(String username);
}

SysUserService接口实现类

public class SysUserServiceImpl implements SysUserService {
    private SysUserDao userDao =new SysUserDaoImpl();
    @Override
    public int regist(SysUser sysUser) {

        // 将用户的明文密码转换为密文密码
        sysUser.setUserPwd(MD5Util.encrypt(sysUser.getUserPwd()));
        // 调用DAO 层的方法  将sysUser信息存入数据库
        return userDao.addSysUser(sysUser);
    }

    @Override
    public SysUser findByUsername(String username) {
        return userDao.findByUsername(username);
    }
}

7.1.3servlet层

package org.example.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.common.Result;
import org.example.common.ResultCodeEnum;
import org.example.pojo.SysUser;
import org.example.service.SysUserService;
import org.example.service.imp.SysUserServiceImpl;
import org.example.util.MD5Util;
import org.example.util.WebUtil;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/user/*")
public class SysUserController  extends BaseContoller {

    private SysUserService userService = new SysUserServiceImpl();



    /**
     * 注册时,接收要注册的用户名,校验用户名是否被占用的业务接口
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    //注册的时候,看当前用户名是否被占用
    protected void checkUsernameUsed(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收用户名
        String username = req.getParameter("username");

        // 调用服务层业务处理方法查询该用于名是否有对应的用户
        SysUser sysUser = userService.findByUsername(username);
        // 如果有 响应 已占用
        // 如果没有 响应 可用

        Result result = Result.ok(null);

        if (null != sysUser) {
            result = Result.build(null, ResultCodeEnum.USERNAME_USED);
        }
        // 将result对象转换为JSON串响应给客户端
        WebUtil.writeJson(resp, result);
    }

    /**
     * 接收用登录请求,完成的登录业务接口
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    //登入
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 接收用户名和密码
        SysUser sysUser = WebUtil.readJson(req, SysUser.class);
        //2 调用服务层方法,根据用户名查询用户信息
        SysUser loginUser = userService.findByUsername(sysUser.getUsername());

        Result result = null;

        if (null == loginUser) {
            result = Result.build(null, ResultCodeEnum.USERNAEM_ERROR);

        } else if (!MD5Util.encrypt(sysUser.getUserPwd()).equals(loginUser.getUserPwd())) {
            result = Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
        } else {
            // 登录程序,将用户uid和username响应给客户端
            Map data = new HashMap();
            loginUser.setUserPwd("");
            data.put("loginUser", loginUser);
            result = Result.ok(data);
        }
        // 3将登录结果响应给客户端
        WebUtil.writeJson(resp, result);

    }

    /**
     * 接收用户注册请求的业务处理方法( 业务接口 不是java中的interface  )
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    //注册
    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1 接收客户端提交的json参数,并转换为User对象,获取信息
        SysUser registUer = WebUtil.readJson(req, SysUser.class);

        // 2 调用服务层方法,完成注册功能
        //将参数放入一个SysUser对象中,在调用regist方法时传入
        int rows = userService.regist(registUer);
        // 3 根据注册结果(成功  失败) 做页面跳转
        Result result = Result.ok(null);
        if (rows < 1) {
            result = Result.build(null, ResultCodeEnum.USERNAME_USED);
        }
        WebUtil.writeJson(resp, result);
    }
}

7.2.1 SysSchedule  dao层

SysScheduleDao接口

public interface SysScheduleDao {
    /**
     * 用于向数据中增加一条日程记录
     * @param schedule 日程数据以SysSchedule实体类对象形式入参
     * @return 返回影响数据库记录的行数, 行数为0说明增加失败,行数大于0说明增加成功
     */
    int addSchedule(SysSchedule schedule);


    /**
     * 查询所有用户的所有日程
     * @return 将所有日程放入一个:List<SysSchedule>集合中返回
     */
    List<SysSchedule> findAll();

    List<SysSchedule> findItemListByUid(int uid);

    Integer addDefault(int uid);

    Integer updateSchedule(SysSchedule schedule);

    Integer removeSchedule(int sid);
}

对应的实现类

public class SysScheduleDaoImpl extends BaseDao implements SysScheduleDao {
    @Override
    public int addSchedule(SysSchedule schedule) {
        String sql ="insert into sys_schedule values(DEFAULT,?,?,?)";
        int rows = baseUpdate(sql,schedule.getUid(),schedule.getTitle(),schedule.getCompleted());
        return rows;
    }

    @Override
    public List<SysSchedule> findAll() {
        String sql ="select sid,uid,title,completed from sys_schedule";
        List<SysSchedule> scheduleList = baseQuery(SysSchedule.class, sql);
        return scheduleList;
    }

    @Override
    public List<SysSchedule> findItemListByUid(int uid) {
        String sql = "select sid ,uid,title,completed from sys_schedule where uid = ? ";
        List<SysSchedule> itemList = baseQuery(SysSchedule.class, sql, uid);
        return itemList;
    }

    @Override
    public Integer addDefault(int uid) {
        String sql = "insert into sys_schedule values (DEFAULT,?,'请输入日程',0) ";
        return baseUpdate(sql,uid);
    }

    @Override
    public Integer updateSchedule(SysSchedule schedule) {
        String sql ="update sys_schedule set title = ? ,completed = ?  where  sid = ?";
        return baseUpdate(sql,schedule.getTitle(),schedule.getCompleted(),schedule.getSid());
    }

    @Override
    public Integer removeSchedule(int sid) {
        String sql = "delete from sys_schedule where sid = ?";
        return baseUpdate(sql,sid);
    }
}

7.2.2service层

接口

public interface SysScheduleService {
    List<SysSchedule> findItemListByUid(int uid);

    Integer addDefault(int uid);

    Integer updateSchedule(SysSchedule schedule);

    Integer removeSchedul(int sid);
}

实现类

public class SysScheduleServiceImpl implements SysScheduleService {
    private SysScheduleDao scheduleDao =new SysScheduleDaoImpl();

    @Override
    public List<SysSchedule> findItemListByUid(int uid) {
        return scheduleDao.findItemListByUid(uid);
    }

    @Override
    public Integer addDefault(int uid) {
        return scheduleDao.addDefault(uid);
    }

    @Override
    public Integer updateSchedule(SysSchedule schedule) {
        return scheduleDao.updateSchedule(schedule);
    }

    @Override
    public Integer removeSchedul(int sid) {
        return scheduleDao.removeSchedule(sid);
    }
}

7.2.3servlet层

@WebServlet( "/schedule/*")
public class SysScheduleController extends BaseContoller {
    private SysScheduleService scheduleService =new SysScheduleServiceImpl();

    protected void removeSchedule(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int sid = Integer.parseInt(req.getParameter("sid"));
        // 调用服务层方法 删除数据
        scheduleService.removeSchedul(sid);
        // 响应  成功信息

        WebUtil.writeJson(resp, Result.ok(null));



    }

    protected void updateSchedule(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收请求体中的JSON串 转换成一个SysSchedule
        SysSchedule schedule = WebUtil.readJson(req, SysSchedule.class);
        // 调用服务层方法,将信息更新进入数据
        scheduleService.updateSchedule(schedule);

        WebUtil.writeJson(resp,Result.ok(null));



    }

    protected void addDefaultSchedule(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收请求中的uid参数
        int uid =Integer.parseInt(req.getParameter("uid"));
        // 调用服务层方法,向数据库中 增加一条 空记录
        scheduleService.addDefault(uid);

        WebUtil.writeJson(resp,Result.ok(null));
    }

    protected void findAllSchedule(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收请求中的uid参数
        int uid =Integer.parseInt(req.getParameter("uid"));

        // 查询用户的所有日程
        List<SysSchedule> itemList =scheduleService.findItemListByUid(uid);

        // 将用户的所有日程放入一个Result对象
        Map data =new HashMap();
        data.put("itemList",itemList);

        Result result = Result.ok(data);
        // 将Result对象转换为json响应给客户端
        WebUtil.writeJson(resp,result);
    }
}

项目实战一结束

项目实战二

全局json统一返回类省略

枚举类省略 

MD5工具类省略

jdbc需要的两个工具类省略(一个引入properties和创建Conn对象的类,一个增删改查的类)

跨域过滤器省略

Webutil省略

全局处理servlet类省略

需要的jar包和上面的的一样

jdbc..properties文件省略

以上参考上一个项目,可直接复制粘贴,这里就不展示了

在上面那个的基础上,新增两个jar包,用于token

     <!--token-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

1.创建数据库,表等操作

1.1创建数据库

create database top_news

1.2创建数据库表,并添加数据 

DROP TABLE IF EXISTS `news_headline`;
CREATE TABLE `news_headline`  (
  `hid` int NOT NULL AUTO_INCREMENT COMMENT '头条id',
  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '头条标题',
  `article` varchar(5000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '头条新闻内容',
  `type` int NOT NULL COMMENT '头条类型id',
  `publisher` int NOT NULL COMMENT '头条发布用户id',
  `page_views` int NOT NULL COMMENT '头条浏览量',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '头条发布时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '头条最后的修改时间',
  `is_deleted` int NULL DEFAULT NULL COMMENT '头条是否被删除 1 删除  0 未删除',
  PRIMARY KEY (`hid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of news_headline
-- ----------------------------
INSERT INTO `news_headline` VALUES (1, 'aaasd', 1, 1, 0, '2023-06-25 09:26:20', '2023-06-25 09:26:20', 0);
INSERT INTO `news_headline` VALUES (2, 'bbbb', 1, 1, 0, '2023-06-25 09:28:06', '2023-06-25 09:28:06', 0);
INSERT INTO `news_headline` VALUES (3, 'ccc。', 1, 1, 0, '2023-06-25 09:31:00', '2023-06-25 09:31:00', 0);
INSERT INTO `news_headline` VALUES (4, 'ddd', 1, 1, 0, '2023-06-25 09:31:36', '2023-06-25 09:31:36', 0);

-- ----------------------------
-- Table structure for news_type
-- ----------------------------
DROP TABLE IF EXISTS `news_type`;
CREATE TABLE `news_type`  (
  `tid` int NOT NULL AUTO_INCREMENT COMMENT '新闻类型id',
  `tname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '新闻类型描述',
  PRIMARY KEY (`tid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of news_type
-- ----------------------------
INSERT INTO `news_type` VALUES (1, '新闻');
INSERT INTO `news_type` VALUES (2, '体育');
INSERT INTO `news_type` VALUES (3, '娱乐');
INSERT INTO `news_type` VALUES (4, '科技');
INSERT INTO `news_type` VALUES (5, '其他');

-- ----------------------------
-- Table structure for news_user
-- ----------------------------
DROP TABLE IF EXISTS `news_user`;
CREATE TABLE `news_user`  (
  `uid` int NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户登录名',
  `user_pwd` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户登录密码密文',
  `nick_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户昵称',
  PRIMARY KEY (`uid`) USING BTREE,
  UNIQUE INDEX `username_unique`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of news_user
-- ----------------------------
INSERT INTO `news_user` VALUES (1, 'zhangsan', 'e10adc3949ba59abbe56e057f20f883e', '张三');
INSERT INTO `news_user` VALUES (2, 'lisi', 'e10adc3949ba59abbe56e057f20f883e', '李四');
INSERT INTO `news_user` VALUES (5, 'zhangxiaoming', 'e10adc3949ba59abbe56e057f20f883e', '张小明');
INSERT INTO `news_user` VALUES (6, 'xiaohei', 'e10adc3949ba59abbe56e057f20f883e', '李小黑');

SET FOREIGN_KEY_CHECKS = 1;
update news_headline set create_time=now() ,update_time=now()

2.创建JwtHelperٖ工具类

package org.example.util;

import com.alibaba.druid.util.StringUtils;
import io.jsonwebtoken.*;

import java.util.Date;

public class JwtHelper {
    private static long tokenExpiration = 24*60*60*1000;
    private static String tokenSignKey = "123456";

    //生成token字符串
    public static String createToken(Long userId) {
        String token = Jwts.builder()

                .setSubject("YYGH-USER")
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                .claim("userId", userId)
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }

    //从token字符串获取userid
    public static Long getUserId(String token) {
        if(StringUtils.isEmpty(token)) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        Integer userId = (Integer)claims.get("userId");
        return userId.longValue();
    }



    //判断token是否有效
    public static boolean isExpiration(String token){
        try {
            boolean isExpire = Jwts.parser()
                    .setSigningKey(tokenSignKey)
                    .parseClaimsJws(token)
                    .getBody()
                    .getExpiration().before(new Date());
            //没有过期,有效,返回false
            return isExpire;
        }catch(Exception e) {
            //过期出现异常,返回true
            return true;
        }
    }
}

3.创建实体类与它的vo

3.1实体类

NewsHeadline
@AllArgsConstructor
@NoArgsConstructor
@Data
public class NewsHeadline implements Serializable {
    private Integer hid;
    private String title;
    private String article;
    private Integer type;
    private Integer publisher;
    private Integer pageViews;
    private Date createTime;
    private Date updateTime;
    private Integer isDeleted;

}
NewsType
@AllArgsConstructor
@NoArgsConstructor
@Data
public class NewsType implements Serializable {
    private Integer tid;
    private String tname;
}
NewsUser
@AllArgsConstructor
@NoArgsConstructor
@Data
public class NewsUser implements Serializable {
    private Integer uid;
    private String username;
    private String userPwd;
    private String nickName;
}

3.2 vo类

HeadlineDetailVo
@AllArgsConstructor
@NoArgsConstructor
@Data
public class HeadlineDetailVo implements Serializable {
    private Integer hid;
    private String title;
    private String article;
    private Integer type;
    private String typeName;
    private Integer pageViews;
    private Long pastHours;
    private Integer publisher;
    private String author;
}
HeadlinePageVo
@AllArgsConstructor
@NoArgsConstructor
@Data
public class HeadlinePageVo implements Serializable {
    private Integer hid;
    private String title;
    private Integer type;
    private Integer pageViews;
    private Long pastHours;
    private Integer publisher;
}
HeadlineQueryVo
@AllArgsConstructor
@NoArgsConstructor
@Data
public class HeadlineQueryVo implements Serializable {
    private String keyWords;
    private Integer type ;
    private Integer pageNum;
    private Integer pageSize;
}

4.登入过滤器

@WebFilter("/headline/*")

public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request =(HttpServletRequest) servletRequest;
        HttpServletResponse response =(HttpServletResponse) servletResponse;
        String token = request.getHeader("token");

        boolean flag = null != token && (!JwtHelper.isExpiration(token));

        if(flag){
            filterChain.doFilter(servletRequest,servletResponse);
        }else{
            WebUtil.writeJson(response, Result.build(null, ResultCodeEnum.NOTLOGIN));
        }
    }
}

5.三层架构

dao层

NewsHeadlineDao接口
public interface NewsHeadlineDao {
    /**
     *
     * @param headlineQueryVo
     * @return
     */
    List<HeadlinePageVo> findPageList(HeadlineQueryVo headlineQueryVo);

    /**
     *
     * @param headlineQueryVo
     * @return
     */
    int findPageCount(HeadlineQueryVo headlineQueryVo);

    /**
     *
     * @param hid
     * @return
     */
    int incrPageViews(int hid);

    /**
     *
     * @param hid
     * @return
     */
    HeadlineDetailVo findHealineDetail(int hid);

    int addNewsHeadline(NewsHeadline newsHeadline);

    /**
     *
     * @param hid
     * @return
     */
    NewsHeadline findByHid(Integer hid);

    int update(NewsHeadline newsHeadline);

    int removeByHid(int hid);
}
NewsTypeDao接口
public interface NewsTypeDao {
    /**
     *
     * @return
     */
    List<NewsType> findAll();
}
NewsUserDao接口
public interface NewsUserDao {
    /**
     *
     * @param username
     * @return
     */
    NewsUser findByUsername(String username);

    /**
     *
     * @param userId
     * @return
     */
    NewsUser findByUid(Integer userId);

    /**
     *
     * @param registUser
     * @return
     */
    Integer insertUser(NewsUser registUser);
}
NewsHeadlineDaoImpl实现类
public class NewsHeadlineDaoImpl extends BaseDao implements NewsHeadlineDao {

    /*
    *
    *       private Integer hid;
            private String title;
            private Integer type;
            private Integer pageViews;
            private Long pastHours;
            private Integer publisher;
            *
            *
            *
            *       private String keyWords;
                    private Integer type ;
                    private Integer pageNum;
                    private Integer pageSize;
            *
            * */
    @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) {
        List params = new ArrayList();

        String sql  = """
                select 
                    count(1)
                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()+"%");
        }

        Long count = baseQueryObject(Long.class, sql, params.toArray());
        return count.intValue();
    }

    @Override
    public int incrPageViews(int hid) {
        String sql ="update  news_headline set page_views = page_views + 1 where hid = ?";

        return baseUpdate(sql,hid);
    }



    @Override
    public HeadlineDetailVo findHealineDetail(int hid) {
        String sql = """
                select
                  h.hid hid ,
                  h.title title ,
                  h.article article ,
                  h.type type ,
                  t.tname typeName ,
                  h.page_views pageViews ,
                  TIMESTAMPDIFF(HOUR,h.create_time,now() )pastHours ,
                  h.publisher publisher ,
                  u.nick_name 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> list = baseQuery(HeadlineDetailVo.class, sql, hid);

        return null != list && list.size()>0 ?  list.get(0):null;
    }

    @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()
                );
    }

    @Override
    public NewsHeadline findByHid(Integer hid) {
        String sql = """
                select
                    hid,
                    title,
                    article,
                    type,
                    publisher,
                    page_views pageViews,
                    create_time createTime,
                    update_time updateTime,
                    is_deleted isDeleted
                from 
                    news_headline
                where 
                    hid = ?
                """;
        List<NewsHeadline> list = baseQuery(NewsHeadline.class, sql, hid);
        return null != list && list.size()>0?list.get(0):null;
    }


    @Override
    public int update(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()
                );
    }


    @Override
    public int removeByHid(int hid) {
        String sql = "update news_headline set is_deleted = 1 where hid = ?";
        return baseUpdate(sql,hid);
    }
}
NewsTypeDaoImpl实现类
public class NewsTypeDaoImpl extends BaseDao implements NewsTypeDao {
    @Override
    public List<NewsType> findAll() {
        String sql = "select tid,tname from news_type";
        return baseQuery(NewsType.class,sql);
    }
}
NewsUserDaoImpl实现类
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);
        return newsUserList != null  && newsUserList.size()>0 ? newsUserList.get(0):null ;
    }

    @Override
    public NewsUser findByUid(Integer userId) {
        String sql = """
                select
                    uid,
                    username,
                    user_pwd userPwd,
                    nick_name nickName 
                from 
                    news_user
                where
                    uid = ?
                """;
        List<NewsUser> newsUserList = baseQuery(NewsUser.class, sql, userId);
        return newsUserList != null  && newsUserList.size()>0 ? newsUserList.get(0):null ;

    }

    @Override
    public Integer insertUser(NewsUser registUser) {
        String sql = """
                insert into news_user values (DEFAULT,?,?,?)
                """;
        return baseUpdate(sql,
                registUser.getUsername(),
                registUser.getUserPwd(),
                registUser.getNickName()
                );
    }
}

service层

NewsHeadlineService接口

public interface NewsHeadlineService {
    /**
     *
     * @param headlineQueryVo
     * @return
     */
    Map findPage(HeadlineQueryVo headlineQueryVo);

    /**
     *
     * @param hid
     * @return
     */
    HeadlineDetailVo findHeadlineDetail(int hid);

    /**
     *
     * @param newsHeadline
     */
    int addNewsHeadline(NewsHeadline newsHeadline);

    /**
     *
     * @param hid
     * @return
     */
    NewsHeadline findByHid(Integer hid);

    int update(NewsHeadline newsHeadline);


    /**
     *
     * @param hid
     * @return
     */
    int removeByHid(int hid);
}
NewsTypeService接口
public interface NewsTypeService {
    /**
     * 查询所有头条类型的方法
     * @return 多个头条类型以List<NewsType>集合形式返回
     */
    List<NewsType> findAll();
}
NewsUserService接口
public interface NewsUserService {
    /**
     * 根据用户登录的账号找用户新的方法
     * @param username 用户输入的账户
     * @return 找到返回NewsUser对象,找不到返回null
     */
    NewsUser findByUsername(String username);

    /**
     *
     * @param userId
     * @return
     */
    NewsUser findByUid(Integer userId);

    /**
     *
     * @param registUser
     * @return
     */
    Integer registUser(NewsUser registUser);
}
NewsHeadlineServiceImpl实现类
public class NewsHeadlineServiceImpl implements NewsHeadlineService {
    private NewsHeadlineDao headlineDao =new NewsHeadlineDaoImpl();
    /*
        totalPage:1,
        totalSize:1
        pageData:[
                    {
                       "hid":"1",                     // 新闻id
                        "title":"尚硅谷宣布 ... ...",   // 新闻标题
                        "type":"1",                    // 新闻所属类别编号
                        "pageViews":"40",              // 新闻浏览量
                        "pastHours":"3",              // 发布时间已过小时数
                        "publisher":"1"
                   }
                 ],
        pageNum:1,
        pageSize:1,


     */
    @Override

    public Map findPage(HeadlineQueryVo headlineQueryVo) {
        int pageNum = headlineQueryVo.getPageNum();
        int pageSize = headlineQueryVo.getPageSize();
        List<HeadlinePageVo> pageData = headlineDao.findPageList(headlineQueryVo);
        int totalSize = headlineDao.findPageCount(headlineQueryVo);

        int totalPage =totalSize % pageSize ==0 ? totalSize/pageSize: totalSize/pageSize+1;
        Map pageInfo= new HashMap();
        pageInfo.put("pageNum",pageNum);
        pageInfo.put("pageSize",pageSize);
        pageInfo.put("totalSize",totalSize);
        pageInfo.put("totalPage",totalPage);
        pageInfo.put("pageData",pageData);
        return pageInfo;
    }

    @Override
    public HeadlineDetailVo findHeadlineDetail(int hid) {
        // 修改该头条的浏览量  +1
        headlineDao.incrPageViews(hid);
        // 查询头条的详情
        return headlineDao.findHealineDetail(hid);
    }

    @Override
    public int addNewsHeadline(NewsHeadline newsHeadline) {
        return headlineDao.addNewsHeadline(newsHeadline);
    }

    @Override
    public NewsHeadline findByHid(Integer hid) {
        return headlineDao.findByHid(hid);
    }

    @Override
    public int update(NewsHeadline newsHeadline) {
        return headlineDao.update(newsHeadline);
    }

    @Override
    public int removeByHid(int hid) {
        return headlineDao.removeByHid(hid);
    }
}
NewsTypeServiceImpl实现类
public class NewsTypeServiceImpl implements NewsTypeService {
    private NewsTypeDao typeDao =new NewsTypeDaoImpl();
    @Override
    public List<NewsType> findAll() {
        return typeDao.findAll();
    }
}
NewsUserServiceImpl实现类
public class NewsUserServiceImpl implements NewsUserService {

    private NewsUserDao userDao =new NewsUserDaoImpl();
    @Override
    public NewsUser findByUsername(String username) {
        return userDao.findByUsername(username);
    }

    @Override
    public NewsUser findByUid(Integer userId) {
        return userDao.findByUid(userId);
    }

    @Override
    public Integer registUser(NewsUser registUser) {
        // 处理增加数据的业务
        // 将明文密码转换成密文密码
        registUser.setUserPwd(MD5Util.encrypt(registUser.getUserPwd()));

        return userDao.insertUser(registUser);
    }
}

servlet层

NewsHeadlineController
@WebServlet("/headline/*")
public class NewsHeadlineController extends BaseController{
    private NewsHeadlineService headlineService =new NewsHeadlineServiceImpl();


    /**
     * 删除头条业务接口 实现
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void removeByHid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int hid = Integer.parseInt(req.getParameter("hid"));

        headlineService.removeByHid(hid);


        WebUtil.writeJson(resp, Result.ok(null));
    }

    /**
     * 更新头条的业务接口实现
     * @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.update(newsHeadline);

        WebUtil.writeJson(resp,Result.ok(null));

    }

    /**
     * 修改头条回显业务接口
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void findHeadlineByHid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer hid = Integer.parseInt(req.getParameter("hid"));
        NewsHeadline headline =headlineService.findByHid(hid);

        Map data =new HashMap();
        data.put("headline",headline);
        WebUtil.writeJson(resp,Result.ok(data));

    }

    /**
     * 发布头条的接口实现
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void publish(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收参数
        String token = req.getHeader("token");
        Long userId = JwtHelper.getUserId(token);


        NewsHeadline newsHeadline = WebUtil.readJson(req, NewsHeadline.class);
        newsHeadline.setPublisher(userId.intValue());


        // 将信息存入数据库
        headlineService.addNewsHeadline(newsHeadline);

        WebUtil.writeJson(resp, Result.ok(null));

    }
}
NewsTypeController
@WebServlet("/type/*")
public class NewsTypeController extends BaseController{
}
NewsUserController
@WebServlet("/user/*")
public class NewsUserController extends BaseController{


    private NewsUserService userService =new NewsUserServiceImpl();


    /**
     * 前端自己校验是否失去登录状态的接口
     * @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);
        if(null != token){
            if (!JwtHelper.isExpiration(token)) {
                result= Result.ok(null);
            }
        }
        WebUtil.writeJson(resp,result);
    }

    /**
     * 完成注册的业务接口
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收JSON信息
        NewsUser registUser = WebUtil.readJson(req, NewsUser.class);

        // 调用服务层将用户信息存入数据
        Integer rows =userService.registUser(registUser);

        // 根据存入是否成功处理响应值
        Result result =Result.ok(null);
        if(rows == 0){
            result=Result.build(null,ResultCodeEnum.USERNAME_USED);
        }

        WebUtil.writeJson(resp,result);

    }

    /**
     * 校验用户名是否被占用的业务接口实现
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void checkUserName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取账号
        String username = req.getParameter("username");

        // 根据用户名查询用户信息  找到了 返回505  找不到 200
        NewsUser newsUser = userService.findByUsername(username);
        Result result =Result.ok(null);
        if(null != newsUser){
            result=Result.build(null,ResultCodeEnum.USERNAME_USED);
        }

        WebUtil.writeJson(resp,result);
    }

    /**
     * 根据token口令获得用户信息的接口实现
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getUserInfo(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求中的token
        String token = req.getHeader("token");


        Result result = Result.build(null,ResultCodeEnum.NOTLOGIN);
        if(null != token && (!"".equals(token))){
            if (!JwtHelper.isExpiration(token)) {
                Integer userId = JwtHelper.getUserId(token).intValue();
                NewsUser newsUser =userService.findByUid(userId);
                if(null != newsUser){
                    //通过校验 查询用户信息放入Result
                    Map data =new HashMap();
                    newsUser.setUserPwd("");
                    data.put("loginUser",newsUser);

                    result = Result.ok(data);
                }
            }
        }

        WebUtil.writeJson(resp,result);

    }

    /**
     * 处理登录表单提交的业务接口的实现
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收用户名和密码
        /*{
            "username":"zhangsan", //用户名
            "userPwd":"123456"     //明文密码
        }*/
        NewsUser paramUser = WebUtil.readJson(req, NewsUser.class);

        // 调用服务层方法 实现登录
        NewsUser loginUser = userService.findByUsername(paramUser.getUsername());
        Result result = null;
        if(null != loginUser){
            if (MD5Util.encrypt(paramUser.getUserPwd()).equalsIgnoreCase(loginUser.getUserPwd())) {
                Map data =new HashMap();
                data.put("token",JwtHelper.createToken(loginUser.getUid().longValue()));
                result=Result.ok(data);
            }else{
                result=Result.build(null,ResultCodeEnum.PASSWORD_ERROR);
            }
        }else {
            result=Result.build(null, ResultCodeEnum.USERNAME_ERROR);

        }

        // 向客户端响应登录验证信息
        WebUtil.writeJson(resp,result);
    }
}
PortalController(分页)
@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 showHeadlineDetail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 接收要查询头条的hid
        int hid = Integer.parseInt(req.getParameter("hid"));
        // 调用服务层完成查询处理
        HeadlineDetailVo headlineDetailVo =headlineService.findHeadlineDetail(hid);
        // 将查到的信息响应给客户端
        Map data =new HashMap();
        data.put("headline",headlineDetailVo);
        WebUtil.writeJson(resp, Result.ok(data));
    }

    /**
     * 分页查询头条信息的接口实现
     * @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);


        // 将参数传递给服务层 进行分页查询
        /*
        * pageData:[
        *   {
        *           "hid":"1",                     // 新闻id
    				"title":"尚硅谷宣布 ... ...",   // 新闻标题
    				"type":"1",                    // 新闻所属类别编号
    				"pageViews":"40",              // 新闻浏览量
    				"pastHours":"3",              // 发布时间已过小时数
    				"publisher":"1"
        *   }
        *
        * ],
        * pageNum:1,
        * pageSize:1,
        * totalPage:1,
        * totalSize:1
        *
        *
        * */
       Map pageInfo =headlineService.findPage(headlineQueryVo);
       Map data =new HashMap();
       data.put("pageInfo",pageInfo);

        // 将分页查询的结果转换成json响应给客户端
        WebUtil.writeJson(resp,Result.ok(data));
    }

    /**
     * 查询所有头条类型的业务接口实现
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */

    protected void findAllTypes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 查询所有的新闻类型,装入Result响应给客户端
        List<NewsType> newsTypeList= typeService.findAll();


        WebUtil.writeJson(resp,Result.ok(newsTypeList));
    }
}

项目实战二结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1954782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十一、Dockerfile解析

目录 一、Dockerfile简介 二、dockerfile的构建的三个步骤 三、Dockerfile的构建过程 1、DockerFile内容的基础知识 2、Docker执行Dockerfile的大致流程 四、dockerfile常用的保留字 1、FROM 2、MAINTAINER 3、RUN 4、EXPOSE 5、WORKDIR 6、USER 7、ENV 8、VOLUME …

VScode使用Github Copilot插件时出现read ECONNREST问题的解决方法

文章目录 read ECONNREST查看是否仍是 Copilot 会员查看控制台输出网络连接问题浏览器设置问题笔者的话 read ECONNREST 最近使用 Copilot 时一直出现 read ECONNREST 问题&#xff0c;这个表示连接被对方重置了&#xff0c;就是说在读取数据时连接被关闭。 我首先怀疑是不是…

QT常用的控件

QT常用控件 一.控件概述二.QWidget 核心属性2.1 核心属性概览2.2 enabled代码示例&#xff1a;使用代码创建一个禁用状态的按钮代码示例: 通过按钮2 切换按钮1 的禁用状态. 2.3 geometry代码示例: 控制按钮的位置代码示例: ⼀个随机按钮程序代码示例: 感受 geometry 和frameGeo…

Python | TypeError: ‘NoneType’ object is not iterable

Python | TypeError: ‘NoneType’ object is not iterable 在Python编程中&#xff0c;TypeError: NoneType object is not iterable 是一个常见的错误&#xff0c;通常表明你尝试对一个值为 None 的对象进行迭代操作&#xff0c;而 None 类型的对象是不可迭代的。本文将深入…

python count返回什么

描述 count() 方法用于统计字符串中某个子字符串出现的次数&#xff0c;可选参数为开始搜索与结束搜索的位置索引。 语法 count() 方法语法&#xff1a; S.count(sub[,start0[,endlen(S)]]) 参数 sub -- 搜索的子字符串。 S -- 父字符串。 start -- 可选参数&#xff0c;…

Windows11和Win10如何彻底永久关闭Windows defender

Windows11和Win10如何彻底永久关闭Windows defender 亲测简单快捷有效关闭病毒和威胁防护。 使用关闭windows defender工具。 随时可以重新开启病毒和威胁防护。

【Spring Boot】Spring 的安全框架:Spring Security

Spring 的安全框架&#xff1a;Spring Security 1.Spring Security 初识1.1 核心概念1.2 认证和授权1.2.1 验证&#xff08;authentication&#xff09;1.2.2 授权&#xff08;authorization&#xff09; 1.3 模块 2.核心类2.1 Securitycontext2.2 SecurityContextHolder2.2.1 …

刷题心得之位运算技巧 gcd 和 lcm

位运算 gcd 和 lcm 位运算技巧遍历 n 的所有子集, 不包括空集遍历 n 的所有子集, 包括空集提取出 n 二进制中第一次出现的1消除 n 二进制中第一次出现的1判断 n 是否是 2 的幂次方 gcd [最大公约数]lcm [最小公倍数] 位运算技巧 遍历 n 的所有子集, 不包括空集 #include <…

52.TFT_LCD液晶屏字符显示

&#xff08;1&#xff09;实验目标&#xff1a;在5寸显示屏&#xff08;800 * 480 60&#xff09;中央显示汉字&#xff08;黄色&#xff09;&#xff0c;且背景颜色为青色。 &#xff08;2&#xff09;代码编写&#xff1a; tft_ctrl模块&#xff1a; module tft_ctrl(inp…

电子电气架构---域控制器的软硬件趋势

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

TiDB-从0到1-sync-diff-inspector数据校验工具

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容TiDB-从0到1-数据导出导入TiDB-从0到1-BR工具 一、sync-diff-inspector工具 sync-diff-inspector是TiDB原生…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第六十二章 定时器按键消抖实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

详解Mysql InnoDB引擎 04

文章目录 1. InnoDB 简介2. 逻辑存储结构2.1 表空间 idb文件2.2 段2.3 区 1M2.4 页 16KB2.5 行 3. 架构3.1 内存结构3.1.1 Buffer Pool 缓冲池3.1.2 Change Buffer 更改缓冲区3.1.3 Adaptive Hash Index3.1.4 Log Buffer 3.2 磁盘结构 4. 后台线程5. 事务原理5.1 redo log 重做…

Pytorch深度学习实践(9)卷积神经网络

卷积神经网络 全连接神经网络 神经网络中全部是线性模型&#xff0c;是由线性模型串联起来的 全连接网络又叫全连接层 卷积神经网络 在全连接神经网络中&#xff0c;由于输入必须是一维向量&#xff0c;因此在处理图像时必须要对图像矩阵进行拉伸成一维的形式&#xff0c;…

视觉巡线小车(STM32+OpenMV)——总结

文章目录 目录 文章目录 前言 一、效果展示 二、完整流程 1、STM32CubeMX配置 2、Keil编辑 3、硬件接线 4、参数调试 5、图像处理调试 三、总结 前言 基于前面的系列文章&#xff0c;已基本介绍完了基于STM32OpenMV的视觉巡线小车&#xff0c;本文将以小编自己的小车…

BACnet物联网关BL103:Modbus协议转BACnet/MSTP

随着物联网技术在楼宇自动化与暖通控制系统中的迅猛发展&#xff0c;构建一种既经济高效又高度可靠的协议转换物联网关成为了不可或缺的核心硬件组件。在此背景下&#xff0c;我们钡铼特别推荐一款主流的BAS&#xff08;楼宇自动化系统&#xff09;与BACnet物联网关——BL103&a…

小世界特性解析——聚类系数与平均路径长度的奥秘

小世界特性解析——聚类系数与平均路径长度的奥秘 小世界特性的核心衡量指标 小世界特性&#xff0c;这一复杂网络中的重要概念&#xff0c;主要通过两个关键指标来衡量&#xff1a;聚类系数和平均路径长度。这两个指标共同揭示了网络结构的紧密程度和信息传播的效率。 聚类…

echarts没数据的时候,页面显示暂无数据

echarts没数据的时候&#xff0c;页面显示暂无数据 给个if判断 let option{} if(data.length0){ //没有数据或者数据不合法,显示暂无数据option {title: {text: 暂无数据,x: center,y: center,textStyle: {fontFamily: Manteka,fontSize: 12,fontWeight: normal,color: #333…

使用 Copilot 对 OneDrive 文档分享进行摘要

对于大量使用onedrive进行资料分享的用户而言&#xff0c;对分享的文件进行简要说明并提供给对方&#xff0c;是一个基本素养。 在以往&#xff0c;他们只能阅读文件名然后靠回忆进行撰写&#xff0c;或者打开每一个文档通读全文然后再关闭返回并撰写摘要。 当用户在 SharePo…

Java聚合快递小程序对接云洋系统程序app源码

​一场物流效率的革命 引言&#xff1a;物流新时代的序章 在数字化浪潮席卷各行各业的今天&#xff0c;物流行业也迎来了前所未有的变革。为了进一步提升物流效率&#xff0c;优化用户体验&#xff0c;聚合快递系统与云洋系统小程序的对接成为了行业内外关注的焦点。这一创新…