Servlet项目教学(附实例代码)

【员工信息管理】

1.员工信息管理

在这里插入图片描述

1.1 介绍
用户进行登录后,可以对员工信息进行管理(增删查改),等操作.如果用户没有登录,不能访问员工操作页面.并且员工操作页面显示当前登录用户信息.

1.2 技术点
使用Vue+ElementUI充当前端界面,使用Servlet+JDBC+Mysql提供数据管理控制.后端统一向前端返回JSON格式的数据.

2. 项目搭建

在这里插入图片描述

2.1 统一前置处理
2.1.1 过滤器
由于所有的请求都是servlet进行处理,但是存在一些共性问题,例如:编码格式,跨域响应头.基于这样的情况,早期web设计者,定义一个对所有请求进行过滤的组件,这个组件叫过滤器.通过实现过滤器的规范,将过滤器注册到服务器,过滤器就会对相应的项目中所有的请求进行干预处理.
在这里插入图片描述

基于过滤器机制,可以将一些共性问题由过滤器处理.JavaWeb中提供接口:Filter,通过实现Filter接口,重写相关方法,再进行注册,就可以使用.

2.1.2 过滤器的实现

  1. 实现Filter接口

  2. 重写相关方法:doFilter方法

  3. 注册过滤器

(1) xml注册

<!-- 声明过滤器 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.powernode.filter.EncodingFilter</filter-class>
</filter>
<!-- 配置过滤器的规则 -->
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <!-- 所有 .do 后缀结尾的请求 进行编码处理 -->
    <url-pattern>*.do</url-pattern>
</filter-mapping>

(2) 注解注册

@WebFilter("*.do")
//@WebFilter(value="*.do")
//@WebFilter(urlPatterns="*.do")
public class EncodingFilter implements Filter {
   }

2.1.3 编码字符集处理

package com.powernode.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 *  编码过滤
 *  在进入servlet之前就进行编码设置
 */
@WebFilter(urlPatterns = "*.do")
public class EncodingFilter implements Filter {
   

    /**
     *  Filter 初始化方法  只会执行一次  项目启动就执行
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
   
        System.out.println("filter 中 init 方法");
    }

    /**
     *  进行具体的过滤方法
     * @param servletRequest  当前请求对象
     * @param servletResponse  当前响应对象
     * @param filterChain  过滤器链 项目中可以存在多个过滤器
     *                     过滤器的注册方式有2种 :
     *                      xml配置
     *                      注解
     *                    过滤存在先后执行问题: 过滤使用责任链模式
     *                    最先执行的最后执行完.如果XML配置方式,配置在最上方的最先执行
     *                    如果是注解的方式,按照文件名顺序(类加载器是按照文件名称顺序加载的)
     *                   filterChain.doFilter(servletRequest,servletResponse); // 将请求对象和响应对象向下传递  调用下一个方法
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   
        System.out.println(" 进行具体的过滤操作 doFilter..... ");
        // xxxxx
        System.out.println("在调用下一个方法之前干点啥......");
        // 调用下一个方法
        // 在进入servlet 之前 就已经设置好了编码格式
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        filterChain.doFilter(servletRequest,servletResponse);
        // xxxxx
        System.out.println("在调用完成也干点啥......");
    }

    @Override
    public void destroy() {
   
        System.out.println("过滤器 销毁前调用的方法");
    }
}

2.1.4 跨域处理

package com.powernode.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 跨域过滤器
 */
@WebFilter("*.do")
public class CrossFilter implements Filter {
   
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        // 所有的请求源 允许跨域
        resp.addHeader("Access-Control-Allow-Origin","*");
        // 放行
        chain.doFilter(req,response);
    }
}

2.2 数据库脚本

DROP TABLE IF EXISTS `dept`;

CREATE TABLE `dept`  (

  `dept_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门编号',

  `dept_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门名称',

  `dept_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门备注',

  PRIMARY KEY (`dept_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;



-- ----------------------------

-- Records of dept

-- ----------------------------

INSERT INTO `dept` VALUES (1, '开发一部', '开发一部');

INSERT INTO `dept` VALUES (2, '开发二部', '开发二部');

INSERT INTO `dept` VALUES (3, '开发三部', '开发三部');



-- ----------------------------

-- Table structure for emp

-- ----------------------------

DROP TABLE IF EXISTS `emp`;

CREATE TABLE `emp`  (

  `emp_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工编号',

  `emp_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '员工姓名',

  `emp_sex` int(11) NULL DEFAULT NULL COMMENT '员工性别',

  `emp_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '员工地址',

  `emp_age` int(11) NULL DEFAULT NULL COMMENT '员工年龄',

  `emp_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '员工工资',

  `emp_birth` datetime(0) NULL DEFAULT NULL COMMENT '员工生日',

  `dept_id` int(11) NULL DEFAULT NULL COMMENT '所属部门ID',

  PRIMARY KEY (`emp_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;



-- ----------------------------

-- Table structure for user

-- ----------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user`  (

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',

  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',

  `password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',

  `realname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',

  `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像',

  PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

2.3 postman安装

接口测试工具,模拟HTTP请求.使用postman模拟常规用户请求操作,可以看到服务器返回的数据,进行接口测试.
在这里插入图片描述

2.4 核心代码
2.4.1 统一业务结果包装类-Result

package com.powernode.common;

/**
 *  统一业务结果 包装类
 */
public class Result {
   
    /**
     *  统一的业务码  0 标识正常
     */
    private Integer code = 0;
    /**
     *  统一业务消息 默认是 操作成功
     */
    private String msg = "操作成功!";
    /**
     *  业务结果数据 所有操作的数据 放入data 属性中
     */
    private Object data;

    /**
     *  成功 但是没有返回业务数据
     */
    public Result(){
   }

    /**
     *  成功 但是 存在 返回业务数据
     * @param data
     */
    public Result(Object data){
   
        this();
        this.data = data;
    }

    /**
     *  异常结果
     * @param code  异常码
     * @param msg 异常消息
     */
    public Result(int code,String msg){
   
        this.code = code;
        this.msg = msg;
    }


    public Integer getCode() {
   
        return code;
    }

    public void setCode(Integer code) {
   
        this.code = code;
    }

    public String getMsg() {
   
        return msg;
    }

    public void setMsg(String msg) {
   
        this.msg = msg;
    }

    public Object getData() {
   
        return data;
    }

    public void setData(Object data) {
   
        this.data = data;
    }
}

2.4.2 数据库连接配置文件

# 数据库连接配置文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/emp?useUnicode=true&useSSL=false&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

2.4.3 数据库连接工具类

package com.powernode.util;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * 自定义JDBC工具类:1)提供获取链接Connection的方法   2)关闭资源的方法  3)实现jdbc配置软编码
 */
public final class DBUtils {
   
    /**
     * 驱动名称
     */
    private static String driverClassName;
    /**
     * 链接信息
     */
    private static String url;
    /**
     * 用户名
     */
    private static String username;
    /**
     * 用户密码
     */
    private static String password;

    static {
   
        try {
   
            //关联.properties配置文件
            Properties prop = new Properties();
            InputStream ins = DBUtils.class.getClassLoader().getResourceAsStream("db.properties");
            prop.load(ins);
            //读取.properties配置文件的属性值
            driverClassName = prop.getProperty("jdbc.driverClassName");
            url = prop.getProperty("jdbc.url");
            username = prop.getProperty("jdbc.username");
            password = prop.getProperty("jdbc.password");
            Class.forName(driverClassName);
        } catch (Exception e) {
   
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     *
     * @return
     */
    public static Connection getConn() {
   
        Connection conn = null;
        try {
   
            conn = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
   
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭资源
     *
     * @param acs
     */
    public static void close(AutoCloseable acs) {
   
        try {
   
            if (acs != null) {
   
                acs.close();
            }
        } catch (Exception e) {
   
            e.printStackTrace();
        }
    }

    /**
     * 关闭资源
     *
     * @param rs
     * @param st
     * @param conn
     */
    public static void close(ResultSet rs, Statement st, Connection conn) {
   
        try {
   
            if (rs != null)
                rs.close();
            if (st != null)
                st.close();
            if (conn != null)
                conn.close();
        } catch (SQLException throwables) {
   
            throwables.printStackTrace();
        }
    }
}
 

2.4.4 通用数据库操作类

package com.powernode.dao;

import com.powernode.util.DBUtils;
import com.powernode.util.PageInfo;

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

/**
 * JDBC工具类:旨在为客户提供更加便捷的操作数据库的方式
 */
public class BaseDao {
   
    /**
     * 修改:可以执行添加、删除、修改单条操作
     * @param sql
     * @param params
     * @return
     */
    public int executeUpdate(String sql,Object...params){
   
        Connection conn = null;
        PreparedStatement st = null;
        int i=0;
        try {
   
            //参数校验
            if(sql==null || "".equals(sql.trim())){
   
                return 0;
            }
            //获取连接
            conn = DBUtils.getConn();
            //创建Statement对象
            st = conn.prepareStatement(sql);
            //给sql赋值参数
            for (int n=0;params!=null && params.length>=1 &&n<params.length;n++){
   
                st.setObject(n+1,params[n]);
            }
            //向mysql发送sql语句,接受结果
            i = st.executeUpdate();
        } catch (Exception throwables) {
   
            throwables.printStackTrace();
        }finally {
   
            //释放资源
            DBUtils.close(null,st,conn);
        }
        return i;
    }

    /**
     * 批量删除
     * @param sql
     * @param params
     * @return
     */
    public int executeBatchDel(String sql,Object...params){
   
        Connection conn = null;
        PreparedStatement st = null;
        int[] arr = null;
        try {
   
            //基本参数校验
            if(sql==null || "".equals(sql.trim())){
   
                return 0;
            }
            //获取连接
            conn = DBUtils.getConn();
            //在同一个事务中执行
            conn.setAutoCommit(false);
            st = conn.prepareStatement(sql);
            //给参数赋值
            for (int i = 0;params!=null && params.length>=1 && i < params.length; i++) {
   
                st.setObject(1,params[i]);
                st.addBatch();
            }
            //执行sql
            arr = st.executeBatch();//[0,0,0,0]
        } catch (Exception throwables) {
   
            throwables.printStackTrace();
        } finally {
   
            try {
   
                conn.setAutoCommit(true);
            } catch (SQLException throwables) {
   
                throwables.printStackTrace();
            }
            //释放资源
            DBUtils.close(null,st,conn);
        }
        return arr.length;
    }

    /**
     * 查询多条记录
     * @param sql
     * @param c
     * @param params
     * @param <T>
     * @return
     */
    public <T> List<T> executeQueryList(String sql, Class<T> c ,Object...params){
   
        Connection conn= null;
        PreparedStatement st = null;
        ResultSet rs = null;
        List<T> dataList = new ArrayList<>();//{}
        try {
   
            //参数校验
            if(sql==null || "".equals(sql.trim())){
   
                return dataList;
            }
            //获取Connection连接
            conn = DBUtils.getConn();
            //创建PrepareStatement对象
            st = conn.prepareStatement(sql);
            for (int i = 0;params!=null && params.length>=1 && i < params.length; i++) {
   
                st.setObject(i+1,params[i]);
            }
            //发送sql,接受结果
            rs = st.executeQuery();
            //获取查询数据的字段个数
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            for(;rs.next();){
   //取记录的次数
                //创建一个c字节码的对象,用来装一条记录
                T t = c.newInstance();
                for (int i = 1; i <=columnCount ; i++) {
   
                    //获取某个字段别名  字段别名默认是和字段名一致
                    String columnName = metaData.getColumnLabel(i);
                    //获取字段对应的值
                    Object value = rs.getObject(columnName);
                    //内部for全部执行完了,则代表一条记录取出来了
                    Field field = c.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t,value);
                    field.setAccessible(false);
                }
                //将对象装入到List中
                dataList.add(t);
            }
        } catch (Exception throwables) {
   
            throwables.printStackTrace();
        }finally {
   
            DBUtils.close(rs,st,conn);
        }
        return dataList;
    }

    /**
     * 查询单条记录
     * @param sql
     * @param c
     * @param param
     * @param <T>
     * @return
     */
    public <T> T executeQueryOne(String sql,Class<T> c,Object...param){
   
        return executeQueryList(sql,c,param).size()==0?null:executeQueryList(sql,c,param).get(0);
    }

    /**
     * 分页查询
     * @param sql 基本分页sql,不用写limit
     * @param pageNum 页码
     * @param pageSize 每页显示的数据条数
     * @param c   某一条数据的类型
     * @param params  分页太哦建
     * @param <T>
     * @return
     */
    public <T> PageInfo<T> executeQueryPage(String sql,int pageNum,int pageSize,Class<T> c,Object...params){
   
        Connection conn=null;
        PreparedStatement st = null;
        ResultSet rs = null;
        PageInfo<T> pageInfo = new PageInfo<>();
        try {
   
            //校验参数
            if(sql==null || "".equals(sql.trim())){
   
                return pageInfo;
            }
            if(pageNum<=0 || pageSize<=0){
   
                return pageInfo;
            }
            if(c==null){
   
                return pageInfo;
            }
            //去除;
            sql = sql.replaceAll(";","");
            //获取数据库连接:Connection对象
            conn = DBUtils.getConn();
            //准备sql语句
            //创建PrepareStatement对象  (此处有个;的小bug)
            String newSql = sql + " limit "+(pageNum-1)*pageSize+","+pageSize+"";
            st = conn.prepareStatement(newSql);
            //给sql占位符?赋值
            for (int i = 0;params!=null && params.length>=1 && i < params.length; i++) {
   
                st.setObject(i+1,params[i]);
            }
            //执行sql,处理结果
            rs = st.executeQuery();
            //数据表头信息
            ResultSetMetaData metaData = rs.getMetaData();
            //获取查询sql语句中字段的个数
            int columnCount = metaData.getColumnCount();
            for (;rs.next();){
   
                //创建一个对象,用于接收一条记录
                T t = c.newInstance();
                for (int i = 1; i <=columnCount ; i++) {
   
                    //获取字段名
                    String columnName = metaData.getColumnLabel(i);
                    //获取字段值
                    Object columnValue = rs.getObject(columnName);
                    //将对应字段的值装入到实体类对象中去
                    Field field = c.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t,columnValue);
                    field.setAccessible(false);
                }
                //将某一条记录放入到List集合中去
                //往pageInfo对象中添加分页数据
                pageInfo.getData().add(t);
            }
            //往pageInfo对象中添加总记录数
            long total = executeQueryCount(sql);
            pageInfo.setTotal(total);
            //往pageInfo对象中添加总页数
            long temp = total % pageSize;//3%2=1
            int pages = temp==0? (int)(total/pageSize): (int)Math.ceil((double)total/(double)pageSize);
            pageInfo.setPages(pages
  • 33
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的Servlet实例代码,它实现了用户登录功能: ```java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String username = request.getParameter("username"); String password = request.getParameter("password"); if (username.equals("admin") && password.equals("admin123")) { out.println("<h1>Login Success!</h1>"); } else { out.println("<h1>Login Failed!</h1>"); } out.close(); } } ``` 在上面的代码中,LoginServlet是一个继承自HttpServlet的Java类,它覆盖了doGet和doPost方法。在doPost方法中,通过request.getParameter方法获取用户提交的登录信息,然后判断用户名和密码是否正确,并输出对应的信息到页面上。 在使用Servlet时,还需要在web.xml文件中进行配置,将Servlet映射到对应的URL上,如下所示: ```xml <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> ``` 以上代码将LoginServlet映射到/login URL上,当用户访问这个URL时,就会调用LoginServlet的doPost方法来处理请求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值