一、项目开发通用化

1、将className,url,user、password常用又不变值,定义为常量,编写到一个类(Constants)中

package mybean.util;

public class Constants {
    public static String DriverName="com.microsoft.sqlserver.jdbc.SQLServerDriver";
    public static String url="jdbc:sqlserver://localhost:1433; Database=ebuy";
    public static String uid="sa"; 
    public static String pwd="123456";

//数据库名,用户名,密码,url有所不同
}

2、创建JDBCTool类,编写连接数据库、关闭连接,实现复用性

package mybean.util;
import java.sql.*;
public class JDBCTool {
public static Connection getConnection()
    {
        Connection conn=null;
        
            try {
                Class.forName(Constants.DriverName);
                conn=DriverManager.getConnection(Constants.url,Constants.uid,Constants.pwd);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
 
    
    return conn;
    }
}


拓展:通过编写一个通用的方法,在不修改源程序的情况下,可以获取任何数据库的连接

解决方案:将相关值放入配置文件中,通过修改配置方法实现和具体的数据解耦

(1)在src文件夹下新建文件(file),jdbc.properties

className=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://10.40.43.202:1433;Database=ebuy
user=shopping
password=shopping

(2)mybean.util包下新建JDBCTool类

package mybean.util;
import java.util.*;

import mybean.*;
import java.sql.*;

import java.io.*;;

public class JDBCTool {
    /*
     * 编写 一个通用的方法,在不修改源程序的情况下,可以获取任何数据库的连接
     */
    public Connection getConnection() throws Exception{
        Connection conn=null;
    
        String className=null;
        String url=null;
        String user=null;
        String password=null;
        
        //读取类路径下的jdbc.properties文件输入流
        InputStream in=getClass().getClassLoader().getResourceAsStream("jdbc.properties");
        //创建properties对象
        Properties properties=new Properties();

        //加载in对象输入流
        properties.load(in);

            /加载字符串
        className=properties.getProperty("className");
        url=properties.getProperty("url");
        user=properties.getProperty("user");
        password=properties.getProperty("password");
        
        
        
        
        Properties  info=new Properties();
        info.put("user", user);
        info.put("password",password);
        //方法 1
//        Driver driver=(Driver)Class.forName(className).newInstance();
//        conn=driver.connect(url, info);

        
        //方法2
        Class.forName(className);//加载数据驱动
        conn=DriverManager.getConnection(url,user,password);

       

        return conn;
        
    }
    
}

二、分页设计

分页考虑一下几个问题

(1)每页显示多少条记录pageNum

(2)当前页是哪页currentPage

(3)总共有多少条记录countNumber

(4)总共有多少页countPage,其中countPage=ceil(countNumber/double(pageNum))

分页需要知道的有:

(1)共有几页countPage,当前页currentPage,共有多少条记录countNumber,每页显示几条记录pageNum

(2)需要获得当前页数据库中数据GoodsDAO.list(PageInfo)


1、设计分页Bean--PageInfo.java

package mybean.util;


public class PageInfo {
 
 private int currentPage =1;//当前页  //2
 private int pageNum = 4;//每页数据数     //1
 private int countNumber = 0; //共记录数   3
 private int countPage=1;
 
 public int getPageNum() {
  return pageNum;
 }
 public void setPageNum(int pageNum) {
  this.pageNum = pageNum;
 }
 public int getCurrentPage() {
  return currentPage;
 }


 public void setCurrentPage(String currentPage) {
  int page=1;
   if(null != currentPage)
     {
          page=Integer.parseInt(currentPage);
       }
 

  this.currentPage = page;
 }


 public int getCountNumber() {
  return countNumber;
 }
 public void setCountNumber(int countNumber) {
  this.countNumber = countNumber;
 }
 public void setCountPage()
 {
  this.countPage = (int)java.lang.Math.ceil(this.getCountNumber()/(this.getPageNum()+0.0));
 }
 public int getCountPage()
 {
  return countPage;
 }
}

2、数据库读取相应页的数据GoodsDAO.list(复制原list代码,适当更改)

public LinkedList<Goods> list(PageInfo pageInfo)
{
    LinkedList<Goods> ls=new LinkedList<Goods>();
 Connection conn=null;
 PreparedStatement  stmt=null;
 ResultSet rs=null;
 String url="jdbc:sqlserver://localhost:1433;Database=ebuy";
 String user="shopping";
 String password="shopping";
 String sql="select top (1*?) * from goods where gid not in (select top (1*?) gid from goods)";

 String className="com.microsoft.sqlserver.jdbc.SQLServerDriver";


 try {
  Class.forName(className);
  
 conn=DriverManager.getConnection(url, user, password);
 
 //首先知道数据库中有多少条记录
 String sql1="select count(*) from goods";
 stmt=conn.prepareStatement(sql1);
 rs=stmt.executeQuery();
 if(rs.next()){
  pageInfo.setCountNumber(rs.getInt(1));
 }
 rs.close();
 stmt.close();

 
 //获取制定条数据记录
 stmt=conn.prepareStatement(sql);
 stmt.setInt(1,pageInfo.getPageNum());
 stmt.setInt(2, pageInfo.getPageNum()*(pageInfo.getCurrentPage()-1));
 rs=stmt.executeQuery();
 
 while(rs.next()){
 Goods g=new Goods();
 g.setGid(rs.getInt("gid"));
 g.setName(rs.getString("name"));
 g.setPrice(rs.getFloat("price"));
 g.setNum(rs.getInt("num"));
 ls.add(g);

 }
 
 } catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }

 try {
  if(rs!=null)
   {rs.close();}
  if(stmt!=null)
   {stmt.close();}
  if(conn!=null)
   {conn.close();}
 } catch (SQLException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 
 
 return ls;
}

3、good_view页添加部分代码实现,显示指定页数据

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="mybean.*,mybean.util.*" %>
<%

 // 显示指定页的数据

  String currentPage = request.getParameter("currentPage");
  PageInfo  pageInfo=(PageInfo)request.getAttribute("pageInfo");
  if(pageInfo==null)
   {
    pageInfo=new PageInfo();
  
    request.setAttribute("pageInfo",pageInfo);
   }
 pageInfo.setCurrentPage(currentPage); //设置当前页
 %>

<div style="width:500px;">
<p>商品信息显示</p>
<div style="padding-left:350px;"><a href="good_add.jsp">添加</a></div>
<table width="400" border="1">
  <tr>
    <td>商品ID</td>
    <td>商品名称</td>
    <td>商品价格</td>
    <td>商品数量</td>
   <td>删除</td>
    <td>修改</td>
    <td>详细</td>
  </tr>
<%
GoodsDAO dao=new GoodsDAO();
LinkedList<Goods>gs=dao.list(pageInfo);
for(Goods g:gs)
{
 //out.println(g.getName());
%>


  <tr>
    <td><%=g.getGid()%></td>
    <td><%=g.getName()%></td>
    <td><%=g.getPrice()%></td>
    <td><%=g.getNum()%></td>
    <td><a href="good_delete.jsp?gid=<%=g.getGid()%>">删除</a></td>
    <td><a href="good_update.jsp?gid=<%=g.getGid()%>">修改</a></td>
    <td>详细</td>
  </tr>
 
  <%}
  pageInfo.setCountPage(); //设置总页数
  %>
</table>
<jsp:include page="page.jsp"/>

 <form  id="form1" name="form1"  action="good_view.jsp" method="post" target="_self">
     <input type="hidden" name="currentPage" id="currentPage" value="<%=pageInfo.getCurrentPage()%>">
    
</form></div>

4、page.jsp实现上一页下一页组件

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@page import="mybean.*"%>
<%@page import="mybean.util.*"%>
 <script type="text/javascript">
   function pageChange(currentPage){
       document.getElementById('currentPage').value = currentPage;
           document.form1.submit();   
   }
</script>
<%
PageInfo pageInfo=(PageInfo)request.getAttribute("pageInfo");

if(pageInfo!=null)
{
int countPage=pageInfo.getCountPage();
int upPage=1;
int downPage=countPage;
if(pageInfo.getCurrentPage()!=1)
{
upPage=pageInfo.getCurrentPage()-1;
}
if(pageInfo.getCurrentPage()!=countPage){
downPage=pageInfo.getCurrentPage()+1;

}

%>
<ul style="list-style:none">
<li style="border:1px solid #ccc;width:50px;float:left;margin:5px;" href="#"></a>首页</li>

<li style="border:1px solid #ccc;width:50px;float:left;margin:5px;" οnclick="pageChange(<%=upPage%>);">上一页</li>
<%
for(int i=1;i<=pageInfo.getCountPage();i++)
{
%>

<li style="border:1px solid #ccc;width:20px;float:left;margin:5px;margin-left:2px;margin-right:2px;" οnclick="pageChange(<%=i%>);"><%=i%></li>

<%
}
%>

<li style="border:1px solid #ccc;width:50px;float:left;margin:5px;" οnclick="pageChange(<%=downPage%>);">下一页</li>
<li style="border:1px solid #ccc;width:50px;float:left;margin:5px;" οnclick="pageChange(<%=pageInfo.getCountPage()%>);">尾页</li>

</ul>

<%} %>


5、实现用户信息分页显示

(1)编写UserDAO.list(pageInfo)

public LinkedList<User> list(PageInfo page){
        //page.countRec,page.countPage;
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        String sql1="select count(*) from users";
        String sql2="select top (1*?)* from users where uid not in" +
                "(select top (1*?)uid from users)";
        LinkedList<User>us=new LinkedList<User>();
        try{
            Class.forName(Const.DRIVER);
            conn=DriverManager.getConnection(Const.URL, Const.USER, Const.PASSWORD);
            ps=conn.prepareStatement(sql1);
            rs=ps.executeQuery();
            
            if(rs.next()){
                page.setCountNumber(rs.getInt(1));
            }
            rs.close();
            ps.close();
            
            ps=conn.prepareStatement(sql2);
            ps.setInt(1,page.getPageNum());
            ps.setInt(2,(page.getCurrentPage()-1)*page.getPageNum() );//2页,不显示前十条(2-1)*10
            
                    
            rs=ps.executeQuery();
            while(rs.next()){
                User u=new User();
                u.setUid(rs.getInt("uid"));
                u.setName(rs.getString("name"));
                u.setEmail(rs.getString("email"));
                us.add(u);
            }
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            if(rs!=null)
                {rs.close();}
            if(ps!=null)
                {ps.close();}
            if(conn!=null)
                {conn.close();}
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return us;
    }

(2)user_view.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="mybean.*,mybean.util.*" %>

<div style="width:500px;">
<p>用户信息</p>

<div style="padding-right:150px;float:right;"><a href="good_add.jsp">添加</a></div>
<table width="400" border="1">
  <tr>
    <td>用户ID</td>
    <td>用户名称</td>
    <td>用户邮箱</td>
    <td>删除</td>
    <td>修改</td>
    <td>详细</td>
  </tr>
<%
PageInfo pageInfo=(PageInfo)request.getAttribute("pageInfo");
if(pageInfo==null){
    pageInfo=new PageInfo();
    pageInfo.setPageNum(6);  //1
    request.setAttribute("pageInfo", pageInfo);
}
String currentPage=request.getParameter("currentPage");
pageInfo.setCurrentPage(currentPage);  //2

UserDAO dao=new UserDAO();
LinkedList<User>  us=dao.list(pageInfo); //pageInfo 3和4属性
for(User u:us)
{
    //out.println(g.getName());
%>


  <tr>
    <td><%=u.getUid()%></td>
    <td><%=u.getName()%></td>
    <td><%=u.getEmail()%></td>
    <td><a href="../user/UserSevlet?type=delete&uid=<%=u.getUid()%>">删除</a></td>
    <td><a href="#?uid=<%=u.getUid()%>">修改</a></td>
    <td>详细</td>
  </tr>
 
  <%}
  //pageInfo.setCountPage();
  %>
</table>
<jsp:include page="page.jsp"/>
 <form  id="form1" name="form1"  action="user_view.jsp" method="post" target="_self">
 <input type="hidden" name="currentPage" id="currentPage" value="<%=pageInfo.getCurrentPage()%>">
           
</form>
</div>
效果如下:



三、Md5加密技术使用

1、可以通过上网等方式查找MD5加密代码

package mybean.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {
 public static String MD5Encrypt(String strIn)
 {
  MessageDigest md = null;
  String strOut = null;
  try
  {
   md = MessageDigest.getInstance("MD5"); //可以选中其他的算法如SHA
   byte[] digest = md.digest(strIn.getBytes());
   //返回的是byet[],要转化为String存储比较方便
   strOut = bytetoString(digest);
  }
  catch (NoSuchAlgorithmException nsae)
  {
   nsae.printStackTrace();
  }
  return strOut;
 }
 public static String bytetoString(byte[] digest)
 {
   String str = "";
   String tempStr = "";
   for (int i = 1; i < digest.length; i++)
   {
    tempStr = (Integer.toHexString(digest[i] & 0xff));
    if (tempStr.length() == 1)
    {
     str = str + "0" + tempStr;
    }
    else
    {
     str = str + tempStr;
    }
   }
   return str.toLowerCase();
 }


}

2、编写主函数进行测试(通过网页查找MD5工具测试与自己编写程序结果是否相同)

public  static void main(String args[]){

String password="wxj";

 String pwd = MD5.MD5Encrypt(password);

System.out.println(pwd);

}



3、任务实施:实现用户注册信息加密

(1)用户注册页面设计 /user/register.jsp

<%@ page language="java" import="java.util.*,mybean.User" pageEncoding="UTF-8"%>

<script type="text/javascript">
 function check()
 {
 if(form1.name.value=="")
 {
 alert("请输入用户名!!");
 form1.name.focus();
 return false;
 }
 if(form1.password.value=="")
 {
 alert("请输入密码!!");
 form1.password.focus();
 return false;
 }
 //var val=document.getElementById("email");
 var val=form1.email.value;
 if(val.indexOf('@')<1)
 {
 alert("邮箱格式不对");
 form1.email.focus();
 return false;
 }
 
 return true;
 }
</script>

  <form action="<%=request.getContextPath()%>/user/UserServlet?type=reg" method="post"  submit="return check();">
    <table width="400" border="1">
   <tr>
     <td>用户名</td>
     <td><input type="text" name="name" value="" /></td>
   </tr>
   <tr>
     <td>密码</td>
     <td><input type="password" name="password" value=""  /></td>
   </tr>
    <tr>
     <td>性别</td>
     <td><input name="sex" type="radio"  value="男" checked="ok" />
       男
       <input name="sex" type="radio" value="女" />
       女</td>
   </tr>
 
   <tr>
     <td>邮箱</td>
     <td><input type="text" name="email" value="" /></td>
   </tr>
     <tr>
     <td>电话</td>
     <td><input type="text" name="tel" value="" /></td>
   </tr>
   <tr>
     <td>&nbsp;</td>
     <td><input type="submit" name="button" id="button" value="提交" />
    </td>
   </tr>
 </table>
  </form>
 </body>
</html>

(2)UserServlet的doPost中添加实现用户注册

public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  request.setCharacterEncoding("utf-8");
  String  type=request.getParameter("type");
  if("login".equals(type)){
   
   String name = request.getParameter("name");
   String pwd = request.getParameter("password");
   UserDAO dao=new UserDAO();
   User u=dao.login(name, pwd);
    
   if(u!=null){
    //request.getRequestDispatcher("index.php").forward(request, response);
    
    request.getSession().setAttribute("user",u);
    response.sendRedirect("../index.jsp");
   }else{
    response.sendRedirect("../index.jsp");
   }
  }else if("reg".equals(type)){
    
   UserDAO dao = new UserDAO();
       User u = new User();
       u.setName(request.getParameter("name"));
       String password=request.getParameter("password");
       String pwd = MD5.MD5Encrypt(password);
       u.setPassword(pwd);
      
       u.setAddress(request.getParameter("address"));
       u.setTel(request.getParameter("tel"));
       u.setEmail(request.getParameter("email"));
       u.setSex(request.getParameter("sex"));
       dao.save(u);
       response.sendRedirect("../index.jsp");
        System.out.println("成功,xx!!");
  
     }
  }

(3)登录处理修改

用户输入用户名,密码(password),将用户输入密码md5加密,之后与数据库中数据比较

UserServlet的 doPost添加一条语句,最后代码如下

public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  request.setCharacterEncoding("utf-8");
  String  type=request.getParameter("type");
  if("login".equals(type)){
   
   String name = request.getParameter("name");
   String pwd = request.getParameter("password");
   pwd = MD5.MD5Encrypt(pwd);
   UserDAO dao=new UserDAO();
   User u=dao.login(name, pwd);
    
   if(u!=null){
    //request.getRequestDispatcher("index.php").forward(request, response);
    
    request.getSession().setAttribute("user",u);
    response.sendRedirect("../index.jsp");
   }else{
    response.sendRedirect("../index.jsp");
   }
  }else if("reg".equals(type)){
   System.out.println("xx!!");
       UserDAO dao = new UserDAO();
       User u = new User();
       u.setName(request.getParameter("name"));
       String password=request.getParameter("password");
       System.out.print(password);
       String pwd = MD5.MD5Encrypt(password);
       u.setPassword(pwd);
      
       u.setAddress(request.getParameter("address"));
       u.setTel(request.getParameter("tel"));
       u.setEmail(request.getParameter("email"));
       u.setSex(request.getParameter("sex"));
       dao.save(u);
      
       System.out.println("成功,xx!!");
       response.sendRedirect("../index.jsp");
       
  }

 }

四、验证码登录
  

<script language="javascript" type="text/javascript">
var code ; //在全局 定义验证码
function createCode(){
code = new Array();
var codeLength = 4;//验证码的长度
var checkCode = document.getElementById("checkCode");
checkCode.value = "";

var selectChar = new Array(2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z');

for(var i=0;i<codeLength;i++) {
   var charIndex = Math.floor(Math.random()*32);
   code +=selectChar[charIndex];
}
if(code.length != codeLength){
   createCode();
}
checkCode.value = code;
}

function validate () {
var inputCode = document.getElementById("input1").value.toUpperCase();

if(inputCode.length <=0) {
   alert("请输入验证码!");
   return false;
}
else if(inputCode != code ){
   alert("验证码输入错误!");
   createCode();
   return false;
}
else {
   form_submit();
   return true;
}
}
</script>

</head>
<body onLoad="createCode();">

<form id="login" name="login" action="#" method="post">

        <div class="user">
        <label>用户名:
        <input type="text" name="username" id="username" />
        </label>
      </div>
      <div class="user">
        <label>密 码:
        <input type="password" name="password" id="password" />
        </label>
      </div>
      <div class="chknumber">
        <label>验证码:

        <input type="text" id="input1" />
        <input type="button" id="checkCode" class="code" style="width:60px" onClick="createCode()" />

        <a href="#" onClick="createCode()">看不清楚</a>

     
      </div>