本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用

内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。

本人互联网技术爱好者,互联网技术发烧友

微博:伊直都在0221

QQ:951226918

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

1.面向接口编程的优势

  1)增加了程序的课扩展性,降低耦合度。即,只需要知道方法就好了,具体的实现不关注。如果需要新的功能,添加在接口中添加方法的声明,还有具体的实现类,这就是可扩展性。

  2)程序的可配置性。通过一个配置的修改,就可以达到不同的实现的目的。

2.面向接口编程的实例。结合上mvc综合实践

  需求:通过MVC设计模式,实现对用户的增删改查操作。提供两种实现方式:jdbc,xml ; 通过工场模式 和 MVC设计模式 实现对实现方式的切换。

  代码:①  CustomerDAOFactory: 单例的 CustomerDAO 工场类。采用饿汉式,线程安全。返回一个CustomerDAO 对象的工厂。

     ②  InitServlet: 一个Servlet 类,实现了init() 方法,读取  实现方式 配置文件  switch.properties , 获取 设置的 type。

     ③  CustomerServlet2: 前台请求的Servlet, 其中有一个CutomerDAO 的私有属性。可以由CustomerDAOFactory 创建。

       ④  CustomerDAOXMLImpl: CustomerDAO 接口的XML 形式的实现类。

     ⑤  CustomerDAOJdbcImpl: CustomerDAO 接口的JDBC实现类。

     ⑥  switch.properties: 实现方式 type 的配置文件。

       ⑦  customer.xml: customer 的xml 存储文件

     ⑧  web.xml:  web的配置文件。此处只需配置 InitServlet的加载时间。而Servlet 的url-parttern 则由系统通过注解的方式实现配置

     ⑨  CustomerDAO : 操作 customer的 DAO接口

接口的关系图:
  

3.具体代码的实现:

  1)CustomerDAOFactory.java

 package com.jason.mvcapp.dao.factory;

 import java.util.HashMap;
import java.util.Map; import com.jason.mvcapp.dao.CustomerDAO;
import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl;
import com.jason.mvcapp.dao.impl.CustomerDAOXMLImpl; /***
*
* @author: jason
* @time:2016年5月28日下午5:37:39
* @description:单例的 CustomerDAO 工场类。采用饿汉式,线程安全
*/
public class CustomerDAOFactory { private Map<String , CustomerDAO> daos = new HashMap<String, CustomerDAO>(); //1.私有化构造器
private CustomerDAOFactory(){ daos.put("jdbc", new CustomerDAOJdbcImpl());
daos.put("xml", new CustomerDAOXMLImpl()); }
//2.创建一个静态的实例
private static CustomerDAOFactory instance = new CustomerDAOFactory();
//3.提供获取实例的方法
public static CustomerDAOFactory getInstance() {
return instance;
} private static String type = null; public void setType(String type) {
this.type = type;
} public static String getType() {
return type;
}
public CustomerDAO getCustomerDAO(){ return daos.get(type);
} }

    2)InitServlet.java

 package com.jason.mvcapp.servlet;

 import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet; import com.jason.mvcapp.dao.factory.CustomerDAOFactory; /**
* Servlet implementation class InitServlet
*/
@WebServlet("/InitServlet")
public class InitServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override
public void init() throws ServletException {
CustomerDAOFactory.getInstance().setType("jdbc"); //1.读取类路径下的switch.properties 配置文件
InputStream is = getServletContext().getResourceAsStream("/WEB-INF/classes/switch.properties"); Properties properties = new Properties();
try {
properties.load(is); //2.获取switch.properties 的type 值
String type = properties.getProperty("type"); //3.赋值给CustomerDAOFactory 的type 属性
CustomerDAOFactory.getInstance().setType(type); } catch (IOException e) {
e.printStackTrace();
}
} }

  3)CustomerServlet2.java

 package com.jason.mvcapp.servlet;

 import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List; 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 com.jason.mvcapp.dao.CustomerDAO;
import com.jason.mvcapp.dao.factory.CustomerDAOFactory;
import com.jason.mvcapp.dao.impl.CustomerDAOJdbcImpl;
import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; /**
* Servlet implementation class CustomerServlet2
*/
@WebServlet("*.do")
public class CustomerServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L; // 创建一个CustomerDAO对象,多态
27 private CustomerDAO customerDAO = CustomerDAOFactory.getInstance().getCustomerDAO();

protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
} protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 1.获取servletPath:/add.do 或者 query.do
String serveltPath = request.getServletPath(); // System.out.println(serveltPath);
// 2.去除/ 和 .do 得到对应的方法,如 add query
String methodName = serveltPath.substring(1);
methodName = methodName.substring(0, methodName.length() - 3);
// System.out.println(methodName); try {
// 3.利用反射获取methodName对应的方法
Method method = getClass().getDeclaredMethod(methodName,
HttpServletRequest.class, HttpServletResponse.class); // 4.利用反射调用方法
method.invoke(this, request, response);
} catch (Exception e) { e.printStackTrace();
}
} private void updateCustomer(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("update");
request.setCharacterEncoding("UTF-8"); //1.获取请求信息:id,name,address,phone,oldName //1.1 隐藏域的 值
String idStr = request.getParameter("id");
String oldNameStr = request.getParameter("oldName"); //1.2 提交的值
String nameStr = request.getParameter("name");
String addressStr = request.getParameter("address");
String phoneStr = request.getParameter("phone"); //2.验证name 是否可用
//通过equalsIgnoreCase() 方式 避免了 大小写的问题。equals 方法区分大小写, 而数据库SQL 不区分大小写
if(!oldNameStr.equalsIgnoreCase(nameStr)){
//2.1 先比较name 和 oldName 是否相同,若相同,说明name 可用
//2.2 若不相同,则调用CustomerDAO 的getCostomerWithName(String name) 获取 name 在数据库中是否存在
long rel = customerDAO.getCountWithName(nameStr);
//2.2.1 若存在,则返回值大于 0,则响应 updatecustomer.jsp 页面:通过转发的方式
if(rel > 0){
// 进行回显字符串,在request 中放入一个属性 message:用户名 name
// 回显:updatecustomer.jsp 的表单值可以回显
// value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>" 进行回显
// 注意:name 显示的是 oldName,而address 和 phone 显示的是新的
request.setAttribute("message", "用户名 " + nameStr + " 已经被占用了,请重新选择!");
//2.2.2 存在,要求在updatecustomer.jsp 页面显示一条消息:用户名 name 已经被占用了,请重新选择
request.getRequestDispatcher("/updatecustomer.jsp").forward(request,response);
// 2.2.3 结束方法:return
return;
}
} //3.通过验证后,则将表单封装为一个Customer 对象 customer
Customer customer = new Customer(nameStr, addressStr, phoneStr);
customer.setId(Integer.parseInt(idStr)); //4.调用CustomerDAO 的save(Customer customer) 执行更新操作
customerDAO.update(customer); //5.重定向到 query.do
response.sendRedirect("query.do"); } private void editeCustomer(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("edit");
String forwardPath = "/error.jsp";
//1. 获取请求参数id
String idStr = request.getParameter("id");
try {
//2. 调用CustomerDAO 的get(id) 方法,获取 和id 对应的Customer 对象
Customer customer = customerDAO.get(Integer.parseInt(idStr));
if(customer != null){
forwardPath ="/updatecustomer.jsp";
//3. 将 customer 放入 request 中
request.setAttribute("customer", customer);
}
} catch (Exception e) {}
//4. 响应updatecustomer.jsp 页面: 转发的形式
request.getRequestDispatcher(forwardPath).forward(request, response); } private void deleteCustomer(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 1.获取请求删除的 id 为 String 类型
String idStr = request.getParameter("id");
// try{}catch{} 的作用:方式idStr 不能转化为 int 类型,若不能转则 id = 0,无法进行任何删除
int id = 0;
try {
// 2.将idStr 解析为int 型
id = Integer.parseInt(idStr);
// 3.调用dao方法 删除数据
customerDAO.delete(id);
} catch (Exception e) {
e.printStackTrace();
}
response.sendRedirect("query.do"); } private void query(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone"); CriteriaCustomer criteriaCustomer = new CriteriaCustomer(name, address,
phone);
List<Customer> lists = customerDAO
.getForListWithCriteriaCustomer(criteriaCustomer); // //1.调用CustomerDAO 的getAll()方法的到Customer 集合
// List<Customer> lists = customerDAO.getAll();
// 2.把Customer 集合放入request
request.setAttribute("list", lists);
// 3.转发页面到index.jsp
request.getRequestDispatcher("/index.jsp").forward(request, response); } private void addCustomer(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException { System.out.println("add function");
request.setCharacterEncoding("UTF-8");
// 1.获取表单参数:name,address,phone
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone"); // 2.检验 name 是否已经被占用
// 2.1调用 CustomerDAO 的 getCountWithName(String name) 获取 name 在数据库中是否存在 long rel = customerDAO.getCountWithName(name);
// 2.2 若返回值大于0,则响应newcustomer.jsp 页面:
if (rel > 0) {
// 2.2.1 要求在newcustomer.jsp 页面显示一条消息:用户名 name 已经被占用了,请重新选择
// 在request 中放入一个属性 message:用户名 name
// 已经被占用,请重新选择!在页面通过request.getAttribute("message") 的方式来显示
// 2.2.2 newcustomer.jsp 的表单值可以回显
// value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>"
// 进行回显
request.setAttribute("message", "用户名 " + name + " 已经被占用了,请重新选择!");
// 通过转发的方式来响应 newcustomer.jsp
request.getRequestDispatcher("/newcustomer.jsp").forward(request,
response);
// 2.2.3 结束方法:return
return;
}
// 3.把表单参数封装为一个Customer 对象
Customer customer = new Customer(name, address, phone); // 4.调用 customerDAO 的 save(Customer customer) 方法执行保存
customerDAO.save(customer); // 5.重定向到success.jsp 页面:使用重定向可以避免出现表单的重复提交
response.sendRedirect("success.jsp");
}
}

  4)CustomerDAOXMLImpl.java

 package com.jason.mvcapp.dao.impl;

 import java.util.List;

 import com.jason.mvcapp.dao.CustomerDAO;
import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; public class CustomerDAOXMLImpl implements CustomerDAO { @Override
public List<Customer> getForListWithCriteriaCustomer(
CriteriaCustomer criteriaCustomer) {
System.out.println("CustomerDAOXMLImpl's getForListWithCriteriaCustomer");
return null;
} @Override
public List<Customer> getAll() {
System.out.println("CustomerDAOXMLImpl's getAll");
return null;
} @Override
public void save(Customer coustomer) {
System.out.println("CustomerDAOXMLImpl's save");
} @Override
public Customer get(Integer id) {
System.out.println("CustomerDAOXMLImpl's get");
return null;
} @Override
public void delete(Integer id) {
System.out.println("CustomerDAOXMLImpl's get"); } @Override
public long getCountWithName(String name) {
System.out.println("CustomerDAOXMLImpl's getCountWithName");
return 0;
} @Override
public void update(Customer customer) {
System.out.println("CustomerDAOXMLImpl's update"); } }

  5)CustomerDAOJdbcImpl.java

 package com.jason.mvcapp.dao.impl;

 import java.util.List;

 import com.jason.mvcapp.dao.CustomerDAO;
import com.jason.mvcapp.dao.DAO;
import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; /**
* @author: jason
* @time:2016年5月25日下午3:45:06
* @description:对CustomerDAO 的实现
*/
public class CustomerDAOJdbcImpl extends DAO<Customer> implements CustomerDAO { @Override
public List<Customer> getAll() {
String sql = "SELECT * FROM customers";
return getForList(sql);
} @Override
public void save(Customer customer) {
String sql = "INSERT INTO customers(name, address, phone) VALUES(?,?,? )";
update(sql,customer.getName(),customer.getAddress(),customer.getPhone());
} @Override
public Customer get(Integer id) {
String sql = "SELECT id, name, address, phone FROM customers WHERE id = ?";
return get(sql,id); } @Override
public void delete(Integer id) {
String sql = "DELETE FROM customers WHERE id = ?";
update(sql, id);
} @Override
public long getCountWithName(String name) {
String sql = "SELECT count(id) FROM customers WHERE name = ?";
return getForValue(sql, name);
} @Override
public List<Customer> getForListWithCriteriaCustomer(
CriteriaCustomer criteriaCustomer) {
//sql语句
String sql = "SELECT id,name,address,phone FROM customers WHERE name LIKE ? AND address LIKE ? AND phone LIKE ?";
//调用DAO<T> 中的方法getForList(),并且为占位符设置
return getForList(sql, criteriaCustomer.getName(),criteriaCustomer.getAddress(),criteriaCustomer.getPhone());
} @Override
public void update(Customer customer) {
String sql = "UPDATE customers SET name = ?, address = ?, phone = ? WHERE id = ?";
update(sql, customer.getName(), customer.getAddress(), customer.getPhone(), customer.getId());
} }

  6)switch.properties

 type=jdbc
#type=xml

  7)customer.xml

 <?xml version="1.0" encoding="UTF-8"?>

 <customers>
<customer id ="1001">
<name>tom</name>
<address>beijing</address>
<phone>123156456</phone>
</customer> </customers>

  8)web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>mvc</display-name> <servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.jason.mvcapp.servlet.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> </web-app>

  ⑨)CustomerDAO.java

 package com.jason.mvcapp.dao;

 import java.util.List;

 import com.jsaon.mvcapp.domain.CriteriaCustomer;
import com.jsaon.mvcapp.domain.Customer; /**
* @author: jason
* @time:2016年5月25日下午3:28:00
* @description:
*/ public interface CustomerDAO { //带参数的模糊查询
public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer criteriaCustomer);
//查询所有
public List<Customer> getAll(); //保存操作
public void save(Customer coustomer); //更新前,先查询
public Customer get(Integer id); //删除用户
public void delete(Integer id); //查看与参数相同的名字有多少个记录数
public long getCountWithName(String name); //更新操作
public void update(Customer customer); }

  3.总结:

  1)从代码层次理解面向接口编程的优势

[原创]java WEB学习笔记27:深入理解面向接口编程的更多相关文章

  1. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. [原创]java WEB学习笔记11:HttpServlet(HttpServletRequest HttpServletRsponse) 以及关于 Servlet 小结

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  5. [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. [原创]java WEB学习笔记45:自定义HttpFilter类,理解多个Filter 代码的执行顺序,Filterdemo:禁用浏览器缓存的Filter,字符编码的Filter,检查用户是否登陆过的Filter

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  7. [原创]java WEB学习笔记19:初识MVC 设计模式:查询,删除 练习(理解思想),小结 ,问题

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. [原创]java WEB学习笔记91:Hibernate学习之路-- -HQL 迫切左外连接,左外连接,迫切内连接,内连接,关联级别运行时的检索策略 比较。理论,在于理解

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. [原创]java WEB学习笔记30:Cookie Demo 之显示最近浏览的记录

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

随机推荐

  1. 有道词典for mac不能取词解决方案

    在mac上装了有道词典,发现在Chrome上不能取词,网上也没有搜到合适的解决方案,后来发现解决这个问题很简单,打开有道词典,点击设置, 再点击软件更新,就会发现有chrome取词插件,安装就OK了. ...

  2. oc 跳转控制方法

    1.presentViewController - (void)presentViewController:(UIViewController *)viewControllerToPresent an ...

  3. 匿名函数 invoke

    delegate string MyDele(string str); string MyFun(string str) { return str; } private void Form1_Load ...

  4. 【hadoop之翊】——windows 7使用eclipse下hadoop应用开发环境搭建

    由于一些缘故,这节内容到如今才写.事实上弄hadoop有一段时间了,能够编写一些小程序了,今天来还是来说说环境的搭建.... 说明一下:这篇文章的步骤是接上一篇的hadoop文章的:http://bl ...

  5. Windows安装Redis的php扩展

    Redis是一种常用的非关系型数据库,主要用作数据缓存,数据保存形式为key-value,键值相互映射.它的数据存储跟MySQL不同,它数据存储在内存之中,所以数据读取相对而言很快,用来做高并发非常不 ...

  6. Atitit.远程接口 监控与木马   常用的api 标准化v2 q216

    Atitit.远程接口 监控与木马   常用的api 标准化v2 q216 1. 木马与远程接口 监控的常用的api2 1.1. 文件复制2 1.2. 屏幕定时截图2 1.3. 邮件发送2 1.4.  ...

  7. WAF绕过方法

    1.大小写绕过 这个大家都很熟悉,对于一些太垃圾的WAF效果显著,比如拦截了union,那就使用Union UnIoN等等绕过. 2.简单编码绕过 比如WAF检测关键字,那么我们让他检测不到就可以了. ...

  8. JAVA读取文件夹大小的几种方式

    (一)单线程递归方式 package com.taobao.test; import java.io.File; public class TotalFileSizeSequential { publ ...

  9. jquery将form表单序列化常json

    var formData = {};$.each(form.serializeArray(),function(i, item){ formData[item.name] = item.value;} ...

  10. ViewPage + Fragment 防止Fragment 重复加载问题

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanc ...