使用 Tomcat9.0 , spring5.0框架原始工厂类解耦,druid-1.0.9jar版本,JDK9,MSQL8版本数据库 模拟web页面登录案例时候出现druid.properties文件找不到的报错信息,详情如下【案例代码贴最后】;
按照正常来讲,配置文件放在src 目录下面,然后copy相对路径就行,可阿里就是反人类;
运行报错,web浏览器空指针,IDEA中:
解决办法,只能copy全路径来解决报错了;
再次运行,跑起来了溜溜的;
另外一种解决方法使用类加载器的方式:
FileInputStream fis = new FileInputStream(JdbcUtils.class.getResource("/").getPath() + "druid.properties");
Properties p = new Properties();
p.load(fis);
项目结构如下:
① 先 jar 包【在lib 中】,以及配置文件【在src下】;
② 写 案例页面 log.html;
③ 开发 utils 工具类【包括获取 jdbcTemplate 的,以及 获取 bean 的 BeanFactory】,本次测试使用了c3p0,和 druid 两种方式进行了测试;
④开发 bean【和数据库中 table 对应】 , dao层,daoImpl层 ,service层,serviceImpl层【需要解耦】,servlet 中【解耦】
⑤进行测试【Spring的xml 配置完成登录案例 的 CRUD写过在bolg中自己看】
配置文件,按照项目结构来【不做一 一说明】:
tUserDao=com.baidu.daoImpl.TUserDaoImpl
tUserService=com.baidu.serviceImpl.TUserServiceImpl
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/reba?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false
root
root
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/reba?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false
root
root
driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/reba?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false
username=root
password=root
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/reba?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=root
实体bean类和数据库对应即可,数据库table如下【 id int , userName varchar , password varchar】:
页面 form 表单中 action 为servlet的 urlParttens;
Bootstrap 101 Template
效果:
开发 utils 工具类;
beans工厂类;
package com.baidu.utils;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.ResourceBundle;
/**
* @auther SyntacticSugar
* @data 2018/9/29 0029下午 10:50
*/
public class BeanFactory {
private static ResourceBundle rb = ResourceBundle.getBundle("beans");
private static HashMap map = new HashMap<>();
static {
try {
Enumeration keys = rb.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
String value = rb.getString(key); //从beans.properties中获取value全路径
Object o = Class.forName(value).getDeclaredConstructor().newInstance();
map.put(key, o);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取 bean
* @param beanName
* @return
*/
public static Object getBeans(String beanName) {
return map.get(beanName);
}
}
连接数据,获取 template ;
package com.baidu.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
/**
* @auther SyntacticSugar
* @data 2018/9/29 0029下午 10:22
*/
public class JdbcUtils {
private static JdbcTemplate template;
private static Connection conn;
private static PreparedStatement statement;
private static ResultSet res;
/**
* 获取 template
*/
public static JdbcTemplate getJdbcTemplate() {
try { //druid
FileInputStream fis = new FileInputStream(JdbcUtils.class.getResource("/").getPath() + "druid.properties");
Properties p = new Properties();
p.load(fis);
// p.load(new FileReader("druid.properties")); // 报错加载不了文件,可以使用绝对路径
DataSource dataSource = DruidDataSourceFactory.createDataSource(p);
//c3p0 连接数据库,获取jdbcTemplate
// ComboPooledDataSource dataSource = new ComboPooledDataSource();
template = new JdbcTemplate(dataSource);
} catch (Exception e) {
e.printStackTrace();
}
return template;
}
/**
* 释放资源
* @param res
* @param statement
* @param conn
*/
public static void release(ResultSet res, PreparedStatement statement, Connection conn) {
try {
if (res != null) {
res.close();
}
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
dao 层 【说明下使用 template的query 方法查询 是因为userName&password 可能在数据库中存在多个,若按照 id 来查询就可以使用queryForObject ,id的唯一性 ;另外在传数据的时候可以把 userName&password 从dao层就封装 成 TUser 对象,这样传参时候直接传一个TUser 对象即可】 ;
package com.baidu.dao;
import com.baidu.Beans.TUser;
import java.util.List;
/**
* @auther SyntacticSugar
* @data 2018/9/29 0029下午 10:17
*/
public interface TUserDao {
//通过userName password 查询
List findTUserByNameAndPsw(String userName,String password);
}
dao现实类;
package com.baidu.daoImpl;
import com.baidu.Beans.TUser;
import com.baidu.dao.TUserDao;
import com.baidu.utils.JdbcUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
/**
* @auther SyntacticSugar
* @data 2018/9/29 0029下午 10:43
*/
public class TUserDaoImpl implements TUserDao {
@Override
public List findTUserByNameAndPsw(String userName, String password) {
JdbcTemplate template = JdbcUtils.getJdbcTemplate();
String sql="select * from t_user where userName=? and password=?";
List list = template.query(sql, new BeanPropertyRowMapper(TUser.class), userName, password);
return list;
}
}
service层 ;
package com.baidu.service;
public interface TUserService {
Boolean login(String userName, String password);
}
service实现类 【该层解耦, 因为使用到 daoImpl 的类,普通使用创建new ,耦合性较高,通过AOP来降低耦合性,这里采用spring的老工厂类的方式获取 bean的全限定名,通过反射创建daoImpl 的类的对象,以此降低 各层 间的耦合性;PS:降低耦合不是没有耦合,只不过更改类等在配置文件中更改摆了,不用动 java代码 ,当然相较于xml 以及注解的方式,这方式太low,仅作为了解学习使用】;
使用接口接收daoImpl 这样体现出面向接口编程的思想【ps:并卵,使用注解开发解耦没人用这个】;
package com.baidu.serviceImpl;
import com.baidu.Beans.TUser;
import com.baidu.dao.TUserDao;
import com.baidu.daoImpl.TUserDaoImpl;
import com.baidu.service.TUserService;
import com.baidu.utils.BeanFactory;
import java.util.List;
/**
* @auther SyntacticSugar
* @data 2018/9/29 0029下午 10:47
*/
public class TUserServiceImpl implements TUserService {
@Override
public Boolean login(String userName, String password) {
TUserDao tUserDao = (TUserDaoImpl) BeanFactory.getBeans("tUserDao");//使用接口接收
// TUserDaoImpl tUserDao = new TUserDaoImpl();
List list = tUserDao.findTUserByNameAndPsw(userName, password);
//对list进行处理 ,返回TUser
if(list.size()==0){
return false;
}else {
return true;
}
}
}
servlet ,登录成功跳转至百度,否则就在页面实现没有登陆成功;
package com.baidu.session;
import com.baidu.Beans.TUser;
import com.baidu.service.TUserService;
import com.baidu.serviceImpl.TUserServiceImpl;
import com.baidu.utils.BeanFactory;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet(name = "Log", urlPatterns = "/log")
public class Log extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);//
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//
String userName = request.getParameter("userName");
String password = request.getParameter("password");
//调用serviceImpl
TUserService o = (TUserServiceImpl) BeanFactory.getBeans("tUserService");//使用接口接收
// TUserServiceImpl o = new TUserServiceImpl();
Boolean login = o.login(userName, password);
//
if (login) { //登陆成功,重定向至百度
System.out.println("ok");
response.sendRedirect("http://www.baidu.com");
}else { //失败,转发至jsp
System.out.println("登录失败");
request.setAttribute("info","登录失败" );
request.getRequestDispatcher("log.html").forward(request,response );
}
}
}
点击启动Tomcat,页面自动加载,输入userName&password进行测试 ;
这里说下需要在 web.xml 中 配置列表;贴上配置不多说;
log.html
product.html
regist.html
login.html
跑了起来了,重点在druid.properties 在Tomcat 中部署以后,报错找不到文件;