网上书店(jsp+servlet+javabean)
一.  过滤器的使用:
1.     对中文字符的处理:(若采用mssql略简单,mysql需设置为UTF-8,本项目数据库采用gb2312)
a. public class SetCharacterEncoding  implements Filter { //必须实现接口类的所有方法
public SetCharacterEncoding() {  super(); } public void destroy() {     }
   public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)  throws IOException,ServletException{
    request.setCharacterEncoding("gb2312");chain.doFilter(request,response);    } 
public void init(FilterConfig filterConfig) throws ServletException {  } }
b.除在请求与响应处理外,对数据库的操作也进行过滤
url="jdbc:mysql://127.0.0.1:3306/DB?useUnicode=true&characterEncoding=GB2312";
c.也可以采取页面函数进行字符编码转换:
<%! public String convert(String s){ try{
return new String(s.getBytes("ISO-8859-1"),"GB2312"); }
catch(Exception e){return null;} } %>
2.     对用户权限的进行过滤,配置为:<url-pattern>/user/*</url-pattern> /表示项目全路径
public class UserFilter implements Filter {
String PAGE="/bookshop/admin/admin1.jsp" ;  protected FilterConfig filterConfig;
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hreq=(HttpServletRequest)req;
        HttpServletResponse hres=(HttpServletResponse)res;//只有Http才有session
        HttpSession session=hreq.getSession();   String name="";
    try{ name=(String)session.getAttribute("name");
         if(name!=null){chain.doFilter(req, res);}else{hres.sendRedirect(PAGE);}}
    catch(Exception e){ e.printStackTrace();}   }
public void destroy(){this.filterConfig=null;}
    public void init(FilterConfig config) throws ServletException {
      this.filterConfig=config; }}
二.CSS经典控制样式:
.button {BORDER-RIGHT: #9ac3d8 1px solid; BORDER-TOP: #cde7f4 1px solid; FONT-WEIGHT: normal; FONT-SIZE: 12px; BACKGROUND: #bedbea; BORDER-LEFT: #cde7f4 1px solid; COLOR: #0076c9; BORDER-BOTTOM: #9ac3d8 1px solid; FONT-STYLE: normal; FONT-FAMILY: 宋体, Arial, Helvetica, sans-serif; HEIGHT: 18px}
.inputbox { BORDER-RIGHT: #cccccc 1px solid; BORDER-TOP: #cccccc 1px solid; FONT-WEIGHT: normal; FONT-SIZE: 12px; BACKGROUND: #ffffff; BORDER-LEFT: #cccccc 1px solid; COLOR: #666680; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: 宋体, Courier, Helvetica, sans-serif }// <TABLE cellSpacing=2 cellPadding=0 align=center border=0>不同表格无缝
.txt_db { FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #666680; LINE-HEIGHT: 23px; FONT-FAMILY: "宋体", "Courier", "Helvetica", "sans-serif"
.tb_dotted { BORDER-RIGHT: #cccccc 1px dotted; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted }
.top_tb_solid {BORDER-RIGHT: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; WIDTH: 768px; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 25px; BACKGROUND-COLOR: #f2f2f2}
二.  管理员模块:
1.如果没有过滤器可以采用:<% String name=(String)session.getAttribute("name");
try { if(!name.equals("admin")){response.sendRedirect("/project/page.jsp");  } }
   catch(Exception e){out.print("对不起,您不是管理员!");  }%>
2.防止空值出现而使单独页面无法调试:(虽然可以用空判断但是空也可能指向一个内存地址)
<% String n=null; ResultSet  rs=null;
n=request.getParameter("id");    rs=DBBean.executeQuery(sql);
    if(rs!=null && rs.next()){   } %>   <td> <%= rs.getInt("id") %></td>
 
3.用Servlet对JDBC进行封装 action=”/project/servlet?id=”//此处要写满全路径
public class UpdateServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException { try{ String myid=request.getParameter("id");
String sql="update table set title='"+title+"' "+"where id="+myid;
Connection conn=DBContext.getInstance.getConnection();//得到一个连接
Statement stmt=conn.createStatement();   int i=stmt.executeUpdate(sql);
if(i>0){response.sendRedirect("/project/page.jsp");}}
catch(Exception e){ e.printStackTrace();}   }
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ doGet(req,res);   }  }
4.实现表单自动提交功能: <script language=javascript>
setInterval("document.表单名.submit()",10000000)</script>  
三.登陆模块:
1.     javasript对登陆控制
<form name="form1" method="post" action="/project/servlet" onSubmit="return check()">
<SCRIPT language=javascript>
function check(){
var emailreg = /^[_a-z0-9]+@([_a-z0-9]+\.)+[a-z0-9]{2,3}$/;var pwdreg = /[a-z0-9]$/;
if ((document.form1.name.value)=="")
{window.alert ('用户名不能为空');document.form1.name.focus();return false;}
else if ((document.form1.name.value.length)<3){window.alert ('长度不能小于3 ');
document.form1.name.focus();return false; }
else if (form1.password.value!=form1.password1.value)
{window.alert ('两次输入的密码不一致');document.form1.pwd2.focus();return false;}
else if ((!emailreg.test(document.form1.email.value))&&(document.form1.email.value!=''))
{window.alert ('Email的格式不正确');document.form1.email.focus();return false;}
else  return true; } </SCRIPT>
2.注册时间类型的处理:因为sql.Date( )必须有Long Date参数,a.如果是在sql插入系统时间则
java.sql.Date date=new java.sql.Date(new java.util.Date().getTime());
3.忽视大小写: if(name.equalsIgnoreCase("admin")&&paw.equalsIgnoreCase("admin"))
4.用户判断: <%  String sql=" select count(*)  from table where name like '"+name+"'  "; 
  ResultSet rs=DBBean.executeQuery(sql);   rs.next( );
  int i=rs.getInt(1); if(i!=0)  { session.setAttribute("name",name); }    %>
5.为防止<%=param%>初次调用显示为null: 
<% String name=""; if(!session.isNew()){name=(String)session.getAttribute("name");
                    if(name==null)  name="";}   %>
6.用include根据用户显示界面: 
<% String name1=null;name1=(String)session.getAttribute("name"); if(name1!=null){ %>
 <form  name="form1" class="inputbox" > 要显示的内容:</form>   
  <% } if(name1= =null) {  %> 
<form action="forward.jsp" method="post" name="form1" class="inputbox"></form><% } %>
四.查询模块: <%  ResultSet rs=null; String idh=request.getParameter("text"); 
String var=request.getParameter("select");   if(var.equals("按图书编号查询"))
       {  rs=DDBean.executeQuery("select * from book where id like '%"+idh+"%'"); }
else if(var.equals("按图书书名查询"))
       { rs=DDBean.executeQuery("select * from book where title  like '%"+idh+"%'"); }
if(rs!=null) { while(rs.next()){  %> 显示内容:   <% }  }   %>
五.购物车:页面用到:DBBean,ShoppingCart,BookDB,BookDetails四个javaBean
1.添加,删除和清空货物:
<% if(request.getParameter("Add")!=null){
        int id=Integer.parseInt(request.getParameter("Add"));//把得到的参数转换
        BookDetails book=bookDB.getBookDetails(id);  cart.add(id,book);  }
   else if(request.getParameter("Remove")!=null){
        int id=Integer.parseInt(request.getParameter("Remove")); cart.remove(id); }
   else if(request.getParameter("Clear")!=null){  cart.clear();}  %>
备注:若cart.add中的id是String类型:cart.add(new Integer(id).toString(),book);
2.显示购物车书目总数:您的购物车内有<%=cart.getNumberOfItems()%> 本书
   显示购物车书目总价:总额;<%=cart.getTotal()%> 元
3.迭代循环显示出每本书:
<% Iterator i=cart.getItems().iterator();   while(i.hasNext()){
   ShoppingCartItem item=(ShoppingCartItem)i.next();
   BookDetails book=(BookDetails)item.getItem();  %>
<tr>
<td><a href="showcart.jsp?Add=<%=book.getId()%>">添加</a> <%=item.getQuantity()%>/>
<td><a href="cartbook.jsp?id=<%=book.getId()%>"><%=book.getTitle()%></a></td>
<td align="center"><%=book.getPrice()%></td>
<td><a href="showcart.jsp?Remove=<%=book.getId()%>">删除</a></td>
</tr> <% } %>   <p><a href="showcart.jsp?Clear=clear">清空购物车</a></p>
4.对库存的操作,可在显示购物车的页面显示<%=saleAmount%>
  购物车对库存的操作(付帐页面): <& bookDB.buyBooks(cart);%>
5.得到超链接当前的路径:<%=request.getContextPath()%>/page.jsp
 
    
        
            |  |  |  |  | 
        
            |  | 
                
                    
                        | 
                        BookDetails.java(书的详细信息): public class BookDetails { private int  id=0; private String title=null; private String  name=null; private float price=0; private String description=null; private String saleAmount=null; public BookDetails( ){   } public BookDetails(int id, String title, String name, float price, String description,String  saleAmount) getter/setter( ){ } //有参构造方法供BookDB插入书籍 |  |  | 
                
                    
                        | 
                        ShoppingCartItem.java(将书封装成一个类整体): public class ShoppingCartItem {     Object item;    int quantity; public ShoppingCartItem(Object anItem) {     item = anItem;  quantity = 1;   } //有参构造方法ShoppingCart调用封装书成类 public void incrementQuantity() { quantity++; } public void decrementQuantity() { quantity--; }   public Object getItem( ) { return item;   } public int getQuantity( ) { return quantity; }} //这两个getter供BookDB和ShoppingCart调用 |  | 
    
 
 
 
 
 
    
        
            | 
            BookDB.java是数据库与购物车页面之间的纽带: public class BookDB {       public BookDetails getBookDetails(int id)throws Exception{Connection conn=null;//得到具体书     PreparedStatement prepStmt=null;   ResultSet rs=null; try{conn=DBContext.getInstance.getConnection();            String selectStatement="select * from book where id=?"; prepStmt=conn.prepareStatement(selectStatement); prepStmt.setInt(1,id);      rs=prepStmt.executeQuery(); if(rs.next()){ BookDetails bd=new BookDetails(rs.getInt(1),rs.getString(2),rs.getString(3), rs.getFloat(4),rs.getString(5), rs.getString(6)); prepStmt.close(); return bd;    }else {return null;}  } finally{rs.close(); conn.close(); prepStmt.close(); }  }   public void buyBooks(ShoppingCart cart)throws Exception{Connection conn=null;//对库存的操作         Collection items=cart.getItems();   Iterator i=items.iterator(); try{   conn=DBContext.getInstance.getConnection(); conn.setAutoCommit(false);    while(i.hasNext()){ ShoppingCartItem sci=(ShoppingCartItem)i.next();     BookDetails bd=(BookDetails)sci.getItem(); int id=bd.getId();     int quantity=sci.getQuantity(); buyBook(id,quantity,conn);} conn.commit();conn.setAutoCommit(true);} catch(Exception ex){conn.rollback();throw ex;} finally{conn.close();   }   }   public void buyBook(int id,int quantity,Connection conn)throws Exception{//调用id和购买数量 PreparedStatement prepStmt=null;ResultSet rs=null; try{ String selectStatement="select * from book where id=?";         prepStmt=conn.prepareStatement(selectStatement); prepStmt.setInt(1,id);          rs=prepStmt.executeQuery(); if(rs.next()){ prepStmt.close();         String updateStatement="update book set saleAmount=saleAmount-?where id=? ";     prepStmt=conn.prepareStatement(updateStatement);prepStmt.setInt(1, quantity);//第一个?     prepStmt.setInt(2, id); prepStmt.executeUpdate();  prepStmt.close(); }  } finally{   rs.close();prepStmt.close();        }   }   } | 
    
 
    
        
            | 
            ShoppingCart.java(购物车的实现功能): public class ShoppingCart{ HashMap items=null; int numberOfItems=0;//调用多个Item只能用散列表 public ShoppingCart() { items = new HashMap();  }//构造方法实例化一个散列表  public synchronized void add(int id, BookDetails book) {   if(items.containsKey(id)) {    ShoppingCartItem scitem = (ShoppingCartItem) items.get(id);//调用散列表的get方法取出对象    scitem.incrementQuantity();  } else { ShoppingCartItem newItem =new ShoppingCartItem(book);  items.put(id,newItem);}    numberOfItems++;  }//如果书存在了单种书+1,如果书不存在根据书的id存放在散列表里面 public synchronized void remove(int id) {    if(items.containsKey(id)) {    ShoppingCartItem scitem = (ShoppingCartItem) items.get(id); scitem.decrementQuantity();    if(scitem.getQuantity() <= 0)items.remove(id);  numberOfItems--; }  } protected void finalize( ) throws Throwable { items.clear();  }//用于释放内存 public synchronized void clear() {items.clear(); numberOfItems = 0; } //getter方法: public synchronized Collection getItems( ) {return items.values(); }//values方法返回集合迭代 public synchronized int getNumberOfItems( ) { return numberOfItems;  }  public synchronized double getTotal( ) {    double amount = 0.0;     for(Iterator i = getItems().iterator(); i.hasNext(); ) {     ShoppingCartItem item = (ShoppingCartItem) i.next();//购物车的集合里面迭代Item书种的类     BookDetails bookDetails = (BookDetails) item.getItem();//每个Item又调用具体书目的信息     amount += item.getQuantity() * bookDetails.getPrice();    } return roundOff(amount); }   private double roundOff(double x) {long val = Math.round(x*100); return val/100.0;  } } |