使用rows cols来控制textarea的高度和宽度,发现在不同的浏览器下显示效果不一样,在IE和Firefox下的每行字数和文字的行数都不一样,而且在字数不足滚动的情况下,IE默认是有滚动条的,而Firefox是没有滚动条的。那应该如何解决这个问题呢?
其实比较简单:
为学日益,为道日损
2012年4月03日 21:48
使用rows cols来控制textarea的高度和宽度,发现在不同的浏览器下显示效果不一样,在IE和Firefox下的每行字数和文字的行数都不一样,而且在字数不足滚动的情况下,IE默认是有滚动条的,而Firefox是没有滚动条的。那应该如何解决这个问题呢?
其实比较简单:
2012年3月19日 23:40
什么是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共享是不可能存在的问题。
2012年3月18日 14:39
1. 执行效率
PreparedStatement可以尽可能的提高访问数据库的性能,数据库在处理SQL语句时都有一个预编译的过程,而预编译对象就是把一些格式固定的SQL编译后,存放在内存池中即数据库缓冲池,当我们再次执行相同的SQL语句时就不需要预编译的过程了,只需DBMS运行SQL语句。所以当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,特别是的大型的数据库中,它可以有效的也加快了访问数据库的速度。
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语句分离出来,这样就可以方便对程序的更改和延续,同样,也可以减少不必要的错误。
sqlString = "select * from user where user.id = '" + userID + "' and user.password = "' + userPassword + "'";
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语句都不应该被显示出来。
2012年3月16日 14:50
今天下定决心解决数据库连接池问题,因为访问数据库总是要考虑连接如何分配,如果忘记释放很多连接或造成程序性能的下降,还是把这些问题都交给数据库连接池来解决吧。
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 在下边的输入框中输入需要的配置信息。之后保存并提交。
<%@ 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>
2012年3月14日 02:32
需要将大量数据(大概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语句对这一列数据的引用。
2012年3月13日 18:27
用Java的File类删除文件夹时发现,如果文件夹下有其他文件则此文件夹无法删除,需要递归的删除。
public void deleteFile(File fileDir)
{
if(fileDir.exists())
{
if(fileDir.isFile())
{
fileDir.delete();
}
else if(fileDir.isDirectory())
{
for(File file : fileDir.listFiles())
{
this.deleteFile(file);
}
fileDir.delete();
}
}
else
{
System.err.println("directory does not exist!");
}
}
2012年3月12日 13:32
最近写JSP需要调用Java程序来处理大量数据,很容易就堆溢出了,在网上找到了如下的解决方法:
可以找到myEclipse的安装目录找到myeclipse.ini文件,用记事本打开,找到这段将其改为如下(这是最大的虚拟内存,可以根据自己的机器配置进行设置)
-vmargs
-Xmx1024m
-XX:MaxPermSize=512m
-XX:ReservedCodeCacheSize=512m
初始值:
-XX:MaxPermSize=256m
-XX:ReservedCodeCacheSize=64m
2012年3月10日 18:21
使用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;
}
}
}
2012年3月10日 02:16
先把数据库连接参数写到.properties文件中,文件内容如下:
URL=jdbc:mysql://localhost/#这里是数据库名
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();
}
2012年3月07日 00:25
最近需要解析用户上传文档的文本内容,自己没有搜到很好的资料,在http://scturtle.is-programmer.com/的介绍下,找到了一些参考资料,于是很快的完成了基本文件格式的解析。下面把资料的链接跟代码地址附上
1.MS doc/docx/Excel/Powerpoint/...
解析微软的office文件有Apache的POI类库支持,只是doc/docx的工作还在完善之中,所以解析出来的格式不是很精确,比如图片部分不能完全去除掉会在解析得到的文本中留下部分乱码。
2.pdf
解析pdf文件有Apache pdfBox类库的支持,解析效果还不错。
3. html
解析html有很强大的工具htmlParser, 无需保存网页文件,只需给一个网页链接,就可以得到html文件中的文本内容,而且可以自动过滤很多无用标签,很是强大。
REF: http://htmlparser.sourceforge.net/
REF: http://perfectlife.iteye.com/blog/366084
4 rtf
解析rtf有javax类库的支持,只需import javax.swing.text.rtf.RTFEditorKit;就能解决问题
5. txt
这个就无需解析了,直接读取文件的文本内容就行了。
其他的参考资料(未找到原文,所以文中提供的dll链接库无法下载,可以直接下载github上的代码)
REF: http://blog.sina.com.cn/s/blog_622bd1660100rk1r.html
REF: http://apps.hi.baidu.com/share/detail/16966435
代码在gitHub的下载地址: https://github.com/jia1546/content-extraction