搭建一个基本的 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包有:
二. 读取 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&¶ms.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&¶ms.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&¶ms.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&¶ms.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&¶ms.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 信息进行相应的举例.
结构信息如下所示:
五.一 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, 会跳转到登录的页面
输入网址: localhost:8080/Servlet_Dev/User?method=login&code=1234&password=1234 ,会执行 login 的方法
输入网址:http://localhost:8080/Servlet_Dev/User?method=login&code=admin&password=1234, 会执行login的方法
本章节代码链接为:
链接:https://pan.baidu.com/s/1Ove6HDywWcZDr9fRJO-LZg 提取码:q31l
谢谢您的观看!!!