Servlet开发搭建

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 搭建一个基本的 Servlet 开发框架,便于后续地快速开发。只适用于 Servlet 阶段。特点: 自定义的 BaseDao,BaseDaoImpl,BaseServlet, 用 beanutils 来封装前台传入参数。

搭建一个基本的 Servlet 开发框架,便于后续地快速开发。只适用于 Servlet 阶段。


特点: 自定义的 BaseDao,BaseDaoImpl,BaseServlet, 用 beanutils 来封装前台传入参数。


一. 添加 jar包


Maven 依赖的形式,添加相应的依赖


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.yjl.project</groupId>
  <artifactId>Servlet_Dev</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
    <!-- 配置java的版本 -->
    <java.version>1.8</java.version>
    <!-- mysql的版本 -->
    <mysql.version>5.1.32</mysql.version>
    <!-- 配置junit的版本 -->
    <junit.version>4.12</junit.version>
    <!-- 配置servlet的版本 -->
    <servlet.version>3.1.0</servlet.version>
  </properties>
  <dependencies>
      <!-- junit 依赖 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <!--tomcat中 jsp与 servlet依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${servlet.version}</version>
      <scope>provided</scope>
    </dependency>
    <!-- jstl 与 standard 依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <!-- 文件上传 的依赖-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.2</version>
    </dependency>
    <!-- 日志依赖-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.22</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.25</version>
    </dependency>
    <!-- mysql依赖 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <!-- c3p0依赖 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>   
    <dependency>
      <groupId>net.sf.json-lib</groupId>
      <artifactId>json-lib</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.1</version>
    </dependency>
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2.2</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <!-- 编译的jdk版本 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>${java.version}</source>
          <target>${java.version}</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <!--tomcat的插件名, tomcat7-maven-plugin, 用的是tomcat7版本 -->
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>8080</port>  <!--tomcat的端口号 -->
          <path>/Servlet_Dev</path> <!--tomcat的项目名 -->
          <uriEncoding>UTF-8</uriEncoding> <!-- 防止get 提交时乱码 -->
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>


也可以 放置 jar包。 所用到的jar包有:


20200420102905389.png


二. 读取 jdbc.properties 数据库配置和 DBUtils 工具类


二.一 数据库配置文件


在 src 目录下,放置一个 jdbc.properties 数据库配置文件信息。


#数据库的配置
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/rbac?characterEncoding=UTF-8
username=root
password=abc123


当修改数据库的时候,只需要修改 jdbc.properties 的配置信息即可。


二.二 DBProperties 数据库属性



package com.yjl.utils;
import java.io.IOException;
import java.util.Properties;
/**
 * 
 * @author 两个蝴蝶飞
 *
 *用于读取数据库的配置信息
 */
public class DBProperties {
  private static String DRIVER_CLASS;
  private static String URL;
  private static String USERNAME;
  private static String PASSWORD;
    static{
     //创建Properties对象
    Properties pro = new Properties();
    try {
      pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties"));
    } catch (IOException e) {
      // TODO 自动生成的 catch 块
      e.printStackTrace();
    }
    DRIVER_CLASS = pro.getProperty("driverClass");
    URL = pro.getProperty("url");
    USERNAME = pro.getProperty("username");
    PASSWORD = pro.getProperty("password");
  }
  public static String getDRIVER_CLASS() {
    return DRIVER_CLASS;
  }
  public void setDRIVER_CLASS(String dRIVER_CLASS) {
    DRIVER_CLASS = dRIVER_CLASS;
  }
  public static String getURL() {
    return URL;
  }
  public void setURL(String uRL) {
    URL = uRL;
  }
  public static String getUSERNAME() {
    return USERNAME;
  }
  public void setUSERNAME(String uSERNAME) {
    USERNAME = uSERNAME;
  }
  public static String getPASSWORD() {
    return PASSWORD;
  }
  public void setPASSWORD(String pASSWORD) {
    PASSWORD = pASSWORD;
  }
  public static void main(String []args){
    System.out.println(DBProperties.getUSERNAME());
  }
}


二.三 DBUtils 工具类


用于开启和关闭数据库连接



package com.yjl.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * 
 * @author 两个蝴蝶飞
 * 
 * 数据库连接的工具
 *
 */
public class DBUtils {
  /**
   * 加载驱动 创建连接
   */
  public static Connection getConnection() {
    Connection conn=null;
    try {
      Class.forName(DBProperties.getDRIVER_CLASS());
      conn = DriverManager.getConnection(DBProperties.getURL(),
          DBProperties.getUSERNAME(), DBProperties.getPASSWORD());
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
    return conn;
  }
  /**
   * 关闭jdbc资源
   */
  public  static void closeAll(ResultSet rs, PreparedStatement ptmt, Connection conn) {
    try {
      if (rs != null) {
        rs.close();
      }
      if (ptmt != null) {
        ptmt.close();
      }
      if (conn != null) {
        conn.close();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
}


三. 数据库 BaseDao 和 BaseDaoImpl


采用泛型的形式,进行开发。


三.一 BaseDao



package com.yjl.utils;
import java.util.List;
/**
 * 
 @Description 基本的dao类型转换
*/
public interface BaseDao<T> {
  /**
   * 插入实体
   * @param sql  sql语句
   * @param params 插入参数,可变参数形式
   * @return 返回插入的条数
   */
  public int insertEntity(String sql,Object...params);
  /**
   * 插入实体
   * @param sql  sql语句
   * @param params 插入参数,集合形式
   * @return 返回插入的条数
   */
  public int insertEntity(String sql,List<Object> params);
  /**
   * 根据id删除实体
   * @param sql 删除语句
   * @param id 删除的编号id
   * @return 返回删除的条数
   */
  public int deleteById(String sql,int id);
  /**
   * 根据某一属性值进行删除
   * @param sql 删除的sql语句,不需要写where 语句。
   * @param name 依据删除的属性
   * @param params 参数
   * @return 返回删除的条数
   */
  public int deleteByNameAndValue(String sql,String name,Object params);
  /**
   * 根据sql语句进行删除
   * @param sql 删除的sql语句,需要写where 语句
   * @param params 传入参数,可变参数的形式
   * @return 返回删除的条数
   */
  public int deleteBySql(String sql,Object ... params);
  /**
   * 根据sql语句进行删除
   * @param sql 删除的sql语句,需要写where 语句
   * @param params 传入参数,集合的形式
   * @return 返回删除的条数
   */
  public int deleteBySql(String sql,List<Object> params);
  /**
   * 根据sql语句,进行更新
   * @param sql 更新的sql语句
   * @param params 传入参数,可变参数的形式
   * @return 返回更新的条数
   */
  public int updateEntity(String sql,Object ... params);
  /**
   * 根据sql语句,进行更新
   * @param sql 更新的sql语句
   * @param params 传入参数,集合的形式
   * @return 返回更新的条数
   */
  public int updateEntity(String sql,List<Object> params);
  /**
   * 根据id进行查询
   * @param sql 查询的语句,需要where 语句
   * @param id id编号
   * @return 返回查询出来的唯一一条记录
   */
  public T getInfoById(String sql,int id);
  /**
   * 根据某一属性进行查询
   * @param sql 查询的语句,不需要where 语句
   * @param name 查询的属性
   * @param params 参数
   * @return 返回查询出来的唯一一条记录,如果有多条,则只返回第一条。
   */
  public T getInfoByNameAndValue(String sql,String name,Object params);
  /**
   * 根据sql语句进行查询
   * @param sql 查询的语句,需要where 语句
   * @param params 参数, 可变参数的形式
   * @return 返回查询出来的唯一一条记录,如果有多条,则只返回第一条
   */
  public T getInfoBySql(String sql,Object ...params);
  /**
   * 根据sql语句进行查询
   * @param sql 查询的语句,需要where 语句
   * @param params 参数,集合的形式
   * @return 返回查询出来的唯一一条记录,如果有多条,则只返回第一条
   */
  public T getInfoBySql(String sql,List<Object> params);
  /**
   * 根据某一属性 进行查询多条记录
   * @param sql 查询的语句 ,不需要where 语句
   * @param name 属性
   * @param params 参数值
   * @return 返回查询出来的多条记录
   */
  public List<T> findInfosByNameAndValue(String sql,String name,Object params);
  /**
   * 根据sql语句查询多条记录
   * @param sql sql语句,需要where 语句
   * @param params 参数, 可变参数的形式
   * @return 返回查询出来的多条记录
   */
  public List<T> findInfosBySql(String sql,Object ...params);
  /**
   * 根据sql语句查询多条记录
   * @param sql sql语句,需要where 语句
   * @param params 参数, 集合的形式
   * @return 返回查询出来的多条记录
   */
  public List<T> findInfosBySql(String sql,List<Object> params);
  /**
   * 根据sql语句查询多条记录
   * @param sql sql语句,不传入筛选条件
   * @return 返回查询出来的多条记录
   */
  public List<T> findAll(String sql);
  /**
   * 根据 sql语句的id,查询出多条记录
   * @param sql sql语句
   * @param ids id的可变参数形式
   * @return 返回根据ids查询出来的多条记录
   */
  public List<T> findInfosByIds(String sql,Object ... ids);
  /**
   * 根据 sql语句的id,查询出多条记录
   * @param sql sql语句
   * @param ids id的集合形式
   * @return 返回根据ids查询出来的多条记录
   */
  public List<T> findInfosByIds(String sql,List<Object> ids);
  /**
   * 根据 sql语句的任一属性,查询出多条记录
   * @param sql sql语句
   * @param params names的可变参数形式
   * @return 返回根据names 查询出来的多条记录
   */
  public List<T> findInfosByNames(String sql,Object ...params);
  /**
   * 根据 sql语句的任一属性,查询出多条记录
   * @param sql sql语句
   * @param params names的 集合形式
   * @return 返回根据names 查询出来的多条记录
   */
  public List<T> findInfosByNames(String sql,List<Object> params);
  /**
   * 分页查询 记录
   * @param sql sql语句,不需要写 limit 语句
   * @param params 参数,集合的形式
   * @param currentPage 当前页
   * @param pageSize 页所显示的记录数
   * @return 返回 当前页的记录
   */
  public List<T> pageInfosBySql(String sql,List<Object> params,int currentPage,int pageSize);
  /**
   * 分页查询 记录
   * @param sql sql语句,不需要写 limit 语句
   * @param currentPage 当前页
   * @param pageSize 页所显示的记录数
   * @param params 参数,可变参数的形式
   * @return 返回 当前页的记录
   */
  public List<T> pageInfosBySql(String sql,int currentPage,int pageSize,Object ...params);
  /**
   * 统计总数
   * @param sql sql语句
   * @return 返回总的记录数
   */
  public int count(String sql);
  /**
   * 统计总数
   * @param sql sql语句
   * @param params 参数, 可变参数的形式
   * @return 返回总的记录数 
   */
  public int count(String sql,Object ... params);
  /**
   * 统计总数
   * @param sql sql语句
   * @param params 参数, 集合的形式
   * @return 返回总的记录数 
   */
  public int count(String sql,List<Object> params);
}


三.二 BaseDaoImpl



package com.yjl.utils;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
 @Description BaseDao实现类
*/
@SuppressWarnings("all")
public class BaseDaoImpl<T> implements BaseDao<T> {
  private T t;
  private Class clazz;
  private Object obj;
  public BaseDaoImpl() {
    //得到当前的类
    Class class1=this.getClass();
    //得到运行中的父类
    ParameterizedType parameterizedType=(ParameterizedType) class1.getGenericSuperclass();
    clazz=(Class) parameterizedType.getActualTypeArguments()[0];
    try {
      t=(T) clazz.newInstance();
    } catch (InstantiationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    //System.out.println("当前类的类:"+clazz.getName()+"完成初始化");
  }
  public BaseDaoImpl(Class cla) {
    clazz=cla;
    try {
      t=(T) clazz.newInstance();
    } catch (InstantiationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    //System.out.println("当前类的类:"+clazz.getName()+"完成初始化");
  }
  @Override
  public int insertEntity(String sql, Object... params) {
    return executeUpdate(sql, params);
  }
  @Override
  public int insertEntity(String sql, List<Object> params) {
    if(params!=null&&params.size()>0){
      return executeUpdate(sql);
    }
    return executeUpdate(sql,params.toArray());
  }
  @Override
  public int deleteById(String sql, int id) {
    return executeUpdate(sql,id);
  }
  @Override
  public int deleteByNameAndValue(String sql, String name, Object params) {
    String newSql=sql+" where "+name+" =?";
    return executeUpdate(newSql,params);
  }
  @Override
  public int deleteBySql(String sql, Object... params) {
    return executeUpdate(sql,params);
  }
  @Override
  public int deleteBySql(String sql, List<Object> params) {
    if(params!=null&&params.size()>0){
      return executeUpdate(sql);
    }
    return executeUpdate(sql,params.toArray());
  }
  @Override
  public int updateEntity(String sql, Object... params) {
    return executeUpdate(sql,params);
  }
  @Override
  public int updateEntity(String sql, List<Object> params) {
    if(params!=null&&params.size()>0){
      return executeUpdate(sql);
    }
    return executeUpdate(sql,params.toArray());
  }
  @Override
  public T getInfoById(String sql, int id) {
    return executeQuery(sql,id);
  }
  @Override
  public T getInfoByNameAndValue(String sql, String name, Object params) {
    String newSql=sql+" where "+name+" = ?";
    return executeQuery(newSql,params);
  }
  @Override
  public T getInfoBySql(String sql, Object... params) {
    return executeQuery(sql,params);
  }
  @Override
  public T getInfoBySql(String sql, List<Object> params) {
    if(params!=null&&params.size()>0){
      return executeQuery(sql);
    }
    return executeQuery(sql,params.toArray());
  }
  @Override
  public List<T> findInfosByNameAndValue(String sql, String name, Object params) {
    String newSql=sql+" where "+name+" =?";
    return executeListQuery(newSql,params);
  }
  @Override
  public List<T> findInfosBySql(String sql, Object... params) {
    return executeListQuery(sql,params);
  }
  @Override
  public List<T> findInfosBySql(String sql, List<Object> params) {
    if(params!=null&&params.size()>0){
      return executeListQuery(sql);
    }
    return executeListQuery(sql,params.toArray());
  }
  @Override
  public List<T> findAll(String sql) {
    return executeListQuery(sql);
  }
  @Override
  public List<T> findInfosByIds(String sql, Object... ids) {
    String newSql=sql+inSuffix(ids);
    return executeListQuery(newSql,ids);
  }
  @Override
  public List<T> findInfosByIds(String sql, List<Object> ids) {
    String newSql=sql+inSuffix(ids.toArray());
    return executeListQuery(newSql,ids);
  }
  @Override
  public List<T> findInfosByNames(String sql, Object... params) {
    String newSql=sql+inSuffix(params);
    return executeListQuery(newSql,params);
  }
  @Override
  public List<T> findInfosByNames(String sql, List<Object> params) {
    String newSql=sql+inSuffix(params.toArray());
    return executeListQuery(newSql,params);
  }
  //拼接in语句
  private String inSuffix(Object... params){
    StringBuilder  newSql=new StringBuilder("( ");
    for(int i=0;i<params.length;i++){
      if(i==params.length-1){
        newSql.append("?");
      }else{
        newSql.append("?,");
      }
    }
    newSql.append(" ) ");
    return newSql.toString();
  }
  private int getStart(int currentPage,int pageSize){
    return currentPage*(pageSize-1);
  }
  @Override
  public List<T> pageInfosBySql(String sql, List<Object> params, int currentPage, int pageSize) {
    String newSql=sql+" limit ?,?";
    params.add(getStart(currentPage,pageSize));
    params.add(pageSize);
    return executeListQuery(newSql,params.toArray());
  }
  @Override
  public List<T> pageInfosBySql(String sql, int currentPage, int pageSize, Object... params) {
    String newSql=sql+" limit ?,?";
    return executeListQuery(newSql,params,getStart(currentPage,pageSize),pageSize);
  }
  @Override
  public int count(String sql) {
    return countQuery(sql);
  }
  @Override
  public int count(String sql, Object... params) {
    return countQuery(sql,params);
  }
  @Override
  public int count(String sql, List<Object> params) {
    return countQuery(sql,params.toArray());
  }
  /**
   * 将所有的更新操作全部放置在此方法中 不同:参数类型相同 ,值不同 通过传入参数解决
   * 
   * @param sql
   * 占位符赋值 ?个数不同,?内值类型不同 数组 object
   * @return
   */
  protected int executeUpdate(String sql, Object ... params) {
    int num = -1;
    Connection conn =DBUtils.getConnection();
    PreparedStatement ptmt=null;
    ResultSet rs=null;
    try {
      ptmt = conn.prepareStatement(sql);
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          ptmt.setObject(i + 1, params[i]);
        }
      }
      num = ptmt.executeUpdate();
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeAll(rs, ptmt, conn);
    }
    return num;
  }
  /**
   * 通过语句和占位符的值查询得到返回结果值
   * 
   * @param sql
   * @param params
   * @return 返回查询后的结果集
   */
  protected int countQuery(String sql, Object ... params) {
    Connection conn =DBUtils.getConnection();
    PreparedStatement ptmt=null;
    ResultSet rs=null;
    Object singleInfo=null;
    int count=0;
    try {
      ptmt = conn.prepareStatement(sql);
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          ptmt.setObject(i + 1, params[i]);
        }
      }
      rs = ptmt.executeQuery();
      if(rs.next()){
        Number c=rs.getLong(1);
        count=c.intValue();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeAll(rs, ptmt, conn);
    }
    return count;
  }
  /**
   * 通过语句和占位符的值查询得到返回结果值
   * 
   * @param sql
   * @param params
   * @return 返回查询后的结果集
   */
  protected T executeQuery(String sql, Object ... params) {
    Connection conn =DBUtils.getConnection();
    PreparedStatement ptmt=null;
    ResultSet rs=null;
    Object singleInfo=null;
    try {
      ptmt = conn.prepareStatement(sql);
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          ptmt.setObject(i + 1, params[i]);
        }
      }
      rs = ptmt.executeQuery();
      singleInfo=ResultSetToBean.getObj(rs,t.getClass());
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeAll(rs, ptmt, conn);
    }
    if(singleInfo!=null){
      return (T)singleInfo;
    }else{
      return null;
    }
  }
  protected List<T> executeListQuery(String sql, Object ... params) {
    Connection conn =DBUtils.getConnection();
    PreparedStatement ptmt=null;
    ResultSet rs=null;
    Object listInfo=null;
    try {
      ptmt = conn.prepareStatement(sql);
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          ptmt.setObject(i + 1, params[i]);
        }
      }
      rs = ptmt.executeQuery();
      listInfo=ResultSetToBean.getList(rs,t.getClass());
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeAll(rs, ptmt, conn);
    }
    if(listInfo!=null){
      return (List<T>) listInfo;
    }else{
      return null;
    }
  }
}


三.三 ResultSet 转换成 JavaBean


package com.yjl.utils;
/**
 * 利用反射机制从ResultSet自动绑定到JavaBean:
 * 要求:JavaBean的字段和ResultSet的字段名或 别名 一样(不区分大小写)
 *     注意:如果JavaBean的字段和数据库表的字段名不一样,那么在查询语句中使用对应的别名即可!
 * 
 * 用到的是jdbc进行对数据库查询,这里是根据JavaBean中的属性名进行查询的,
 * 所以属性名要和字段名一致,
 * 然后再利用反射,将表字段映射到JavaBean中对应的属性。
 */
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ResultSetToBean {
    /**
     * 获取结果集的所有结果,存放到ArrayList里
     * 
     * @param rs 查询结果,ResultSet
     * @param clazz JavaBean类型,如Article.class
     * @return ArrayList,存放映射后的JavaBean对象
     */
    public static <T> List<T> getList(ResultSet rs, Class<T> clazz) {
        // 获取JavaBean里面的所有属性
        Field[] field = clazz.getDeclaredFields();
        T obj = null;
        // 创建list容器,存放映射后的JavaBean对象
        List<T> list = new ArrayList<T>();
        try {
            ResultSetMetaData rsmd = rs.getMetaData();  
            // 获取记录集中的列数  
            int counts = rsmd.getColumnCount();  
            // 定义counts个String 变量  
            String[] columnNames = new String[counts];  
            // 给每个变量赋值(字段名称全部转换成大写)  
            for (int i = 0; i < counts; i++) {  
                // getColumnLabel() 取别名(如有) 即SQL AS的值
                // getColumnName() 取字段名:
                columnNames[i] = rsmd.getColumnLabel(i + 1).toUpperCase(); 
            } 
            List<String> columnNameList = Arrays.asList(columnNames);
            // System.out.println(columnNameList);
            // 开始遍历查询结果
            while (rs.next()) {
                // 创建Javabean对象
                obj = clazz.newInstance();
                // 循环将查询结果写入对应的JavaBean属性中
                for (Field f : field) {
                    // 获取该字段名称
                    String name = f.getName();
                    // 判断该字段是否在ResultSet的字段里,在的话才去进行赋值操作
                    // 如果不进行判断的话,在JavaBean字段比ResultSet字段多的情况下,会抛异常
                    if(columnNameList.contains(name.toUpperCase())) {
                        // 判断是否查询到对应的值
                        if (rs.getObject(name) != null) {
                          Object newObj=rs.getObject(name);
                          if(newObj instanceof java.sql.Date){
                            java.sql.Date sqlD=(java.sql.Date)newObj;
                            java.util.Date utilD=new java.util.Date(sqlD.getTime());
                            newObj=utilD;
                          }
                          if(newObj instanceof java.lang.Long){
                            Long lD=(Long)newObj;
                            int iD=lD.intValue();
                            newObj=iD;
                          }
                            // 跳过检查,这里访问的时私有属性
                            f.setAccessible(true);
                            // 将查询到的值付给对应的属性
                            f.set(obj, newObj);
                        }
                    } 
                }
                // 把结果的每一列都添加到list中
                list.add(obj);
            }
        } catch (SQLException e) {
            System.err.println("结果集遍历失败");
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("数据读取失败");
            e.printStackTrace();
        }
        return list;
    }
    /**
     * 只取结果集的第一条结果
     * 
     * @param rs 查询结果,ResultSet
     * @param clazz JavaBean类型,如Article.class
     * @return JavaBean对象
     */
    public static <T> T getObj(ResultSet rs, Class<T> clazz) {
        //Class<T> clazz = (Class<T>) t.getClass();
        // 获取JavaBean里面的所有属性
        Field[] field = clazz.getDeclaredFields();
        T obj = null;
        try {
            ResultSetMetaData rsmd = rs.getMetaData();  
            // 获取记录集中的列数  
            int counts = rsmd.getColumnCount();  
            // 定义counts个String 变量  
            String[] columnNames = new String[counts];  
            // 给每个变量赋值(字段名称全部转换成大写)  
            for (int i = 0; i < counts; i++) {  
                columnNames[i] = rsmd.getColumnLabel(i + 1).toUpperCase(); 
            } 
            List<String> columnNameList = Arrays.asList(columnNames);
            // System.out.println(columnNameList);
            // 获取第一条记录
            if (rs.next()) {
                // 创建Javabean对象
                obj = clazz.newInstance();
                // 循环将查询结果写入对应的JavaBean属性中
                for (Field f : field) {
                    // 获取该字段名称
                    String name = f.getName();
                    // 判断该字段是否在ResultSet的字段里,在的话才去进行赋值操作
                    if(columnNameList.contains(name.toUpperCase())) {
                        // 判断是否查询到对应的值
                        if (rs.getObject(name) != null) {
                          Object newObj=rs.getObject(name);
                          if(newObj instanceof java.sql.Date){
                            java.sql.Date sqlD=(java.sql.Date)newObj;
                            java.util.Date utilD=new java.util.Date(sqlD.getTime());
                            newObj=utilD;
                          }
                          if(newObj instanceof java.lang.Long){
                            Long lD=(Long)newObj;
                            int iD=lD.intValue();
                            newObj=iD;
                          }
                            // 跳过检查,这里访问的时私有属性
                            f.setAccessible(true);
                            // 将查询到的值付给对应的属性
                            f.set(obj, newObj);
                        }
                    } 
                }
            }
        } catch (SQLException e) {
            System.err.println("结果集操作失败");
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("数据读取失败");
            e.printStackTrace();
        }
        return obj;
    }
}


四. BaseServlet


自己编写的 Servlet, 需要继承 BaseServlet.


prefix 和 suffix 是跳转的jsp 的配置信息。




package com.yjl.utils;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
/**
 * 通用的servlet
 * @author 两个蝴蝶飞
 *
 */
@SuppressWarnings("all")
public class BaseServlet extends HttpServlet {
  //定义前缀
  private static String prefix;
  //定义后缀
  private static String suffix;
  {
    prefix="/WEB-INF/pages/";
    suffix=".jsp";
  }
  /**
   * 提交请求  执行方法时, User?method=login, 参数需要写 req,resp
   *     跳转到某个页面, User?jsp=toLogin, 参数不需要写 req,resp
   */
  @Override
  protected void service(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    try {
      req.setCharacterEncoding("utf-8");
      //标识 0是方法,1是界面 2 是默认
      int flag=0;
      String method = req.getParameter("method");
      //判断如果method为空
      if(method == null) {
        method=req.getParameter("jsp");
        if(method==null){
          method = "execute";
          flag=2;
        }else{
          flag=1;
        }
      }
      //得到当前请求的servlet,当前运行的类,得到UserServlet类的Class
      Class clazz = this.getClass();
      String result="";
      if(flag==0||flag==2){
        //根据得到传递过来的名称,让名称对应的方法去执行
        Method m1 = clazz.getMethod(method, HttpServletRequest.class,HttpServletResponse.class);
        //让方法执行
        result= (String) m1.invoke(clazz.newInstance(), req,resp);
      }else if(flag==1){
        //根据得到传递过来的名称,让名称对应的方法去执行
        Method m1 = clazz.getMethod(method);
        //让方法执行
        result= (String) m1.invoke(clazz.newInstance());
      }else{
        //是默认的
        result="";
      }
      if(result != null) {
        //转发操作
        if(result.indexOf("?method=")==-1){
          result=prefix+result+suffix;  
        }
        req.getRequestDispatcher(result).forward(req, resp);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } 
  }
  /**
   * 将指定Java对象转为json,并响应到客户端页面
   * @param o
   * @param exclueds
   */
  public void java2Json(HttpServletResponse resp,Object o ,String[] exclueds){
    JsonConfig jsonConfig = new JsonConfig();
    //指定哪些属性不需要转json
    jsonConfig.setExcludes(exclueds);
    JSONObject objData=JSONObject.fromObject(o,jsonConfig);
    JSONObject objMap=new JSONObject();
    objMap.put("data",objData);
    objMap.put("status",true);
    resp.setContentType("text/json;charset=utf-8");
    try {
      resp.getWriter().print(objMap.toString());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /**
   * 将指定Java对象转为json,并响应到客户端页面
   * @param o
   * @param exclueds
   */
  public void java2Json(HttpServletResponse resp,List o ,String[] exclueds){
    JsonConfig jsonConfig = new JsonConfig();
    //指定哪些属性不需要转json
    jsonConfig.setExcludes(exclueds);
    JSONArray objData=JSONArray.fromObject(o,jsonConfig);
    JSONObject objMap=new JSONObject();
    objMap.put("data",objData);
    objMap.put("status",true);
    resp.setContentType("text/json;charset=utf-8");
    try {
      resp.getWriter().print(objMap.toString());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /**
   * 将状态返回到前台,通常是添加,删除,更新的操作,如果错误,则传入错误代码。
   * @param o
   * @param exclueds
   */
  public void map2Json(HttpServletResponse resp,String ... code){
    JsonConfig jsonConfig = new JsonConfig();
    //指定哪些属性不需要转json
    JSONObject objMap=new JSONObject();
    if(code==null||code.length<1){
      objMap.put("status",true);
    }else{
      objMap.put("status",false);
      objMap.put("error_code",code[0]);
    }
    resp.setContentType("text/json;charset=utf-8");
    try {
      resp.getWriter().print(objMap.toString());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /**
   * 传入是否成功,只返回状态
   * @param o
   * @param exclueds
   */
  public void boolean2Json(HttpServletResponse resp,boolean flag){
    JsonConfig jsonConfig = new JsonConfig();
    //指定哪些属性不需要转json
    JSONObject objMap=new JSONObject();
    objMap.put("status",true);
    objMap.put("flag",flag);
    resp.setContentType("text/json;charset=utf-8");
    try {
      resp.getWriter().print(objMap.toString());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /**
   * 将请求的参数,转换成相应的 JavaBean 
   * @param req
   * @param clazz
   * @return
   */
  public <T> T reqParamToBean(HttpServletRequest req,Class <T> clazz){
    T t=null;
    try {
      t = clazz.newInstance();
      Map<String ,String []> paramMap=req.getParameterMap();
      BeanUtils.populate(t,paramMap);
    } catch (Exception e) {
      // TODO 自动生成的 catch 块
      e.printStackTrace();
    }
    return t;
  }
  public String getPrefix() {
    return prefix;
  }
  public void setPrefix(String prefix) {
    this.prefix = prefix;
  }
  public String getSuffix() {
    return suffix;
  }
  public void setSuffix(String suffix) {
    this.suffix = suffix;
  }
}


五. 开发过程举例


以 User 信息进行相应的举例.


结构信息如下所示:



20200510181351654.png


五.一 pojo 下的 User.java



package com.yjl.pojo;
/**
 * 
 * @author 两个蝴蝶飞
 * 员工表, 放置实体
 *
 */
public class User {
/**
 * @param id id编号
 * @param code 员工编号
 * @param name 员工姓名
 * @param password 密码
 */
  private Integer id;
  private String code;
  private String name;
  private String password;
  //实现setter 和getter方法
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getCode() {
    return code;
  }
  public void setCode(String code) {
    this.code = code;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  //实现toString() 方法
  @Override
  public String toString() {
    return "User [id=" + id + ", code=" + code + ", name=" + name + ", password=" + password + "]";
  }
}


五.二 开发 Dao层


五.二.一 创建 UserDao



package com.yjl.dao;
import com.yjl.pojo.User;
import com.yjl.utils.BaseDao;
/**
 * 
 * @author 两个蝴蝶飞
 * User 的接口, 可以扩展 BaseDao 里面没有的方法
 */
public interface UserDao extends BaseDao<User>{
}


五.二.二 实现 UserDaoImpl



package com.yjl.dao.impl;
import com.yjl.dao.UserDao;
import com.yjl.pojo.User;
import com.yjl.utils.BaseDaoImpl;
/**
 * 
 * @author 两个蝴蝶飞
 * 放置 dao  实现类
 *
 */
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{
}


五.三 开发 service 层


五.三.一 创建 UserService



package com.yjl.service;
import com.yjl.pojo.User;
/**
 * 
 * @author 两个蝴蝶飞
 * 业务逻辑验证
 */
public interface UserService {
  public User login(User user);
}


五.三.二 实现UserServiceImpl


package com.yjl.service.impl;
import com.yjl.dao.UserDao;
import com.yjl.dao.impl.UserDaoImpl;
import com.yjl.pojo.User;
import com.yjl.service.UserService;
import com.yjl.utils.MD5Utils;
/**
 * 
 * @author 两个蝴蝶飞
 * 业务验证
 *
 */
public class UserServiceImpl implements UserService{
  //注入 userDao 对象
  private UserDao userDao;
  /**
   * 举例,登录的方法
   */
  @Override
  public User login(User user) {
    userDao=new UserDaoImpl();
    String sql="select * from user where code=? and password=? ";
    return userDao.getInfoBySql(sql,user.getCode(),MD5Utils.md5(user.getPassword()));
  }
}


五.四 开发 Servlet


package com.yjl.web.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.yjl.pojo.User;
import com.yjl.service.UserService;
import com.yjl.service.impl.UserServiceImpl;
import com.yjl.utils.BaseServlet;
/**
 * 
 * @author 两个蝴蝶飞
 * 
 *  Servlet 控制器
 *
 */
@WebServlet("/User")
public class UserServlet extends BaseServlet{
  private static final long serialVersionUID = 1L;
  //注入UserService 对象
  private UserService userService;
  //跳转到登录页面,是页面,不需要req,resp对象 。  
  //访问网址形式为: /User?jsp=toLogin
  public String toLogin(){
    //完整的前缀和后缀,已经在 BaseServlet里面定义好了
    return "login";
  }
  //具体的登录方法, 需要接收数据,要req,resp对象。 
  public void login(HttpServletRequest req,HttpServletResponse resp){
    //将请求信息参数,封装到对象里面。
    User userInfo=super.reqParamToBean(req,User.class);
    //实例化service 对象
    userService=new UserServiceImpl();
    //从数据库中查询信息 
    User user=userService.login(userInfo);
    if(user!=null){
      //说明登录成功
      HttpSession session=req.getSession();
      session.setAttribute("loginUser",user);
      super.boolean2Json(resp, true);
    }else{
      //代码为001,表示用户名或者密码错误
       super.map2Json(resp,"001");
    }
  } 
  /**
   * 
   * 跳转到登录的页面 
   */
  public String toList(){
    return "user";
  }
}


五.五 测试


输入网址: http://localhost:8080/Servlet_Dev/User?jsp=toLogin, 会跳转到登录的页面



20200510181405261.png


输入网址: localhost:8080/Servlet_Dev/User?method=login&code=1234&password=1234 ,会执行 login 的方法



20200510181400418.png


输入网址:http://localhost:8080/Servlet_Dev/User?method=login&code=admin&password=1234, 会执行login的方法



20200510181411705.png


本章节代码链接为:



链接:https://pan.baidu.com/s/1Ove6HDywWcZDr9fRJO-LZg 
提取码:q31l


谢谢您的观看!!!

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4天前
|
前端开发 JavaScript Java
Java与Web开发的结合:JSP与Servlet
Java与Web开发的结合:JSP与Servlet
8 0
|
19天前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
|
1月前
|
前端开发 Java API
深入理解Servlet技术:Java Web开发的核心
【4月更文挑战第3天】Servlet是Java Web开发的核心技术,定义了响应客户端请求的接口。它遵循请求-响应模型,处理动态Web内容,生命周期由Web容器管理。Servlet API包含接口和类,如HttpServletRequest和HttpServletResponse,支持请求处理和会话管理。尽管现代开发常使用Spring MVC等框架,但理解Servlet对于理解框架底层机制至关重要。掌握Servlet基础知识对构建健壮的Web应用仍然必要。
|
2月前
|
Java 数据处理 数据库
Java Web开发中的Servlet
Java Web开发中的Servlet
|
3月前
|
Java 应用服务中间件 API
深入解析Java Servlet技术在Web开发中的应用
深入解析Java Servlet技术在Web开发中的应用
216 1
|
4月前
|
XML 前端开发 Java
Web开发: 什么是Servlet和JSP?
Web开发: 什么是Servlet和JSP?
92 0
|
7月前
|
SQL 前端开发 Java
JSP网上订餐管理系统myeclipse开发sql数据库BS模式java编程servlet技术mvc框架
JSP 网上订餐管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助servlet技术mvc框架,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用java语言开发,系统主要采用B/S模式开发。
40 0
|
7月前
|
存储 设计模式 JavaScript
掌握JavaWeb开发的必备技能:Servlet、JSP、Cookie、Session、EL、JSTL详解 ~~~~B站老杜--Servlet-JSP-课堂笔记(三)
当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了。)之后,被web服务器自动调用。 思考一个业务场景
48 0
|
7月前
|
前端开发 Java 应用服务中间件
掌握JavaWeb开发的必备技能:Servlet、JSP、Cookie、Session、EL、JSTL详解 ~~~~B站老杜--Servlet-JSP-课堂笔记(一)
对于一个动态的web应用来说,一个请求和响应的过程有多少个角色参与,角色和角色之间有多少个协议
53 0
|
9月前
|
设计模式 容器
JavaWeb开发 Servlet技术详解(五)
JavaWeb开发 Servlet技术详解(五)