Ajax 获取JSON数据

首先,介绍一下JSON。JSON(JavaScript Obect Notation)是一种轻量级的数据交换格式,易于人阅读和书写,也易于机器解析和生成。JSON建构与两种结构:

  • “名称/值”对的集合,在不同的语言中,它被理解为对象,记录,结构,字典,哈希表,有键列表或者关联数组。
  • 值的有序列表,大部分语言中,它被理解为数组

JSON具有以下这些形式:

对象是一个无序的,“名称/值”对的集合。一个对象以“{”始,“}”结束。每个名称后面跟一个“:”,“名称/值”对之间用“,”隔开。

数组是值的有序集合,一个数组以“[”开始,“]”结束,值之间用“,”隔开。

值可以是用双引号括起来的字符串,数值,true,false, null,对象或者数组。这些结构可以嵌套。

字符串是由双引号包围的任意数量的Unicode字符的集合,使用反斜线转义。一个字符即一个单独的字符串。

数值也与C或Java的数值非常类似,除去未曾使用的八进制与十六进制,除去一些编码细节。

getJSON(url,[data],[callback])是JQuery获取JSON数据格式的方法,其中“url”表示请求的地址,可以是生成JSON数据的页面或者JSON数据保存的文件,可选项data表示发送到服务器端的数据,其格式是“key/value”的键值对,另一个可选项“callback”表示加载成功时执行的回调函数。下面是在一个页面中用Ajax获取另一个页面生成的JSON数据的例子:

$.getJSON(
	"jsonGene.jsp", 
	function(data){
		$.each(data, function(index, values){
			$.each(values, function(key, value){
				$("#page").append(value + "<br>");
			});
		});
	});

生成JSON数据的JSP页面为:

<jsp:directive.page contentType="text/html; charset=utf-8"/>
<%@ page import="handle.DBlogic"%>
<%@ page import="handle.Seed"%>
<%@ page import="java.util.*"%>
<%
	DBlogic dblogic = new DBlogic();
	ArrayList<Seed> seedList = dblogic.getdata();
	String str = "[";
	int i;
	for(i=0; i<seedList.size()-1; i++){
		Seed seed = seedList.get(i);
		String temp = "{";
		temp += "\"patternTypes\": " + '"' + seed.getPatternTypes() + '"' + ",";
		temp += "\"pattern1\": " + '"' + seed.getPattern1() + '"' + ",";	
		temp += "\"label\": " + '"' + seed.getLabel()+ '"' + ",";
		temp += "\"value\": " + '"' + seed.getValue() + '"' + ",";
		temp += "\"anotherPattern1\": " + '"' + seed.getAnotherPattern1() + '"';
		temp += "},";
		str += temp;
	}
	Seed seed = seedList.get(i);
	String temp = "{";
	temp +=	"\"patternTypes\": " + '"' + seed.getPatternTypes() + '"' + ",";
	temp += "\"pattern1\": " + '"' + seed.getPattern1() + '"' + ",";	
	temp += "\"label\": " + '"' + seed.getLabel()+ '"' + ",";
	temp += "\"value\": " + '"' + seed.getValue() + '"' + ",";
	temp += "\"anotherPattern1\": " + '"' + seed.getAnotherPattern1() + '"';
	temp += "}";
	
	str += temp;
	str += "]";
	
	out.print(str);
 %>

 生成的JSON对象为:

[
    {
        "patternTypes": "PER,CIT",
        "pattern1": "1177_3_14_;",
        "label": "negPlace",
        "value": "0.5",
        "anotherPattern1": "knock.v DATE @"
    },
    {
        "patternTypes": "PER,CIT",
        "pattern1": "126_14_53_;14_53_24_;",
        "label": "isInCity",
        "value": "0.38888889",
        "anotherPattern1": "marry.v in.p"
    },
    {
        "patternTypes": "PER,CIT",
        "pattern1": "14_53_24_;",
        "label": "isInCity",
        "value": "0.5",
        "anotherPattern1": "marry.v in.p"
    }
]
一直没有获取到页面生成的JSON数据,因为将JSP页面写成了HTML格式,其生成的响应是一个HTML页面,不是格式正确JSON数据,自然获取不到了。
 
ref:
http://www.bejson.com 提供了JSON数据的在线校验,可以查看程序生成的JSON数据格式是否正确
写前台开发的时候,Firefox的firebug插件很好用,可以查看页面发出的请求以及得到相应的数据,对脚本的调试很有帮助。

使用JavaMail SMTP协议发送邮件

最近需要实现通过发送邮件让用户找回密码的功能,自己用Socket写了SMTP协议的邮件发送程序,但是很多邮件服务器的anti-spam需要验证发送邮箱的合法性,所以只得放弃,后来发现用javamail包可以很方便的实现。示例程序使用gmail的邮件服务器来发送邮件。关于SMTP端口等配置见下面链接:

https://support.google.com/mail/bin/answer.py?hl=en&answer=13287

注:下面程序需导入javaee-api-6.0.jar 跟 mail.jar

1.使用TLS发送邮件

import java.util.Properties;
 
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
 
public class SendMailTLS {
 
	public static void main(String[] args) {
 
		final String username = "someoe@gmail.com";
		final String password = "password";
 
		Properties props = new Properties();
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable", "true");
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.port", "587");
 
		Session session = Session.getInstance(props,
		  new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(username, password);
			}
		  });
 
		try {
 
			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress("someone@gmail.com"));
			message.setRecipients(Message.RecipientType.TO,
				InternetAddress.parse("someone@yourISP.com"));
			message.setSubject("Testing Subject");
			message.setText("Dear Mail Crawler,"
				+ "\n\n No spam to my email, please!");
 
			Transport.send(message);
 
			System.out.println("Done");
 
		} catch (MessagingException e) {
			throw new RuntimeException(e);
		}
	}
}

2.使用SSL发送邮件

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
 
public class SendMailSSL {
	public static void main(String[] args) {
		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.port", "465");
 
		Session session = Session.getDefaultInstance(props,
			new javax.mail.Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication("username","password");
				}
			});
 
		try {
 
			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress("from@no-spam.com"));
			message.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse("to@no-spam.com"));
			message.setSubject("Testing Subject");
			message.setText("Dear Mail Crawler," +
					"\n\n No spam to my email, please!");
 
			Transport.send(message);
 
			System.out.println("Done");
 
		} catch (MessagingException e) {
			throw new RuntimeException(e);
		}
	}
}

统一textarea在IE、Firefox下的效果

使用rows cols来控制textarea的高度和宽度,发现在不同的浏览器下显示效果不一样,在IE和Firefox下的每行字数和文字的行数都不一样,而且在字数不足滚动的情况下,IE默认是有滚动条的,而Firefox是没有滚动条的。那应该如何解决这个问题呢?

其实比较简单:

1、用textarea的宽度(widht)和高度(height)来定义textarea的大小
2、让滚动条自适应:overflow-y:auto

重新认识session对象

什么是session对象?

session对象用来保存在每个用户会话期间需要保存的数据信息,这样就方便会话期间处理程序,如可以用session变量记住用户名,以后不必再其他网页中重复输入。session对象的信息保存在服务器端中,但session ID保存在客户机的Cookies中。由于每个客户端与服务器会话的ID不同,因此服务器通过这个ID来区分不同的用户。当用户关闭某个Web服务器上的所有网页时,此服务器与客户机的session对象及其变量会自动消失。

以前写程序,测试时教师与学生在同一个浏览器中登录,发现使用session对象来记住用户身份会乱掉,比如学生先登录,通过session.setAttribute("user_role", "student"), 然后教师登录, session.setAttribute("user_role", teacher), 然后在学生页面获取session对象,session.getAttribute("user_role"),发现这是user_role的值变为"teacher"。当时我认为session对象在不同的用户之间是共享的。然而,在实际的系统中,教师与学生是不可能在同一个浏览器中登录的,因为通过session记住用户名之后,当用户在同一个浏览器中打开新的页面进入系统时,会以当前服务器端保存的session信息自动登录系统,也就是一个浏览器中只能一种用户身份登录。所以session共享是不可能存在的问题。

JDBC使用预编译SQL的好处

1. 执行效率

PreparedStatement可以尽可能的提高访问数据库的性能,数据库在处理SQL语句时都有一个预编译的过程,而预编译对象就是把一些格式固定的SQL编译后,存放在内存池中即数据库缓冲池,当我们再次执行相同的SQL语句时就不需要预编译的过程了,只需DBMS运行SQL语句。所以当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,特别是的大型的数据库中,它可以有效的也加快了访问数据库的速度。

2. 代码可读性、可维护性
比如向记录用户信息的表中插入记录: user(id, password, name, email, address)。使用Statement的SQ语句如下:
String sqlString = "insert into user values('" +
user.id + "', '" +
user.password + "', '" +
user.name + "', '" +
user.email + "', '" +
user.address + "')";

使用PrearedStatement的SQL语句如下:

String sqlString = "insert into user(id, password, name, email, address) values(?, ?, ?, ?, ?)";
PreparedStatement pstmt = connection.PreparedStatement(sqlString);
pstmt.setString(1, user.id);
pstmt.setString(2, user.password);
pstmt.setString(3, user.name);
pstmt.setString(4, user.email);
pstmt.setString(5, user.address);

使用占位符?代替参数,将参数与SQL语句分离出来,这样就可以方便对程序的更改和延续,同样,也可以减少不必要的错误。

3. SQL执行的安全性
SQL注入攻击:是从客户端输入一些非法的特殊字符,从而使服务器端在构造SQL语句时仍能正确构造,从而收集程序和服务器的信息或数据。比如在Web信息系统的登录入口处,要求用户输入用户名和密码,客户端输入后,服务器端根据用户输入的信息来构造SQL语句,在数据库中查询是否存在此用户名以及密码是否正确。假设使用上述例子中的表“user”构造SQL语句的Java程序可能是:
sqlString = "select * from user where user.id = '" + userID + "' and user.password = "' + userPassword + "'";
其中userID, userPassword是从用户输入的用户名及密码。如果用户和密码输的都是 '1' or '1'='1',则服务器端生成的SQL语句如下:
sqlString = "select * from user where user.id = '1' or '1'='1' and user.password = '1' or '1'='1'

这个SQL语句中的where字句没有起到数据筛选的作用,因为只要数据库中有记录,就会返回一个结果不为空的记录集,查询就会通过。上面的例子说明:在Web环境中,有恶意的用户会利用那些设计不完善的、不能正确处理字符串的应用程序。特别是在公共Web站点上,在没有首先通过PreparedStatement对象处理的情况下,所有的用户输入都不应该传递给SQL语句。此外,在用户有机会修改SQL语句的地方,如HTML的隐藏区域或一个查询字符串上,SQL语句都不应该被显示出来。

 

Tomcat 5.5 配置数据库连接池

今天下定决心解决数据库连接池问题,因为访问数据库总是要考虑连接如何分配,如果忘记释放很多连接或造成程序性能的下降,还是把这些问题都交给数据库连接池来解决吧。

首先,每一次Web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的Web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
 
由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。
 
对于共享资源,有一个很著名的设计模式:资源池(Resource Pool)。该模式正是为了解决资源的频繁分配、释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量、使用情况,为系统开发、测试及性能调整提供依据。

1. 使用Tomcat 5.5版本,首先安装Admin组件(可以在浏览器中以图形化界面配置Tomcat)

可以参考http://book.51cto.com/art/200908/148435.htm

2. 配置数据库连接池

2.1 配置JNDI

启动Tomcat,打开Firefox在地址栏内输入http://localhost:8080/admin 进入Tomcat的管理界面,点击右边的Data Sources 在右上角的下拉菜单中选择Create New Data Source 在下边的输入框中输入需要的配置信息。之后保存并提交。

  • JNDI Name:jdbc/Pool4User                              //(Pool4User自己命名)
  • Data Source URL:jdbc:mysql://localhost:3306/user     //(user为要连接的数据库名)
  • JDBC Driver Class: com.mysql.jdbc.Driver
  • User Name:root                                        //根据你的MySQL数据库的用户名密码
  • Password:                                             //数据库密码
  • Max. Active Connections: 20                           //最大连接数
  • Max. Idle Connections: 5                              //最大的空闲连接数
  • Max. Wait for Connection:5000                         //最大等待连接时间
2.2 配置tomcat添加JDBC驱动
首先要下载安装驱动,然后将mysql-connector-java-xxx-bin.jar文件放到Tomcat安装路下的common/lib下
 
2.3 配置tomcat安装路下的/conf/context.xml文件,添加如下内容:
<Resource name="jdbc/Pool4User" 
                auth="Container" 
                type="javax.sql.DataSource" 
                driverClassName="com.mysql.jdbc.Driver" 
                url="jdbc:mysql://localhost:3306/user"
                username="root" 
                password="" 
                maxActive="20" 
                maxIdle="5" 
                maxWait="5000" />
 
3. 编写测试程序(JSP文件)
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Connection Pool Testing</title>
</head>
<body>
Tomcat Connection Pool Testing
<br>
<%
Connection connection = null;
Context iniCtx = new InitialContext();
Context ctx = (Context)iniCtx.lookup("java:comp/env");

javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup("jdbc/Pool4User");
connection = ds.getConnection();

String sqlString = "select * from account";
PreparedStatement pstmt = connection.prepareStatement(sqlString);
ResultSet rs = pstmt.executeQuery();

out.print("<table>");
while(rs.next())
{
	out.print("<tr>");
		out.print("<td>" + rs.getString(1) + "</td>");
		out.print("<td>" + rs.getString(2) + "</td>");
	out.print("</tr>");
}
out.print("</table>");

rs.close();
pstmt.close();
connection.close();

out.print("test success!");
 %>
 
</body>
</html>
 
至此数据库连接池配置完毕!

 

如何提升MySQL批量插入的效率

需要将大量数据(大概5W条)插入MySQL数据库,用普通的SQL Statement执行,时间大概是几分钟。于是想到用PreparedStatement,但是改了之后发现效率并没有很大的提升。不成,想到了load data local infile...命令,以前一直认为这条命令仅限MySQL终端上使用而不是标准的SQL语句,今天看了几篇文章之后有了很大的收获。

1. 使用PreparedStatement batch operation

以前使用PreparedStatement性能没有很大提升的原因在于:

  • 没有使用批处理方法
  • 在语句执行之前应关闭事务自动提交,语句执行完之后再提交
	public void batchLoad(Connection connection) 
	{
		try {
			connection.setAutoCommit(false);
			
			BufferedReader reader = new BufferedReader(new FileReader("tfacts_result"));
			String sqlString = "insert into test(node1, node2, weight) values(?, ?, ?)";
			
			PreparedStatement pstmt = connection.prepareStatement(sqlString);
			String line = null;
			
			while(true)
			{
				line = reader.readLine();
				if(line == null)
				{
					break;
				}
				
				String[] columns = line.split("\t");
				
				for(int i = 1; i <= columns.length; i++)
				{
					pstmt.setString(i, columns[i-1]);	
				}
				pstmt.addBatch();
			}
			
			pstmt.executeBatch();
			
			connection.commit();  
			
			pstmt.close();
			
			reader.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (SQLException e){
			e.printStackTrace();
		}catch (IOException e){
			e.printStackTrace();
		}

2.使用load data local infile into tabel XXX(注意在文件中用\t将每列数据隔开)

	public void loadData(Connection connection)
	{
		long starTime = System.currentTimeMillis();
	
		String sqlString = "load data local infile ? into table test";
		PreparedStatement pstmt;
		try {
			pstmt = connection.prepareStatement(sqlString);
			
			pstmt.setString(1, "tfacts_result");
			
			pstmt.executeUpdate();
			
			pstmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("program runs " + (endTime - starTime) + "ms");

	}

测试了5W条数据,PreparedStatement耗时10s,而load data infile耗时3s。

REF:

http://www.iteye.com/topic/320942

http://www.blogjava.net/jicheng687/archive/2010/12/23/341418.html

PS:使用load data local infile 命令的时候貌似最后一列后面还需要加“\t”,不然会会把换行符导入到表中最后一列的数据中,影响到其他SQL语句对这一列数据的引用。

MyEclipse 堆溢出设置

最近写JSP需要调用Java程序来处理大量数据,很容易就堆溢出了,在网上找到了如下的解决方法:

可以找到myEclipse的安装目录找到myeclipse.ini文件,用记事本打开,找到这段将其改为如下(这是最大的虚拟内存,可以根据自己的机器配置进行设置)

-vmargs  
-Xmx1024m  
-XX:MaxPermSize=512m  
-XX:ReservedCodeCacheSize=512m  

初始值:

-XX:MaxPermSize=256m
-XX:ReservedCodeCacheSize=64m

从表单上传文件到数据库或服务器

使用html表单上传文件,然后保存到数据库或服务器,使用Apache commons fileUpload组件来实现。组件下载地址:

common fileUpload: http://commons.apache.org/fileupload/index.html

commons io: http://commons.apache.org/io/

PS. 注意两个jar包都要导入

html代码:

<form enctype="multipart/form-data" id="form1" name="form1" action="UploadServlet" method="post">  
  
    <input type="file" id="uploadfile" name="uploadfile" />  
  
    <input type="text" name="column" />  
  
    <input type="submit" value="上传" name="submit">  
  
</form>  

1. 上传文件至数据库

		String[] errorType ={"exe","com","cgi","asp","jsp"};
		InputStream  inStream = null;
		int MAXSIZE = 5*1024*1024;	//文件大小限制为5M
		int errorType_int = 1;
		DiskFileUpload fu = new DiskFileUpload();
		fu.setSizeMax(MAXSIZE);
		fu.setSizeThreshold(MAXSIZE);
		fu.setRepositoryPath("D://temp");
	
		List fileItems = fu.parseRequest(request);
		Iterator iter = fileItems.iterator();
		String name = null; 
		long size = 0L;
		FileItem item = null;
		while(iter.hasNext())
		{
			item = (FileItem)iter.next();
			if (!item.isFormField())
     		{
        		name = item.getName();//获取上传的文件名
        		size = item.getSize();//获取上传的文件大小(字节为单位)
        		if(name == null || name.equals(""))
        		{
        			errorType_int = 0;
        			out.print("上传文件不能为空!"+"<br>");
        			break;
        		}
  				else if(size >= MAXSIZE)
  				{
  					errorType_int = 0;
  					out.println("文件大小超过5M"+"<br>");
  					break;
  				}
  				else
  				{
  					String suffix = name.substring(name.lastIndexOf('.'));
   					for (int temp=0; temp < errorType.length; temp++)
   					{
       					if (name != null && name.endsWith(errorType[temp]))
        				{
        					out.println(name+": 不允许上传此类型文件!<br>");
    						errorType_int = 0;
         				}
    				}
    				if(errorType_int != 0)
    					inStream=item.getInputStream(); 
    			}
  			}
  			else	//获取表单数据
  			{
  				if(item.getFieldName().equals("deadline"))
  					deadline = (String)item.getString();
  			}
		}//while
		//开始上传数据
    	if(errorType_int != 0)
    	{ 			
        	int byteread=0;
        	//读取输入流,也就是上传的文件内容
        	PreparedStatement pstmt=con.prepareStatement("insert into work_provide(Course_Id,Work_No,Work_Name,Work_quote,Work,Insert_Time,Deadline) values(?,?,?,?,?,?,?)");
        	pstmt.setString(1,Course_Id);
        	pstmt.setInt(2,Work_No); 
        	pstmt.setString(3,name);
        	pstmt.setInt(4,Work_Quote);
        	pstmt.setBinaryStream(5,inStream,(int)size);
        	pstmt.setString(6,dateString);
        	pstmt.setString(7,mdate);
        	pstmt.executeUpdate();
        	inStream.close();
			con.close();
		}
	}

这里获取上传文件的输入流,然后用PreparedStatement将文件保存到数据库

2. 上传文件到服务器

String fileDir = this.getServletContext().getRealPath("temp/");  
String localFileName = "";  
String serverFileName = "";  
String serverFilePath = "";  
if(ServletFileUpload.isMultipartContent(request)) {  
    DiskFileItemFactory factory = new DiskFileItemFactory(); // 基于磁盘文件项目创建一个工厂对象  
    //factory.setSizeThreshold(20*1024);  
    factory.setRepository(factory.getRepository());  
    ServletFileUpload upload = new ServletFileUpload(factory); // 创建一个新的文件上传对象  
    int size = 10*1024*1024;  // 最大上传文件,不超过10M  
    List formlists = null;  
    FileItem formitem;  
       try{  
           formlists = upload.parseRequest(request); // 解析上传请求  
       }catch(FileUploadException e){  
              e.printStackTrace();  
       }     
       Iterator iter = formlists.iterator(); // 枚举方法  
       while(iter.hasNext()) {  
           formitem = (FileItem)iter.next(); // 获取FileItem对象  
           if(!formitem.isFormField()) {     // 判断是否为文件域  
              if(formitem.getName()!=null && !formitem.getName().equals("")) { // 判断是否选择了文件  
                  long upFileSize = formitem.getSize(); // 上传文件大小  
                  if (upFileSize > size) {  
                     out.print("<script>alert('上传文件太大![<100M]')</script>");  
                     return;  
                  }     
                  localFileName = formitem.getName();   // 获取文件名  
                  int ii = localFileName.lastIndexOf(".");  
                  String sExt = localFileName.substring(ii,localFileName.length());//取文件名的后缀  
                  if ((!sExt.equals(".xls")) && (!sExt.equals(".xlsx"))) {  
                     out.print("<script>alert('请选择excel文件!')</script>");  
                     return;  
                  }  
                  //得到不重复的文件名,这一步是为了防止同时上传两个同文件名的excel而做的,避免文件名重复     
                  Date dt = new Date(System.currentTimeMillis());     
                  SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");  
                  serverFileName = fmt.format(dt);      
                  serverFileName = serverFileName + sExt;     
                  //如果不存在该目录,则新建一个     
                  File dir =new File(fileDir);     
                  if (!dir.exists()) {     
                     dir.mkdirs();     
                  }  
                  serverFilePath = fileDir+"\\"+serverFileName;  
                  File serverFile = new File(serverFilePath);  
                  try {  
                     formitem.write(serverFile);  
                  }catch(Exception e) {  
                     e.printStackTrace();  
                  }   
              }else {                       
                  out.print("<script>alert('没有选择文件!')</script>");  
                  return;  
              }     
           }else {  
              try {  
                  if("column".equals(formitem.getFieldName())) {  
                     column = Integer.parseInt(formitem.getString("gb2312").trim());  
                         //System.out.println(column);  
                  }  
              }catch (NumberFormatException e) {  
                  e.printStackTrace();  
                  return;  
              }  
           }  
       }  

REF: http://yjandx.iteye.com/blog/1170356

使用properties文件配置数据库

先把数据库连接参数写到.properties文件中,文件内容如下:

URL=jdbc:mysql://localhost/#这里是数据库名

USER=#这里是连接数据库用户名
PASSWD=#连接数据库的密码
DRIVER=com.mysql.jdbc.Driver
 
把.properties文件放到当前应用的WEB/INF/classes子目录下,如果WEB/INF没有classes目录,就自行建立,再放到此目录下。
 
读取properties文件的程序为:
	        public Properties getPropertiesFile(String addr)
	        {
		        try{
			    Properties properties  = new Properties();
			    FileInputStream file = new FileInputStream(addr);
			    properties.load(file);
			    return properties;
		            }catch(IOException e){
			    e.printStackTrace();
			    return null;
		           }
	        }
		
           Properties properties = getPropertiesFile("/connection.properties");
		String driver = properties.getProperty("DRIVER");
		String url = properties.getProperty("URL");
		String user = properties.getProperty("USER");
		String pwd = properties.getProperty("PASSWD");
		try{
			Class.forName(driver);
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}
		try{
			this.connection = DriverManager.getConnection(url,user,pwd);
		}catch(SQLException e){
			e.printStackTrace();
		}