create database onlinemall; use onlinemall; CREATE TABLE `user` ( `uid` varchar(100) NOT NULL, `username` varchar(20) DEFAULT NULL, `password` varchar(20) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `email` varchar(30) DEFAULT NULL, `telephone` varchar(20) DEFAULT NULL, `birthday` date DEFAULT NULL, `sex` varchar(10) DEFAULT NULL, `state` int(11) DEFAULT NULL, `code` varchar(100) DEFAULT NULL, PRIMARY KEY (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
com.web.servlet com.web.filter com.iservice com.service.impl com.dao com.dao.impl com.bean com.utils com.constant
package com.web.servlet; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 为了提高代码的复用性,我们写了这个基类, * * @author LuoJoy * */ public class BaseServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 使用反射技术获取方法,并调用方法 // 获取隐藏域传过来的method String methodName = request.getParameter("method"); // 获取字节码文件对象 Class<? extends BaseServlet> clazz = this.getClass(); try { Method method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); String path = (String) method.invoke(this, request, response); // 不等于null时说明都是需要执行请求转发,因为如果时请求重定向,那么就让它返回空,这样就不会执行下面的代码,而是执行原来的方法 if (path != null) { request.getRequestDispatcher(path).forward(request, response); } } catch (Exception e) { e.printStackTrace(); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.web.filter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; /** * 统一编码 * @author Administrator * */ public class EncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //1.强转 HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response=(HttpServletResponse) resp; //2.放行 chain.doFilter(new MyRequest(request), response); } @Override public void destroy() { // TODO Auto-generated method stub } } class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; private boolean flag=true; public MyRequest(HttpServletRequest request) { super(request); this.request=request; } @Override public String getParameter(String name) { if(name==null || name.trim().length()==0){ return null; } String[] values = getParameterValues(name); if(values==null || values.length==0){ return null; } return values[0]; } @Override /** * hobby=[eat,drink] */ public String[] getParameterValues(String name) { if(name==null || name.trim().length()==0){ return null; } Map<String, String[]> map = getParameterMap(); if(map==null || map.size()==0){ return null; } return map.get(name); } @Override /** * map{ username=[tom],password=[123],hobby=[eat,drink]} */ public Map<String,String[]> getParameterMap() { /** * 首先判断请求方式 * 若为post request.setchar...(utf-8) * 若为get 将map中的值遍历编码就可以了 */ String method = request.getMethod(); if("post".equalsIgnoreCase(method)){ try { request.setCharacterEncoding("utf-8"); return request.getParameterMap(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if("get".equalsIgnoreCase(method)){ Map<String,String[]> map = request.getParameterMap(); if(flag){ for (String key:map.keySet()) { String[] arr = map.get(key); //继续遍历数组 for(int i=0;i<arr.length;i++){ //编码 try { arr[i]=new String(arr[i].getBytes("iso8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } flag=false; } //需要遍历map 修改value的每一个数据的编码 return map; } return super.getParameterMap(); } }
/**
* 1 首先什么是面向接口编程?
*
* 面向接口编程就是先把客户的业务逻辑线提取出来,作为接口,业务具体实现通过该接口的实现类来完成。
* 当客户需求变化时,只需编写该业务逻辑的新的实现类,通过更改配置文件(例如Spring框架)中该接口
* 的实现类就可以完成需求,不需要改写现有代码,减少对系统的影响
*
* 面向接口编程的优点?
* 1 降低程序的耦合性。其能够最大限度的解耦,所谓解耦既是解耦合的意思,它和耦合相对。耦合就是联系
* ,耦合越强,联系越紧密。在程序中紧密的联系并不是一件好的事情,因为两种事物之间联系越紧密,你更换
* 其中之一的难度就越大,扩展功能和debug的难度也就越大。
* 2 易于程序的扩展;
* 3 有利于程序的维护
*
* 接口编程在设计模式中的体现:开闭原则
* 其遵循的思想是:对扩展开放,对修改关闭。其恰恰就是遵循的是使用接口来实现。在使用面向接口的编程过程
* 中,将具体逻辑与实现分开,减少了各个类之间的相互依赖,当各个类变化时,不需要对已经编写的系统进行
* 改动,添加新的实现类就可以了,不在担心新改动的类对系统的其他模块造成影响。
一,案例需求
在register.jsp上填写用户的信息,点击保存,将用户信息保存到数据库中. 发送激活邮件给注册的用户.
-
修改注册的超链接,跳转到register.jsp
-
在注册页面,修改表单属性 ,提交到UserServlet里面
<form action="/OnlineMall/user">
<input type="hideen" name="method" value="regist"/>
....
</form> -
创建 UserServlet继承BaseServlet,在UserServlet里面创建regist()方法
-
在regist()方法里面
获得请求参数,封装成user对象
调用业务
分发转向
/** * 用于处理用户注册业务的方法 * * @param request * @param response */ public String regist(HttpServletRequest request, HttpServletResponse response) { // 接受请求参数 Map<String, String[]> map = request.getParameterMap(); // 创建user对象 User user = new User(); // 使用BeanUtil工具类把请求参数封装到user对象上 try { BeanUtils.populate(user, map); // 还有,uid,state,code 未封装 user.setUid(UUIDUtils.getId());// 封装uid user.setState(Constants.activation); user.setCode(UUIDUtils.getId());// 封装code } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } Boolean flag = false; // 调用业务层的方法完成用户注册 try { IUserService service = (IUserService) ContextFactory.getInstance("user_service"); flag = service.regist(user); } catch (Exception e) { e.printStackTrace(); } if (flag) { // 注册成功,跳转到登陆页面 request.setAttribute("msg", "恭喜您!注册成功,请前往邮箱激活账户"); } else { // 注册失败 request.setAttribute("msg", "注册失败,请重新注册!"); } return "jsp/msg.jsp"; }
5.1调用dao操作数据库
5.2 发送激活的邮件
public interface IUserService { //用户注册方法 public Boolean regist(User user); //用户激活账户 public Boolean doCode(String code); //用户登录 public User doLogin(String usename, String password); }
实现类
package com.service.impl; import org.dom4j.DocumentException; import com.bean.User; import com.dao.intf.IUserDao; import com.factory.ContextFactory; import com.service.intf.IUserService; import com.utils.MailUtils; import com.utils.TransactionManager; public class UserServiceImpl implements IUserService { @Override public Boolean regist(User user) { Boolean falg = false; try { // 开启事务 TransactionManager.startTransaction(); IUserDao dao = (IUserDao) ContextFactory.getInstance("user_dao"); dao.regist(user); // 向用户发送激活邮件 MailUtils.sendMail(user.getEmail(), "尊敬的:" + user.getName() + "欢迎注册古代商城,请点击下面的链接进行激活<a href='localhost:8080/OnlineMall/user?method=active&code=" + user.getCode() + "'>用户激活</a>", "用户账户激活"); // 提交事务 TransactionManager.commit(); falg = true; } catch (Exception e) { e.printStackTrace(); // 如果出现异常回滚 try { TransactionManager.rollback(); } catch (Exception e1) { e1.printStackTrace(); } } try { TransactionManager.close(); } catch (Exception e) { e.printStackTrace(); } return falg; } /** * 激活用户账户的业务逻辑操作 */ @Override public Boolean doCode(String code) { Boolean flag = false; // 调用dao曾的方法校验激活码 IUserDao dao = null; try { dao = (IUserDao) ContextFactory.getInstance("user_dao"); dao.updateCode(code); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } @Override public User doLogin(String usename, String password) { // 调用Dao的方法登陆 IUserDao dao = null; User user = null; try { dao = (IUserDao) ContextFactory.getInstance("user_dao"); user = dao.doLogin(usename, password); } catch (Exception e) { e.printStackTrace(); } return user; } }
5.创建UserDao数据库访问层,定义一个方法保存用户
-
package com.dao.intf; import java.sql.SQLException; import com.bean.User; public interface IUserDao { public void regist(User user) throws Exception; public void updateCode(String code) throws SQLException; public User doLogin(String usename, String password) throws SQLException; }
package com.dao.impl; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import com.bean.User; import com.constant.Constants; import com.dao.intf.IUserDao; import com.utils.C3P0Util; import com.utils.TransactionManager; public class UserDaoImpl implements IUserDao { /** * 用户注册的方法 */ @Override public void regist(User u) throws Exception { QueryRunner runner = new QueryRunner(); String sql = "insert into user values(?,?,?,?,?,?,?,?,?,?);"; runner.update(TransactionManager.getConnectionFromThreadLocal(), sql, u.getUid(), u.getUsername(), u.getPassword(), u.getName(), u.getEmail(), u.getTelephone(), u.getBirthday(), u.getSex(), u.getState(), u.getCode()); } /** * 激活账户 修改用户账户状态为已激活 把code码清空 * * @throws SQLException */ @Override public void updateCode(String code) throws SQLException { QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); String sql = "update user set state=? , code=? where code=?"; runner.update(sql, Constants.activated, null, code); } /** * 用户登录方法 */ @Override public User doLogin(String usename, String password) throws SQLException { QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); String sql = "select * from user where username=? and password=?"; User user = runner.query(sql, new BeanHandler<>(User.class), usename, password); return user; } }