Java Web新手小项目及源码

[html] view plain copy
  1. <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">这是javaweb的期末作业,本人大三。在这里和大家分享,有不足之处也希望大家指出来。</span>  

项目比较简单,主要供新手小白参考,大牛请轻喷~

实现的主要功能有:JSP连接数据库、MD5加密、验证码验证、AJAX、文件上传下载、session登录验证、等


先来几张成果图:

Java Web新手小项目及源码Java Web新手小项目及源码

Java Web新手小项目及源码Java Web新手小项目及源码

Java Web新手小项目及源码

Java Web新手小项目及源码

首页的图是盗用teambition的,样式也是仿照它写的,不要在意这些。。。



首先写登录页login.jsp

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <html>  
  3.     <head>  
  4.         <title>WormJam-登录</title>  
  5.         <link rel="stylesheet" href="css/style.css" type="text/css">  
  6.     </head>  
  7.     <body>  
  8.         <div class="loginHeader">  
  9.             <div class="title">  
  10.                 <center><span>WormJam</span></center>  
  11.                 <center><h3>秀出你的源代码</h3></center>  
  12.             </div>  
  13.         </div>          
  14.         <div class="form">  
  15.             <form method="post" name="loginForm">  
  16.                 账号:<input type="text" name="account" onInput="accountChange()">  
  17.                 <span id="accountText"> </span><span id="loginInfo"></span><br><br>  
  18.                 密码:<input type="password" name="password" onInput="passwordChange()">  
  19.                 <span id="passwordText"> </span><br><br>     
  20.                 验证码:<input type="text" name="code" size="10" onInput="validate()">  
  21.                 <img name="imgValidate" onclick="refresh()" border=0 src="validate.jsp"></img>  
  22.                 <span id="codeText" name="codeText" style="color:green"> </span><br><br>     
  23.                 <input type="button" value="登录" onclick="validateSubmit()">  
  24.                 <a href="register.jsp">注册</a>  
  25.             </form>  
  26.         </div>  
  27.         <script>  
  28.             //验证账号密码格式  
  29.             function accountChange(){  
  30.                 var str = loginForm.account.value;  
  31.                 var reg = /[a-zA-Z0-9]{6,16}/;  
  32.                 if(reg.test(str)){  
  33.                     accountText.innerHTML = "√";  
  34.                     accountText.style.color = "green";  
  35.                 }  
  36.                 else{  
  37.                     accountText.innerHTML = "账号为6至16位数字或字母!";  
  38.                     accountText.style.color = "red";  
  39.                 }  
  40.             }  
  41.             function passwordChange(){  
  42.                 var str = loginForm.password.value;  
  43.                 var reg = /^[x00-x7f]+$/;  
  44.                 if(reg.test(str) && str.length>5 && str.length<17){  
  45.                     passwordText.innerHTML = "√";  
  46.                     passwordText.style.color = "green";  
  47.                 }else{  
  48.                     passwordText.innerHTML = "密码必须是6至16位!";  
  49.                     passwordText.style.color = "red";  
  50.                 }  
  51.             }  
  52.             //验证码刷新  
  53.             function refresh(){  
  54.                 //加入随机参数防止调用浏览器缓存  
  55.                 loginForm.imgValidate.src = "validate.jsp" + "?id=" + Math.random();  
  56.             }  
  57.             //表单提交验证  
  58.             function validateSubmit(){  
  59.                 if(accountText.innerHTML=="√" && passwordText.innerHTML == "√" && codeText.innerHTML == "√"){  
  60.                     var account = loginForm.account.value;  
  61.                     var password = loginForm.password.value;  
  62.                     var xmlHttp = new XMLHttpRequest();  
  63.                     var url = "LoginServlet?account=" + account + "&password=" + password;  
  64.                     xmlHttp.open("POST",url,true);  
  65.                     xmlHttp.onreadystatechange = function(){  
  66.                         if(xmlHttp.readyState == 4){  
  67.                             loginInfo.innerHTML = xmlHttp.responseText;  
  68.                         }else{  
  69.                             loginInfo.innerHTML = "正在验证密码……";  
  70.                         }  
  71.                 }  
  72.                 xmlHttp.send();  
  73.                 }else{  
  74.                     return false;  
  75.                 }  
  76.             }             
  77.             //AJAX  
  78.             function validate(){  
  79.                 var code = loginForm.code.value;  
  80.                 var xmlHttp = new XMLHttpRequest();  
  81.                 var url = "ValidateServlet?code=" + code;  
  82.                 xmlHttp.open("POST",url,true);  
  83.                 xmlHttp.onreadystatechange = function(){  
  84.                     if(xmlHttp.readyState == 4){  
  85.                         codeText.innerHTML = xmlHttp.responseText;  
  86.                     }else{  
  87.                         codeText.innerHTML = "正在验证……";  
  88.                     }  
  89.                 }  
  90.                 xmlHttp.send();  
  91.             }  
  92.         </script>  
  93.     </body>  
  94. </html>  

登录的表单里先不看验证码,为了限制账号及密码 的格式为6至16位的数字或字母,用input里的onInput事件,当账号或密码框中的值发生改变时即调用accountChange()或passwordChange()函数进行输入格式的验证。accountChange()中的正则表达式/[a-zA-Z0-9]{6,16}/;表示6至16位的字母或数字,passwordChange()中的/^[x00-x7f]+$/表示键盘上能够输入的符号。

再看验证码。我是采用了书上的validate.jsp页面生成验证码:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <%@ page import="java.awt.*" import="java.awt.image.BufferedImage" import="javax.imageio.ImageIO" %>  
  3. <html>  
  4. <body>  
  5. <%  
  6.     response.setHeader("Cache-Control", "no-cache");  
  7.     //在内存中创建图像  
  8.     int width = 60,height = 20;  
  9.     BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);  
  10.     //获取画笔  
  11.     Graphics g = image.getGraphics();  
  12.     //设置背景色  
  13.     g.setColor(new Color(200,200,200));  
  14.     g.fillRect(0,0,width,height);  
  15.     //随机产生验证码  
  16.     Random rnd = new Random();  
  17.     int randNum = rnd.nextInt(8999) + 1000;  
  18.     String randStr = String.valueOf(randNum);  
  19.     //将验证码存入session  
  20.     session.setAttribute("randStr",randStr);  
  21.     //将验证码显示在图像中  
  22.     g.setColor(Color.black);  
  23.     g.setFont(new Font("",Font.PLAIN,20));  
  24.     g.drawString(randStr,10,17);  
  25.     //随机产生100个随机点  
  26.     for(int i=0;i<100;i++){  
  27.         int x = rnd.nextInt(width);  
  28.         int y = rnd.nextInt(height);  
  29.         g.drawOval(x,y,1,1);  
  30.     }  
  31.     //输出图像到页面  
  32.     ImageIO.write(image,"JPEG", response.getOutputStream());  
  33.     out.clear();  
  34.     out = pageContext.pushBody();  
  35. %>  
  36. </body>  
  37. </html>  

这段代码生成一个验证码并放在图片中显示,然后login.jsp的登录表单中用img标签把这个验证码图片加载进来。

然后写个ValidateServlet对输入的验证码进行验证:

[java] view plain copy
  1. package servlets;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.*;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11. import javax.servlet.http.HttpSession;  
  12.   
  13. public class ValidateServlet extends HttpServlet {  //对验证码验证  
  14.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  15.             throws ServletException, IOException {  
  16.         //得到提交的验证码  
  17.         String code = request.getParameter("code");  
  18.         //获取session中的验证码  
  19.         HttpSession session = request.getSession();  
  20.         String randStr = (String)session.getAttribute("randStr");  
  21.         //response.setCharacterEncoding("utf-8");  
  22.         PrintWriter out = response.getWriter();  
  23.         if(!code.equals(randStr)){  
  24.             out.println("");  
  25.         }  
  26.         else{  
  27.             out.print("√");  
  28.         }  
  29.     }  
  30. }  

当输入的验证码正确时输出"√",错误时输出空格(无显示),顺便说一句,login.jsp里的validateSubmit()可以看到,我的登录表单是通过判定输出的文本来提交的,即如果账号密码和验证码后面的文本输出不全是"√"的话就无法提交表单。

现在的问题是,在servlet中输出的话,浏览器会新打开一个页面来显示验证码验证的结果,所以要用到AJAX把输出显示在登录页验证码图片的后面,login.jsp里的validate()就使用了AJAX,使验证码验证的结果显示在id为codeText的span标签里,并传一个名为code值为你输入的验证码的参数给ValidateServlet。验证正确时就可以提交给LoginServlet进行密码的验证了。

在这之前先写注册页面register.jsp:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <html>  
  3.     <head>  
  4.         <title>WormJam-注册</title>  
  5.         <link rel="stylesheet" href="css/style.css" type="text/css">  
  6.     </head>  
  7.     <body>  
  8.         <div class="loginHeader">  
  9.             <div class="title">  
  10.                 <center><span>WormJam</span></center>  
  11.                 <center><h3>秀出你的源代码</h3></center>  
  12.             </div>  
  13.         </div>      
  14.         <div class="form">  
  15.             <form method="post" name="registerForm">  
  16.                 输入账号:<input type="text" name="account" onInput="accountChange()"><br>  
  17.                 <span id="accountText"></span><br>  
  18.                 输入密码:<input type="password" name="password1" onInput="password1Change()"><br>  
  19.                 <span id="passwordText1"></span><br>  
  20.                 确认密码: <input type="password" name="password2" onInput="password2Change()"><br>  
  21.                 <span id="passwordText2"></span><br>  
  22.                 <span id="info"></span><br>  
  23.                 <input type="button" value="注册" onclick="formSubmit()">  
  24.                 <a href="login.jsp">返回登录</a>  
  25.             </form>  
  26.         </div>  
  27.         <script>  
  28.             function accountChange(){  
  29.                 var str = registerForm.account.value;  
  30.                 var reg = /[a-zA-Z0-9]{6,16}/;  
  31.                 if(reg.test(str)){  
  32.                     accountText.innerHTML = "√";  
  33.                     accountText.style.color = "green";  
  34.                 }  
  35.                 else{  
  36.                     accountText.innerHTML = "账号为6至16位数字或字母!";  
  37.                     accountText.style.color = "red";  
  38.                 }  
  39.             }  
  40.             function password1Change(){  
  41.                 var str = registerForm.password1.value;  
  42.                 var reg = /^[x00-x7f]+$/;  
  43.                 if(reg.test(str) && str.length>5 && str.length<17){  
  44.                     passwordText1.innerHTML = "√";  
  45.                     passwordText1.style.color = "green";  
  46.                 }else{  
  47.                     passwordText1.innerHTML = "密码必须是6至16位!";  
  48.                     passwordText1.style.color = "red";  
  49.                 }  
  50.             }  
  51.             function password2Change(){  
  52.                 var str1 = registerForm.password1.value;  
  53.                 var str2 = registerForm.password2.value;  
  54.                 if(str1 == str2){  
  55.                     passwordText2.innerHTML = "√";  
  56.                     passwordText2.style.color = "green";  
  57.                 }else{  
  58.                     passwordText2.innerHTML = "两次密码不一致";  
  59.                     passwordText2.style.color = "red";  
  60.                 }  
  61.             }  
  62.             //表单验证  
  63.             function formSubmit(){  
  64.                 if(accountText.innerHTML=="√" && passwordText1.innerHTML=="√" && passwordText2.innerHTML=="√"){  
  65.                     registerSubmit();  
  66.                 }else{  
  67.                     return false;  
  68.                 }  
  69.             }  
  70.             //AJAX  
  71.             function registerSubmit(){  
  72.                 var account = registerForm.account.value;  
  73.                 var password = registerForm.password1.value;  
  74.                 var xmlHttp = new XMLHttpRequest();  
  75.                 var url = "RegisterServlet?account=" + account + "&password=" + password;  
  76.                 xmlHttp.open("POST",url,true);  
  77.                 xmlHttp.onreadystatechange = function(){  
  78.                     if(xmlHttp.readyState == 4){  
  79.                         info.innerHTML = xmlHttp.responseText;  
  80.                     }else{  
  81.                         info.innerHTML = "正在注册……";  
  82.                     }  
  83.                 }  
  84.                 xmlHttp.send();  
  85.             }  
  86.         </script>  
  87.     </body>  
  88. </html>  

表单方面包括格式验证、AJAX都和登录页面同理,提交给RegisterServlet注册,现在就要开始连接数据库操作了。JSP连接数据库的一些配置我就不赘述了。

数据库脚本:

[sql] view plain copy
  1. create table ACCOUNTS(  
  2.     ACNAME varchar(16) not null,  
  3.     PASSWD varchar(16) not null  
  4. );  

为了方便就写了这两列,账号名和密码,16位不为空。然后数据库我是采用DAO设计模式。

先是VO类Account.java:

[java] view plain copy
  1. package VO;  
  2.   
  3. public class Account {  
  4.     private String account;                 //定义账户  
  5.     private String password;                //定义密码  
  6.     public String getAccount(){  
  7.         return account;  
  8.     }  
  9.     public void setAccount(String account){  
  10.         this.account = account;  
  11.     }  
  12.     public String getPassword(){  
  13.         return password;  
  14.     }  
  15.     public void setPassword(String password){  
  16.         this.password = password;  
  17.     }  
  18. }  

分别定义了get和set方法。

然后是数据库连接类DatabaseConnection.java:

[java] view plain copy
  1. package dbc;  
  2.   
  3. import java.sql.*;  
  4.   
  5. public class DatabaseConnection {  
  6.     private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ;   
  7.     private static final String DBURL = "jdbc:mysql://localhost:3306/wormjam" ;  
  8.     private static final String DBUSER = "root" ;  
  9.     private static final String DBPASSWORD = "你的密码" ;  
  10.     private Connection conn ;  
  11.     public DatabaseConnection() throws Exception {              //在构造方法中进行数据库连接  
  12.         Class.forName(DBDRIVER) ;                               //加载驱动程序  
  13.         this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;  
  14.     }  
  15.     public Connection getConnection(){                          //取得数据库连接  
  16.         return this.conn ;  
  17.     }  
  18.     public void close() throws Exception {                      //关闭数据库  
  19.         if(this.conn != null){  
  20.             try{  
  21.                 this.conn.close() ;  
  22.             }catch(Exception e){  
  23.                 throw e ;  
  24.             }  
  25.         }  
  26.     }  
  27. }  

然后定义DAO操作标准IAccountDAO.java:

[java] view plain copy
  1. package DAO ;  
  2.   
  3. import java.util.* ;  
  4. import VO.Account;  
  5.   
  6. public interface IAccountDAO {          //定义DAO操作  
  7.     public boolean doCreate(Account account) throws Exception ;  
  8.     public String findByAccount(String acname) throws Exception ;  
  9. }  


定义了两个操作:创建和寻找。创建用来注册用户,而寻找用来比对密码是否正确。


接着是真实主题实现类AccountDAOImpl.java:

[java] view plain copy
  1. package DAO ;  
  2.   
  3. import java.util.* ;  
  4. import java.sql.* ;  
  5. import DAO.IAccountDAO;   
  6. import VO.Account;  
  7.   
  8. public class AccountDAOImpl implements IAccountDAO {  
  9.     private Connection conn = null ;                        //数据库连接对象  
  10.     private PreparedStatement pstmt = null ;                //数据库操作对象  
  11.     public AccountDAOImpl(Connection conn){                 //通过构造方法取得数据库连接  
  12.         this.conn = conn ;  
  13.     }  
  14.     public boolean doCreate(Account account) throws Exception{ //添加账户  
  15.         boolean flag = false ;                              //定义标志位  
  16.         String sql = "INSERT INTO ACCOUNTS(ACNAME,PASSWD) VALUES (?,?)" ;  
  17.         this.pstmt = this.conn.prepareStatement(sql) ;      //实例化PrepareStatement对象  
  18.         this.pstmt.setString(1,account.getAccount()) ;  
  19.         this.pstmt.setString(2,account.getPassword()) ;  
  20.         if(this.pstmt.executeUpdate() > 0){                  //如果有更新操作  
  21.             flag = true ;  
  22.         }  
  23.         this.pstmt.close() ;  
  24.         return flag ;  
  25.     }  
  26.     public String findByAccount(String acname) throws Exception{//按账号查找密码  
  27.         String password = null;  
  28.         String sql = "SELECT PASSWD FROM ACCOUNTS WHERE ACNAME=?" ;  
  29.         this.pstmt = this.conn.prepareStatement(sql) ;  
  30.         this.pstmt.setString(1,acname);  
  31.         ResultSet rs = this.pstmt.executeQuery() ;  
  32.         if(rs.next()){  
  33.             password = rs.getString("PASSWD");  
  34.         }  
  35.         this.pstmt.close() ;  
  36.         return password ;  
  37.     }  
  38. }  

代理主题实现类AccountDAOProxy.java:

[java] view plain copy
  1. package DAO ;  
  2.   
  3. import java.util.* ;  
  4. import java.sql.* ;  
  5.   
  6. import DAO.AccountDAOImpl;   
  7. import DAO.IAccountDAO;  
  8. import dbc.DatabaseConnection;  
  9. import VO.Account;  
  10.   
  11. public class AccountDAOProxy implements IAccountDAO {  
  12.     private DatabaseConnection dbc = null ;  
  13.     private IAccountDAO dao = null ;  
  14.     public AccountDAOProxy() throws Exception {     //在构造方法中实例化连接,同时实例化dao对象  
  15.         this.dbc = new DatabaseConnection() ;  
  16.         this.dao = new AccountDAOImpl(this.dbc.getConnection()) ;  
  17.     }  
  18.     public boolean doCreate(Account account) throws Exception{                
  19.         boolean flag = false ;  
  20.         try{  
  21.             if(this.dao.findByAccount(account.getAccount()) == null){  
  22.                 flag = this.dao.doCreate(account) ;  
  23.             }  
  24.         }catch(Exception e){  
  25.             throw e ;  
  26.         }finally{  
  27.             this.dbc.close() ;  
  28.         }  
  29.         return flag ;  
  30.     }  
  31.     public String findByAccount(String acname) throws Exception{  
  32.         String password = null ;  
  33.         try{  
  34.             password = this.dao.findByAccount(acname) ;  
  35.         }catch(Exception e){  
  36.             throw e ;  
  37.         }finally{  
  38.             this.dbc.close() ;  
  39.         }  
  40.         return password ;  
  41.     }  
  42. }  

DAO工厂类DAOFactory:

[java] view plain copy
  1. package factory;  
  2.   
  3. import DAO.IAccountDAO;  
  4. import DAO.AccountDAOProxy;  
  5. import DAO.IUploadFileDAO;  
  6. import DAO.UploadFileDAOProxy;  
  7.   
  8. public class DAOFactory {  
  9.     public static IAccountDAO getIAccountDAOInstance() throws Exception{  //取得DAO接口实例  
  10.         return new AccountDAOProxy();               //取得代理类实例  
  11.     }  
  12.     public static IUploadFileDAO getIUploadFileDAOInstance() throws Exception{  
  13.         return new UploadFileDAOProxy();  
  14.     }  
  15. }  

不要问我为什么这么多类这么麻烦。。这是小项目看起来是很麻烦,如果是大项目的话这样就更方便了。

写完这些就可以在RegisterServlet里愉快的注册了:

[java] view plain copy
  1. package servlets;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.*;  
  6.   
  7. import md5.MD5;  
  8. import factory.DAOFactory;  
  9. import VO.Account;  
  10.   
  11. import javax.servlet.ServletException;  
  12. import javax.servlet.http.HttpServlet;  
  13. import javax.servlet.http.HttpServletRequest;  
  14. import javax.servlet.http.HttpServletResponse;  
  15.   
  16. public class RegisterServlet extends HttpServlet {  //注册账号  
  17.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         PrintWriter out = response.getWriter();  
  20.         Account account = new Account() ;  
  21.         account.setAccount(request.getParameter("account"));  
  22.         try {  
  23.             account.setPassword(MD5.generateCode(request.getParameter("password")));  
  24.         } catch (Exception e1) {  
  25.             e1.printStackTrace();  
  26.         }  
  27.         try{  
  28.             if(DAOFactory.getIAccountDAOInstance().doCreate(account)){  //执行添加操作  
  29.                 out.print("注册成功!");  
  30.             } else {  
  31.                 out.print("该用户已被注册!");  
  32.             }  
  33.         }catch(Exception e){  
  34.             e.printStackTrace() ;  
  35.             out.print("注册失败!");  
  36.         }  
  37.     }  
  38. }  

这里当向数据库增加一个账号时使用了MD5加密,这样在数据库中存放的密码就是经过处理的密文,就算查询数据库看到的密码也是看不懂的乱码。MD5.java:

[java] view plain copy
  1. package md5;  
  2.   
  3. import java.security.MessageDigest;  
  4.   
  5. public class MD5 {  
  6.     public static String generateCode(String str) throws Exception{    //MD5加密  
  7.         MessageDigest md5 = MessageDigest.getInstance("MD5");  
  8.         byte[] srcBytes = str.getBytes();  
  9.         md5.update(srcBytes);  
  10.         byte[] resultBytes = md5.digest();  
  11.         String result = new String(resultBytes);  
  12.         return result;  
  13.     }  
  14. }  

以上就能成功地注册了。

既然能注册了,也就能登录了。现在写LoginServlet:

[java] view plain copy
  1. package servlets;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.*;  
  6. import factory.DAOFactory;  
  7. import VO.Account;  
  8. import md5.MD5;  
  9.   
  10. import javax.servlet.ServletException;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. public class LoginServlet extends HttpServlet {    //验证账号密码  
  16.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  17.             throws ServletException, IOException {  
  18.         PrintWriter out = response.getWriter();  
  19.         String account = request.getParameter("account");  
  20.         try {  
  21.             String password = MD5.generateCode(request.getParameter("password"));  
  22.             if(DAOFactory.getIAccountDAOInstance().findByAccount(account).equals(password)){  
  23.                 request.getSession().setAttribute("account", account);  
  24.                 response.sendRedirect("toIndex.jsp");  
  25.             }else{  
  26.                 out.print("账号或密码不正确");  
  27.             }  
  28.         }catch(Exception e){  
  29.             e.printStackTrace() ;  
  30.             out.print("登录错误");  
  31.         }  
  32.     }  
  33. }  

这里当验证成功时跳转到toIndex:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <html>  
  3.     <head><meta http-equiv="refresh" content="0;url=index.jsp"> </head>  
  4.     <body>  
  5.     正在登录……  
  6.     </body>  
  7. </html>  

为什么不直接跳到主页呢?因为我在登录页面写了AJAX,使LoginServlet的输出显示在登录页上,比如密码错时就把”账号或密码不正确“显示在登录页。但是登录成功时如果直接跳转到Index.jsp会让首页显示在登录页那里。所以设置一个过渡页面,然后再通过<meta http-equiv="refresh" content="0;url=index.jsp">标签跳转到首页。

index.jsp

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <%@ page import="factory.DAOFactory" %>  
  3. <%@ page import="VO.UploadFile" %>  
  4. <% request.setCharacterEncoding("utf-8"); %>  
  5. <html>  
  6.     <head>  
  7.         <title>WormJam-首页</title>  
  8.         <head><link rel="stylesheet" href="css/style.css" type="text/css"></head>  
  9.     </head>  
  10.     <body>  
  11.         <div class="header">  
  12.         <div class="headerText">  
  13.         <%  
  14.             String account = (String)session.getAttribute("account");  
  15.             out.println("欢迎你," + account);  
  16.          %>  
  17.         <a href="loginOut.jsp">退出登录</a>  
  18.         </div>  
  19.         </div>  
  20.         <div class="body">  
  21.         <h1>上传我的源代码</h1>  
  22.         <form action="UploadServlet" method="post" enctype="multipart/form-data">  
  23.             选择一个文件:  
  24.             <input type="file" name="myFile"><br>  
  25.             添加描述:<br>  
  26.             <textarea rows="3" cols="80" name="text"></textarea><br>  
  27.             <input type="submit" value="上传">  
  28.             <a href="myUpload.jsp">我上传的</a>  
  29.         </form>  
  30.         ${msg }  
  31.         <hr>  
  32.         <h1>热门分享</h1>  
  33.         <table width="80%">  
  34.         <tr class="title">  
  35.             <td>文件名</td>  
  36.             <td>作者</td>  
  37.             <td>描述</td>  
  38.             <td>下载</td>  
  39.         </tr>  
  40.         <%  
  41.             List<UploadFile> all = DAOFactory.getIUploadFileDAOInstance().findAll();  
  42.             Iterator<UploadFile> iter = all.iterator();  
  43.             while(iter.hasNext()){  
  44.                 UploadFile file = iter.next();  
  45.                 out.println("<tr>");  
  46.                 out.println("<td>" + file.getFileName() + "</td>");  
  47.                 out.println("<td><a href='hisUpload.jsp?account=" + file.getAccount() + "'>" + file.getAccount() + "</td>");  
  48.                 out.println("<td>" + file.getDescription() + "</td>");  
  49.                 out.println("<td><a href='/WormJam/files/" + file.getFileName() +"'>下载</a>");  
  50.                 out.println("<tr>");  
  51.             }  
  52.          %>  
  53.          </table>  
  54.          </div>  
  55.     </body>  
  56. </html>  

在首页,可以上传文件,然后再热门分享中把所有文件以及上传文件的作者列出来。我这里没有遍历文件夹来列出文件,而是在上传文件的同时记录到数据库。因此还应建立上传文件的DAO类。

VO类UploadFile.java:

[java] view plain copy
  1. package VO;  
  2.   
  3. public class UploadFile {   //用户上传文件的类  
  4.     private String account;  
  5.     private String fileName;  
  6.     private String description;  
  7.     public String getAccount(){  
  8.         return account;  
  9.     }  
  10.     public void setAccount(String account){  
  11.         this.account = account;  
  12.     }  
  13.     public String getFileName(){  
  14.         return fileName;  
  15.     }  
  16.     public void setFileName(String fileName){  
  17.         this.fileName = fileName;  
  18.     }  
  19.     public String getDescription(){  
  20.         return description;  
  21.     }  
  22.     public void setDescription(String description){  
  23.         this.description = description;  
  24.     }  
  25. }  

定义了文件名,作者及描述。

DAO标准类IUploadFileDAO.java:

[java] view plain copy
  1. package DAO;  
  2.   
  3. import java.util.* ;  
  4. import VO.UploadFile;  
  5.   
  6. public interface IUploadFileDAO {  
  7.     public boolean doCreate(UploadFile file) throws Exception;              //写入  
  8.     public List<UploadFile> findByAccount(String account) throws Exception;   //按账号查找文件  
  9.     public List<UploadFile> findAll() throws Exception;                       //列出所有文件  
  10. }  

真实主题实现类UploadFileDAOImpl.java:

[java] view plain copy
  1. package DAO ;  
  2.   
  3. import java.util.* ;  
  4. import java.sql.* ;  
  5.   
  6. import DAO.IUploadFileDAO;   
  7. import VO.UploadFile;  
  8.   
  9. public class UploadFileDAOImpl implements IUploadFileDAO {  
  10.     private Connection conn = null;                     //数据库连接对象  
  11.     private PreparedStatement pstmt = null;             //数据库操作对象  
  12.     public UploadFileDAOImpl(Connection conn){                  //通过构造方法取得数据库连接  
  13.         this.conn = conn;  
  14.     }  
  15.     public boolean doCreate(UploadFile file) throws Exception{ //添加账户  
  16.         boolean flag = false;                               //定义标志位  
  17.         String sql = "INSERT INTO FILES(acname,file,descript) VALUES (?,?,?)";  
  18.         this.pstmt = this.conn.prepareStatement(sql);       //实例化PrepareStatement对象  
  19.         this.pstmt.setString(1,file.getAccount());  
  20.         this.pstmt.setString(2,file.getFileName());  
  21.         this.pstmt.setString(3, file.getDescription());  
  22.         if(this.pstmt.executeUpdate() > 0){                  //如果有更新操作  
  23.             flag = true ;  
  24.         }  
  25.         this.pstmt.close() ;  
  26.         return flag ;  
  27.     }  
  28.     public List<UploadFile> findByAccount(String acname) throws Exception{//按账号查找密码  
  29.         List<UploadFile> all = new ArrayList<UploadFile>();  
  30.         String sql = "SELECT FILE,descript FROM FILES WHERE acname=?" ;  
  31.         this.pstmt = this.conn.prepareStatement(sql) ;  
  32.         this.pstmt.setString(1,acname);  
  33.         ResultSet rs = this.pstmt.executeQuery() ;  
  34.         UploadFile file = null;  
  35.         while(rs.next()){  
  36.             file = new UploadFile();  
  37.             file.setFileName(rs.getString(1));  
  38.             file.setDescription(rs.getString(2));  
  39.             all.add(file);  
  40.         }  
  41.         this.pstmt.close();  
  42.         return all;  
  43.     }  
  44.     public List<UploadFile> findAll() throws Exception { //查找所有  
  45.         List<UploadFile> all = new ArrayList<UploadFile>();  
  46.         String sql = "SELECT * FROM FILES";  
  47.         this.pstmt = this.conn.prepareStatement(sql) ;  
  48.         ResultSet rs = this.pstmt.executeQuery() ;  
  49.         UploadFile file = null;  
  50.         while(rs.next()){  
  51.             file = new UploadFile();  
  52.             file.setAccount(rs.getString(1));  
  53.             file.setFileName(rs.getString(2));  
  54.             file.setDescription(rs.getString(3));  
  55.             all.add(file);  
  56.         }  
  57.         this.pstmt.close();  
  58.         return all;  
  59.     }  
  60. }  

代理主题实现类UploadFileDAOProxy:

[java] view plain copy
  1. package DAO ;  
  2.   
  3. import java.util.* ;  
  4. import java.sql.* ;  
  5.   
  6. import DAO.UploadFileDAOImpl;   
  7. import DAO.IUploadFileDAO;  
  8. import dbc.DatabaseConnection;  
  9. import VO.UploadFile;  
  10.   
  11. public class UploadFileDAOProxy implements IUploadFileDAO {  
  12.     private DatabaseConnection dbc = null ;  
  13.     private IUploadFileDAO dao = null ;  
  14.     public UploadFileDAOProxy() throws Exception {      //在构造方法中实例化连接,同时实例化dao对象  
  15.         this.dbc = new DatabaseConnection() ;  
  16.         this.dao = new UploadFileDAOImpl(this.dbc.getConnection()) ;  
  17.     }  
  18.     public boolean doCreate(UploadFile file) throws Exception{                
  19.         boolean flag = false ;  
  20.         try{  
  21.             flag = this.dao.doCreate(file) ;  
  22.         }catch(Exception e){  
  23.             throw e ;  
  24.         }finally{  
  25.             this.dbc.close() ;  
  26.         }  
  27.         return flag ;  
  28.     }  
  29.     public List<UploadFile> findByAccount(String acname) throws Exception{  
  30.         List<UploadFile> all = null;  
  31.         try{  
  32.             all = this.dao.findByAccount(acname) ;  
  33.         }catch(Exception e){  
  34.             throw e ;  
  35.         }finally{  
  36.             this.dbc.close() ;  
  37.         }  
  38.         return all ;  
  39.     }  
  40.     public List<UploadFile> findAll() throws Exception{  
  41.         List<UploadFile> all = null;  
  42.         try{  
  43.             all = this.dao.findAll() ;  
  44.         }catch(Exception e){  
  45.             throw e ;  
  46.         }finally{  
  47.             this.dbc.close() ;  
  48.         }  
  49.         return all ;  
  50.     }  
  51. }  

然后就可以上传文件了,并且上传成功后会把文件名,作者,和描述保存在数据库。上传文件需要用到jsmartcom包,而且我在解决上传的文件名乱码这一块花了很长时间,注意,我的项目里所使用的都是utf-8编码。有些jsmartcom包不支持中文,可以下载到别人改过的支持中文的包。

上传文件用UploadServlet:

[java] view plain copy
  1. package servlets;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.ArrayList;  
  6.   
  7. import factory.DAOFactory;  
  8. import VO.UploadFile;  
  9.   
  10. import javax.servlet.ServletException;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14. import javax.servlet.RequestDispatcher;  
  15. import javax.servlet.ServletConfig;  
  16. import javax.servlet.http.HttpSession;  
  17.   
  18. import com.jspsmart.upload.File;  
  19. import com.jspsmart.upload.SmartUpload;  
  20. import com.jspsmart.upload.SmartUploadException;  
  21.   
  22. public class UploadServlet extends HttpServlet {    //上传文件时的处理  
  23.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  24.             throws ServletException, IOException {  
  25.         UploadFile uploadfile = new UploadFile();  
  26.         HttpSession session = request.getSession();  
  27.         String account = (String)session.getAttribute("account");           //获取session中的用户名  
  28.         uploadfile.setAccount(account);  
  29.         SmartUpload smartUpload = new SmartUpload();  
  30.         ServletConfig config = this.getServletConfig();  
  31.         smartUpload.initialize(config, request, response);        
  32.         try{  
  33.             smartUpload.upload();  
  34.             String text = smartUpload.getRequest().getParameter("text");  
  35.             uploadfile.setDescription(text);  
  36.             File smartFile = smartUpload.getFiles().getFile(0);  
  37.             String fileName = smartFile.getFileName();  
  38.             smartFile.saveAs("/files/" + fileName,smartUpload.SAVE_VIRTUAL);              
  39.             request.setAttribute("msg""上传成功!");  
  40.             uploadfile.setFileName(fileName);  
  41.             DAOFactory.getIUploadFileDAOInstance().doCreate(uploadfile);  
  42.         }catch(SmartUploadException e){  
  43.             request.setAttribute("msg""上传失败!");  
  44.             e.printStackTrace();              
  45.         } catch (Exception e) {  
  46.             request.setAttribute("msg""上传失败!");  
  47.             e.printStackTrace();  
  48.         }  
  49.         RequestDispatcher rd = request.getRequestDispatcher("/index.jsp");  
  50.         rd.forward(request, response);  
  51.     }  
  52. }  

需注意,session中的用户名是在登录成功时设置的,我用一个session登录验证的过滤器来确保用户只有在登录的时候能够访问主页等页面,不然跳到登录页面:

LoginFilter:

[java] view plain copy
  1. package filters;  
  2.   
  3. import javax.servlet.http.HttpServlet;  
  4. import java.io.IOException;  
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpSession;  
  13.   
  14. public class LoginFilter implements Filter {  //登录验证过滤器  
  15.     public void init(FilterConfig config) throws ServletException{}  
  16.     public void doFilter(ServletRequest request,ServletResponse response,  
  17.             FilterChain chain) throws IOException,ServletException{  
  18.         HttpServletRequest req = (HttpServletRequest)request;  
  19.         HttpSession ses = req.getSession();  
  20.         if(ses.getAttribute("account")!=null){  
  21.             chain.doFilter(request, response);  
  22.         }else{  
  23.             request.getRequestDispatcher("login.jsp").forward(request, response);  
  24.         }  
  25.     }  
  26.     public void destroy(){}  
  27. }  

而点击页面上方的”退出登录“时,就要删除session中的用户,并跳到登录页:

loginOut.jsp:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <%   
  3.     session.removeAttribute("account");  
  4.     response.sendRedirect("login.jsp");  
  5. %>  

最后,还有点击”我的上传“和“他的上传”的页面:

myUpload.jsp:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <%@ page import="factory.DAOFactory" %>  
  3. <%@ page import="VO.UploadFile" %>  
  4. <% request.setCharacterEncoding("utf-8"); %>  
  5. <html>  
  6.     <head>  
  7.         <title>WormJam-我的上传</title>  
  8.         <head><link rel="stylesheet" href="css/style.css" type="text/css"></head>  
  9.     </head>  
  10.     <body>  
  11.         <div class="header">  
  12.         <div class="headerText">  
  13.         <%  
  14.             String account = (String)session.getAttribute("account");  
  15.             out.println("欢迎你," + account);  
  16.          %>  
  17.         <a href="loginOut.jsp">退出登录</a>  
  18.         <a href="index.jsp">返回首页</a>  
  19.         </div>  
  20.         </div>  
  21.         <div class="body">  
  22.         <h1>我的上传</h1>  
  23.         <table width="60%">  
  24.         <tr class="title">  
  25.             <td>文件名</td>  
  26.             <td>描述</td>  
  27.             <td>下载</td>  
  28.         </tr>  
  29.         <%  
  30.             List<UploadFile> all = DAOFactory.getIUploadFileDAOInstance().findByAccount(account);  
  31.             Iterator<UploadFile> iter = all.iterator();  
  32.             while(iter.hasNext()){  
  33.                 UploadFile file = iter.next();  
  34.                 out.println("<tr>");  
  35.                 out.println("<td>" + file.getFileName() + "</td>");  
  36.                 out.println("<td>" + file.getDescription() + "</td>");  
  37.                 out.println("<td><a href='/WormJam/files/" + file.getFileName() +"'>下载</a>");  
  38.                 out.println("<tr>");  
  39.             }  
  40.          %>  
  41.          </table>  
  42.          </div>  
  43.     </body>  
  44. </html>  

hisUpload.jsp:

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>  
  2. <%@ page import="factory.DAOFactory" %>  
  3. <%@ page import="VO.UploadFile" %>  
  4. <% request.setCharacterEncoding("utf-8"); %>  
  5. <html>  
  6.     <head>  
  7.         <title>WormJam-他的上传</title>  
  8.         <head><link rel="stylesheet" href="css/style.css" type="text/css"></head>  
  9.     </head>  
  10.     <body>  
  11.         <div class="header">  
  12.         <div class="headerText">  
  13.         <%  
  14.             String account = (String)session.getAttribute("account");  
  15.             out.println("欢迎你," + account);  
  16.             String acname = request.getParameter("account");  
  17.          %>  
  18.         <a href="loginOut.jsp">退出登录</a>  
  19.         <a href="index.jsp">返回首页</a>  
  20.         </div>  
  21.         </div>  
  22.         <div class="body">  
  23.         <h1><%= acname + "的上传" %></h1>  
  24.         <table width="60%">  
  25.         <tr class="title">  
  26.             <td>文件名</td>  
  27.             <td>描述</td>  
  28.             <td>下载</td>  
  29.         </tr>  
  30.         <%  
  31.             List<UploadFile> all = DAOFactory.getIUploadFileDAOInstance().findByAccount(acname);  
  32.             Iterator<UploadFile> iter = all.iterator();  
  33.             while(iter.hasNext()){  
  34.                 UploadFile file = iter.next();  
  35.                 out.println("<tr>");  
  36.                 out.println("<td>" + file.getFileName() + "</td>");  
  37.                 out.println("<td>" + file.getDescription() + "</td>");  
  38.                 out.println("<td><a href='/WormJam/files/" + file.getFileName() +"'>下载</a>");  
  39.                 out.println("<tr>");  
  40.             }  
  41.          %>  
  42.          </table>  
  43.          </div>  
  44.     </body>  
  45. </html>  

最后补充一点,点击下载时会新开一个页面显示文件的内容,而右键“下载”点击“链接另存为”时才会下载,特别是如果文件是zip等不能查看的类型就会出错。也有使点击就能下载的方法,我比较懒就没去试了。


以上です

希望对大家有所帮助