2008年7月31日
内容如下:
Code
<script>
setInterval( function() {
var date = new Date();
if (date.getMinutes() == 0 || date.getMinutes() == 30) {
alert("老大,喝点水,休息一下!");
}
}, 1000 * 60);
</script>
大家注意身体啊
--------------------------
09博客园纪念T恤新闻:
网站评测:搜狐博客 VS 我烧网网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/08/25/1553578.html
posted @
2009-08-25 13:33 破名超难起 阅读(151) |
评论 (0) |
编辑 收藏
防盗链原理:
http标准协议中有专门的字段记录referer
一来可以追溯上一个入站地址是什么
二来对于资源文件,可以跟踪到包含显示他的网页地址是什么。
因此所有防盗链方法都是基于这个Referer字段
网上比较多的2种
一种是使用apache文件FileMatch限制,在httpd.conf中增加 ( 其实也可以将把下面的语句存成一个.htaccess文件),并放到你的网站的根目录(就是www/html目录),这样子别人就没有办法盗连你的东东了~~
SetEnvIfNoCase Referer "^http://yahoo.com/" local_ref=1
Order Allow,Deny
Allow from env=local_ref
Allow from 127.0.0.1
这种很方便禁止非允许访问URL引用各种资源文件
请大家注意,把第一句"^http://yahoo.com/"改为你的网站,比如我的网站是: http://www.linji.cn
我应该这么写的
"^http://www.linji.cn/"
第二种是使用rewrite,需要增加apache的mode_rewrite,支持.htaccess文件目录权限限制
在虚拟主机根目录增加.htaccess文件,描述从定向,把非本地地址refer的图片文件都从定向到警告图片或者警告网页上。
首先要确认你的服务器或空间的服务器解译引擎为Apache2,还有支持.htaccess客户设置文件,
如果你有自己的服务器就请先对./conf/httpd.conf 文件做以下修改
找到:#LoadModule rewrite_module modules/mod_rewrite.so
把前面的 # 给去丢
找到等一个 AllowOverride None 改为 AllowOverride All
重启Apache2服务器
接下就是做一个 .htaccess 文件了,其 .htaccess 文件内容为
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://aaoo.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://aaoo.net$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.aaoo.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.aaoo.net$ [NC]
RewriteRule .*.(jpg|jpeg|gif|png|bmp|rar|zip|exe)$ http://down.yoyo.com.ru/err.html [R,NC]
其中有色的地方都是要改为你的:
红色:就是改为你提供下载页面的地址,也就是只有通过这个地址才可以下载你所提供的东东。
蓝色:就是要保护文件的扩展名(以|分开),也就是说以这些为扩展名的文件只有通过红色的地址才可以访问。
绿色:如果不是通过红色的地址访问蓝色这些为扩展名的文件时就回重定向到绿色地址上。
这个方法有个好处是,不同的虚拟主机用不同的描述定义。
接下就是怎么用 .htaccess 文件来实现防盗链了。
首先要在空间上建两个目录(当然目录名随你),一个为 web 另一个为 down ,
web 是用来放下载页面的(或下载程序),down 当然就是放你提供的东东的啦,
把 .htaccess 文件的红色部分改一下,改为http://你的域名/web。蓝色部分
改为你要保护文件的扩展名。绿色部分改为http://你的域名/web。改后保存
.htaccess 文件把它上传到 down 目录。
还有第三种:
我在解决plog禁止盗链的时候,发现个问题,也算个好方法。
plog把所有资源都自己管理起来,用resserver.php来动态显示,这样统一的入口方便添加权限操作。
同时造成上面2种方法无法使用,因为不再是apache直接访问资源文件,而是php通过文件读取。
因此只能在代码中做手脚:在读取资源文件输出之前,加如下判断代码
引用
$referer = $_SERVER['HTTP_REFERER'];
$selfurl = $_SERVER['HTTP_HOST'];
if(false == strpos($referer,$selfurl))
{
echo '非法盗链!';
exit(1);
}
这里有些偷懒,直接看引用地址中是否包含host地址,不过原理就是这样,判断referer是否是本站地址。
我们常常在下载的时候,也碰到盗链网站无法下载,报盗链的问题。要下载这类文件最简单的方法就是改referer
比方flashget中,网址下面的"引用"一栏中,直接填写下载地址就可以了。
--------------------------
09博客园纪念T恤新闻:
微软:不一样的PowerPoint 2010网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/08/21/1551756.html
posted @
2009-08-21 23:30 破名超难起 阅读(326) |
评论 (0) |
编辑 收藏
这两天完善了一下视频转换这个东西,以前做的那套东西上传完之后就开始转换,无法适应大并发量下的视频转换(我觉得同时有10个ffmpeg进程在转视频服务器肯定要挂掉),所以我用了另一套方案,视频上传之后先不转换,把视频的基本信息存到数据库中,然后由程序定时的从数据库中读取数据,依次转换视频。具体做法是:1、上传文件,将文件名存入数据库,同时在数据库标明videostat字段为0(表示未转换)
2、通过程序,每隔30秒(根据不同情况可以改变)取出一个未转换(videostat=0)且失败次数小于5(confailtime<5)的纪录
3、开始转换视频,这里要先将数据库中videostat字段改为2(表示正在转换)不然30秒钟转换不完下个进程又会读到这条纪录开始转换......
4、等待转换进程结束,如果成功将相应纪录的videostat字段的值改为1(表示转换成功),若转换失败则将失败次数字段加一(confailtime=confailtime+1)
在鼓捣这东西的过程中,遇到了一个问题,如果一个进程先执行p.waitFor();方法而后输出命令行中的结果是不行的,即:
Code
int flag = p.waitFor();
InputStream inErr = p.getErrorStream();
InputStream inIns = p.getInputStream();
BufferedReader brErr = new BufferedReader(new InputStreamReader(
inErr));
BufferedReader brIns = new BufferedReader(new InputStreamReader(
inIns));
// inErr读取输出信息开始
String strsErr = "";
String strErr = brErr.readLine();
while (strErr != null) {
strsErr = strsErr + strErr + "\n";
System.out.println(strErr);
strErr = brErr.readLine();
}
// inErr读取输出信息结束
// inIns读取输出信息开始
String strsIns = "";
String strIns = brIns.readLine();
while (strIns != null) {
strsIns = strsIns + strIns + "\n";
System.out.println(strIns);
strIns = brErr.readLine();
}
如果这样执行的话进程会挂起,无法继续下午,而正确的方法是先读取命令行的数据,再来waitFor();
还有一点需要注意的是获得命令行的输出结果先要从错误流中获得,即(ErrorStream),而非从输入流(InputStream)中获得,很有用的经验。
--------------------------
09博客园纪念T恤新闻:
自由软件基金会列举Windows 7之七宗罪网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/08/04/1538824.html
posted @
2009-08-04 17:45 破名超难起 阅读(265) |
评论 (0) |
编辑 收藏
很久不在这里发帖子了,最近在家闲来无事,想到转视频的那东西又要做了,遂翻出以前的帖子,看到一年前丰哥让我做一下文件上传的进度条....额~~那就做一下吧。
东西很简单,主要用到commons-fileupload,其中有一个progressListener的接口,该接口可以实现实时更新已上传文件的大小,有了这个还说什么呢?
给出代码
代码
package lc.progress;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import lc.progress.vo.fileUploadStatus;
import org.apache.commons.fileupload.ProgressListener;
public class myProgressListener implements ProgressListener {
private HttpSession session;
public myProgressListener(HttpServletRequest req) {
session=req.getSession();
fileUploadStatus status = new fileUploadStatus();
session.setAttribute("status", status);
}
/* pBytesRead 到目前为止读取文件的比特数
* pContentLength 文件总大小
* pItems 目前正在读取第几个文件
* 只要在session中实时保存文件上传的状态(这里我用fileUploadStatus类来封装)
*/
public void update(long pBytesRead, long pContentLength, int pItems) {
// TODO Auto-generated method stub
fileUploadStatus status = (fileUploadStatus) session.getAttribute("status");
status.setPBytesRead(pBytesRead);
status.setPContentLength(pContentLength);
status.setPItems(pItems);
}
}
然后在上传得servlet或action中加入这样一段代码,就可以把自定义的progressListener添加进去
代码
myProgressListener getBarListener = new myProgressListener(req);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(getBarListener);
最后就是通过js来不断的访问另一个servlet来实时返回上传状态就可以了,限于篇幅我就不再贴代码了,有兴趣的读者可以自己下载来看。
代码下载(目标另存为就行了)
--------------------------
09博客园纪念T恤新闻:
网速调查报告:韩国互联网网速全球居首网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/08/03/1537870.html
posted @
2009-08-03 19:46 破名超难起 阅读(4886) |
评论 (7) |
编辑 收藏
http://family168.com/oa/springsecurity/html/index.html
posted @
2009-07-19 18:28 破名超难起 阅读(195) |
评论 (0) |
编辑 收藏
package lc.util;
import java.math.BigDecimal;
public class MathHelper {
private static final int DEF_DIV_SCALE = 10;
private MathHelper() {
}
/**
* 提供精确的加法运算。
*
* @param v1
* 被加数
* @param v2
* 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param v1
* 被减数
* @param v2
* 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
*
* @param v1
* 被乘数
* @param v2
* 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
*
* @param v1
* 被除数
* @param v2
* 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
*
* @param v1
* 被除数
* @param v2
* 除数
* @param scale
* 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
*
* @param v
* 需要四舍五入的数字
* @param scale
* 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
--------------------------
09博客园纪念T恤新闻:
王建宙台湾布道TD:痛快,一起努力的感觉网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/05/20/1469589.html
posted @
2009-05-20 17:13 破名超难起 阅读(305) |
评论 (0) |
编辑 收藏
import java.sql.*;
public class Access
{
public static void main(String args[])
{
try
{
String strurl="jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=books.mdb";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn=DriverManager.getConnection(strurl) ;
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery("select * from books");
if(rs.next())
{
System.out.println(rs.getString("简介"));
}
}catch(Exception e)
{
System.out.println(e);
}
}
}
--------------------------
09博客园纪念T恤新闻:
微软正式对Word禁售令提起上诉 称法官不懂法网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/05/08/1452661.html
posted @
2009-05-08 15:08 破名超难起 阅读(176) |
评论 (0) |
编辑 收藏
又一个新闻发布......比以前的更加人性化了,用到了Struts2、Struts2的JSON插件,前台js用了Jquery库,自己看吧。欢迎大家提出自己的宝贵意见。
关于显示新闻的功能我还没有找到一个合适的AJAX表现形式,所以还没有完成,欢迎大家给我个建议
点击下载源码
--------------------------
09博客园纪念T恤新闻:
IBM 2009年北美裁员近1万人网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2009/03/16/1413631.html
posted @
2009-03-16 17:48 破名超难起 阅读(192) |
评论 (0) |
编辑 收藏
最近搞的一个通讯录想要加一个Ajax的自动完成功能,看起来功能虽小,可给用户的体验会改进不少。在一个介绍了几十种java的Ajax框架的网页里面,我找到了AjaxTags这个小东西,开始了我的第一次Ajax之旅。
从AjaxTags的官方网站上面http://ajaxtags.sourceforge.net/可以下载到其最新的版本,目前是AjaxTags1.3顺便下载了一个官方的小例子看了看,确实很好阿,例子中使用Ajax完成了11种功能,然而我需要的是自动完成(autocomplete)部分的代码,所以重点研究这一部分
jsp页面中,首先当然是要添加AjaxTags的标签支持,需要如下语句
Code
<%@ taglib uri="http://ajaxtags.org/tags/ajax" prefix="ajax"%>
然后在页面中加入如下的标签
Code
<ajax:autocomplete
source="model"//从控件"model"中获得输入的字符
target="make"//通过Ajax自动完成控件"make"的内容
baseUrl="${contextPath}/autocomplete.view"//Ajax执行时调用的请求路径
className="autocomplete"//css类名
indicator="indicator"
minimumCharacters="1"//Ajax执行需要输入的最小字符数
/>
在官方的例子中使用的是Servlet来完成Ajax,而对于使用struts就不适用了,后面说这个问题。
在 autocomplete.view对应的Servlet类中需要建立xml来供页面调取,代码如下
Code
public class AutocompleteServlet extends BaseAjaxServlet {
public String getXmlContent(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String model = request.getParameter("model");//从页面获取控件"model"的输入值
CarService service = new CarService();
List<Car> list = service.getModelsByName(model);//调用CarService的方法获得汽车的List
// Create xml schema
return new AjaxXmlBuilder().addItems(list, "model", "make",true).toString();//生成xml
}
}
其实还是很简单的,接下来看CarService的代码吧,重点其实只有一段,然后在下面显示出自动提示,于是可以把刚才的那个ajax标签修改如下
Code
public class CarService {
private static List<Car> cars = new ArrayList<Car>();
static {
cars.add(new Car("Ford", "Escape"));
cars.add(new Car("Ford", "Expedition"));
cars.add(new Car("Ford", "Explorer"));
cars.add(new Car("Ford", "Focus"));
cars.add(new Car("Ford", "Mustang"));
cars.add(new Car("Ford", "Thunderbird"));
cars.add(new Car("Honda", "Accord"));
cars.add(new Car("Honda", "Civic"));
cars.add(new Car("Honda", "Element"));
cars.add(new Car("Honda", "Ridgeline"));
cars.add(new Car("Mazda", "Mazda 3"));
cars.add(new Car("Mazda", "Mazda 6"));
cars.add(new Car("Mazda", "RX-8"));
}//其实把上面这个地方改为数据库查询就可以从数据库中得到List来供页面显示
public CarService() {
super();
}
public List<Car> getModelsByMake(String make) {
.
}
public List<Car> getModelsByName(String name) {
..
}
public List<Car> getAllCars() {
return cars;
}
}
例子看完了,开始实际操作吧,在我的页面中,需要通过一个名为"name"的文本框输入要查询的人的姓名
Code
<ajax:autocomplete
source="name"
target="name"
baseUrl="ajaxfinduser.do"
className="autocomplete"
indicator="indicator"
minimumCharacters="1"
/>
接下来是我的Action,在写Action的时候,我以为只需要把原来Servlet继承的BaseAjaxServlet改为BaseAjaxAction就可以了,可后来才发现,jar包中根本就没有BaseAjaxAction这个类,无语,去官方网站上看了后才知道,在1.2更新到1.3的时候,把对Struts的支持去掉了,如果想支持Struts的话需要建立自己的BaseAjaxAction
(Struts removed, to use it create your own BaseAjaxAction.java and implement BaseAjaxXmlAction then just call xml = AjaxActionHelper.invoke(this, request, response);)
下载了一份AjaxTags的源码来看,原来AjaxActionHelper.invoke();这个方法需要调用Action中的getXmlContent方法来完成xml的写入,那就好说了,代码如下:
Code
package com.txl.action;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ajaxtags.servlets.BaseAjaxXmlAction;
import org.ajaxtags.xml.AjaxXmlBuilder;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ajaxtags.servlets.AjaxActionHelper;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.txl.service.AjaxFindUserService;
import com.vo.User;
public class AjaxFindUserAction extends Action implements BaseAjaxXmlAction {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, Exception {
response.setCharacterEncoding("utf-8");
response.getOutputStream().print(new String(AjaxActionHelper.invoke(this, request, response).getBytes("UTF-8"),"ISO-8859-1"));//这里需要转换编码,不然无法支持中文查询
response.getOutputStream().flush();
return null;
}
public String getXmlContent(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String realname = request.getParameter("name");
ApplicationContext ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(servlet.getServletContext());//用ssh时需要在这里引入spring的配置文件,不然会在调用dao的时候报空指针异常
AjaxFindUserService service = (AjaxFindUserService) ctx
.getBean("AjaxFindUserService");
List<User> list = service.getUsersByRealname(realname);
return new AjaxXmlBuilder()
.addItems(list, "realname", "realname", true).toString();
}
}
剩下工作就是在struts-config.xml中配置对应的action,在spring中配置对应的bean就ok拉
--------------------------
09博客园纪念T恤新闻:
Office 2010双拳出击加强反盗版网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/09/22/1295661.html
posted @
2008-09-22 09:42 破名超难起 阅读(200) |
评论 (0) |
编辑 收藏
我一直有通宵下东西的习惯,可又不忍心让笔记本下载完成后一直等到我睡醒,所以我经常用迅雷给我们提供的下载完成后自动关机这个功能。
然而现在迅雷运行在了虚拟机里面,这就郁闷了,即使自动关机也只能关掉一个虚拟机的进程,无奈我想到可不可以用shell程序来监测虚拟机的进程,当他关闭后就运行关机的命令,经过测试,果然成功了,具体代码如下:
Code
#!/bin/bash
while [ `pidof -s $1` ]
do
sleep 2 #&& echo "ok"
done
date
echo "Done..shuting down in 60 seconds." && sleep 60
shutdown -h -P now
将代码保存在shutdown.sh文件中
使用起来也很方便,用"ps ux"找到vbox运行的进程,将其对应的time command值作为参数输入进来,例如我的是:
lichao 10659 91.7 52.0 1224284 1079860 ? Sl 21:49 11:01 /opt/VirtualBox-1.6.4/VirtualBox -comment winxp -startvm 5e04c66f-82f7-4df0-0f92-8b9113be6f2
则执行上述脚本文件:
./ shutdown.sh /opt/VirtualBox-1.6.4/VirtualBox -comment winxp -startvm 5e04c66f-82f7-4df0-0f92-8b9113be6f2
监测开始
当虚拟机关机后命令行出现如下提示:
Done..shuting down in 60 seconds.
60秒后就会关机拉,如果你还不想关机,可以Ctrl+Alt+C停止当前任务,再进行其他操作,怎么样,挺好使的
--------------------------
09博客园纪念T恤新闻:
中国联通:国际通讯已恢复至震前水平网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/21/1273554.html
posted @
2008-08-21 22:25 破名超难起 阅读(506) |
评论 (0) |
编辑 收藏
查看软件xxx安装内容
查找软件
查找文件属于哪个包
- dpkg -S filename
apt-file search filename
查询软件xxx依赖哪些包
查询软件xxx被哪些包依赖
增加一个光盘源
系统升级
- sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
清除所以删除包的残余配置文件
- dpkg -l |grep ^rc|awk '{print $2}' |tr ["n"] [" "]|sudo xargs dpkg -P -
编译时缺少h文件的自动处理
- sudo auto-apt run ./configure
查看安装软件时下载包的临时存放目录
- ls /var/cache/apt/archives
备份当前系统安装的所有包的列表
- dpkg --get-selections | grep -v deinstall > ~/somefile
从上面备份的安装包的列表文件恢复所有包
- dpkg --set-selections < ~/somefile
sudo dselect
清理旧版本的软件缓存
清理所有软件缓存
删除系统不再使用的孤立软件
查看包在服务器上面的地址
- apt-get -qq --print-uris install ssh | cut -d' -f2
系统 查看内核
查看Ubuntu版本
查看内核加载的模块
查看PCI设备
查看USB设备
查看网卡状态
查看CPU信息
显示当前硬件信息
硬盘 查看硬盘的分区
查看IDE硬盘信息
查看STAT硬盘信息
- sudo hdparm -I /dev/sda
或
sudo apt-get install blktool
sudo blktool /dev/sda id
查看硬盘剩余空间
查看目录占用空间
优盘没法卸载
- sync
fuser -km /media/usbdisk
内存 查看当前的内存使用情况
进程 查看当前有哪些进程
中止一个进程
- kill 进程号(就是ps -A中的第一列的数字)
或者 killall 进程名
强制中止一个进程(在上面进程中止不成功的时候使用)
- kill -9 进程号
或者 killall -9 进程名
图形方式中止一个程序
- xkill 出现骷髅标志的鼠标,点击需要中止的程序即可
查看当前进程的实时状况
查看进程打开的文件
ADSL 配置 ADSL
ADSL手工拨号
激活 ADSL
- sudo /etc/ppp/pppoe_on_boot
断开 ADSL
查看拨号日志
如何设置动态域名
- #首先去 http://www.3322.org 申请一个动态域名
#然后修改 /etc/ppp/ip-up 增加拨号时更新域名指令
sudo vim /etc/ppp/ip-up
#在最后增加如下行
w3m -no-cookie -dump 'http://username:password@members.3322.org/dyndns/update?system=dyndns&hostname=yourdns.3322.org'
网络 根据IP查网卡地址
查看当前IP地址
- ifconfig eth0 |awk '/inet/ {split($2,x,":");print x[2]}'
查看当前外网的IP地址
- w3m -no-cookie -dump www.ip138.com|grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}'
w3m -no-cookie -dump www.123cha.com|grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}'
w3m -no-cookie -dump ip.loveroot.com|grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}'
查看当前监听80端口的程序
查看当前网卡的物理地址
- arp -a | awk '{print $4}'
ifconfig eth0 | head -1 | awk '{print $5}'
立即让网络支持nat
- echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
sudo iptables -t nat -I POSTROUTING -j MASQUERADE
查看路由信息
- netstat -rn
sudo route -n
手工增加删除一条路由
- sudo route add -net 192.168.0.0 netmask 255.255.255.0 gw 172.16.0.1
sudo route del -net 192.168.0.0 netmask 255.255.255.0 gw 172.16.0.1
修改网卡MAC地址的方法
- sudo ifconfig eth0 down #关闭网卡
sudo ifconfig eth0 hw ether 00:AA:BB:CC:DD:EE #然后改地址
sudo ifconfig eth0 up #然后启动网卡
统计当前IP连接的个数
- netstat -na|grep ESTABLISHED|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -r -n
netstat -na|grep SYN|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -r -n
统计当前20000个IP包中大于100个IP包的IP地址
- tcpdump -tnn -c 20000 -i eth0 | awk -F "." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr | awk ' $1 > 100 '
屏蔽IPV6
- echo "blacklist ipv6" | sudo tee /etc/modprobe.d/blacklist-ipv6
服务 添加一个服务
- sudo update-rc.d 服务名 defaults 99
删除一个服务
- sudo update-rc.d 服务名 remove
临时重启一个服务
临时关闭一个服务
临时启动一个服务
设置 配置默认Java使用哪个
- sudo update-alternatives --config java
修改用户资料
给apt设置代理
- export http_proxy=http://xx.xx.xx.xx:xxx
修改系统登录信息
中文 转换文件名由GBK为UTF8
- sudo apt-get install convmv
convmv -r -f cp936 -t utf8 --notest --nosmart *
批量转换src目录下的所有文件内容由GBK到UTF8
- find src -type d -exec mkdir -p utf8/{} ;
find src -type f -exec iconv -f GBK -t UTF-8 {} -o utf8/{} ;
mv utf8/* src
rm -fr utf8
转换文件内容由GBK到UTF8
- iconv -f gbk -t utf8 $i > newfile
转换 mp3 标签编码
- sudo apt-get install python-mutagen
find . -iname “*.mp3” -execdir mid3iconv -e GBK {} ;
控制台下显示中文
- sudo apt-get install zhcon
使用时,输入zhcon即可
文件 快速查找某个文件
- whereis filename
- find 目录 -name 文件名
查看文件类型
显示xxx文件倒数6行的内容
让tail不停地读地最新的内容
- tail -n 10 -f /var/log/apache2/access.log
查看文件中间的第五行(含)到第10行(含)的内容
- sed -n '5,10p' /var/log/apache2/access.log
查找包含xxx字符串的文件
查找关于xxx的命令
通过ssh传输文件
- scp -rp /path/filename username@remoteIP:/path #将本地文件拷贝到服务器上
scp -rp username@remoteIP:/path/filename /path #将远程文件从服务器下载到本地
查看某个文件被哪些应用程序读写
把所有文件的后辍由rm改为rmvb
把所有文件名中的大写改为小写
删除特殊文件名的文件,如文件名:--help.txt
- rm -- --help.txt 或者 rm ./--help.txt
查看当前目录的子目录
将当前目录下最近30天访问过的文件移动到上级back目录
- find . -type f -atime -30 -exec mv {} ../back ;
将当前目录下最近2小时到8小时之内的文件显示出来
- find . -mmin +120 -mmin -480 -exec more {} ;
删除修改时间在30天之前的所有文件
- find . -type f -mtime +30 -mtime -3600 -exec rm {} ;
查找guest用户的以avi或者rm结尾的文件并删除掉
- find . -name '*.avi' -o -name '*.rm' -user 'guest' -exec rm {} ;
查找的不以java和xml结尾,并7天没有使用的文件删除掉
- find . ! -name *.java ! -name ‘*.xml’ -atime +7 -exec rm {} ;
统计当前文件个数
统计当前目录个数
- ls -l /usr/bin|grep ^d|wc -l
显示当前目录下2006-01-01的文件名
- ls -l |grep 2006-01-01 |awk '{print $8}'
压缩 解压缩 xxx.tar.gz
解压缩 xxx.tar.bz2
压缩aaa bbb目录为xxx.tar.gz
- tar -zcvf xxx.tar.gz aaa bbb
压缩aaa bbb目录为xxx.tar.bz2
- tar -jcvf xxx.tar.bz2 aaa bbb
Nautilus 显示隐藏文件
显示地址栏
特殊 URI 地址
- * computer:/// - 全部挂载的设备和网络
* network:/// - 浏览可用的网络
* burn:/// - 一个刻录 CDs/DVDs 的数据虚拟目录
* smb:/// - 可用的 windows/samba 网络资源
* x-nautilus-desktop:/// - 桌面项目和图标
* file:/// - 本地文件
* trash:/// - 本地回收站目录
* ftp:// - FTP 文件夹
* ssh:// - SSH 文件夹
* fonts:/// - 字体文件夹,可将字体文件拖到此处以完成安装
* themes:/// - 系统主题文件夹
查看已安装字体
- 在nautilus的地址栏里输入”fonts:///“,就可以查看本机所有的fonts
程序 详细显示程序的运行信息
- strace -f -F -o outfile <cmd>
日期和时间 设置日期
设置时间
将时间写入CMOS
读取CMOS时间
从服务器上同步时间
- sudo ntpdate time.nist.gov
sudo ntpdate time.windows.com
控制台 不同控制台间切换
- Ctrl + ALT + ←
Ctrl + ALT + →
指定控制台切换
控制台下滚屏
控制台抓图
数据库 mysql的数据库存放在地方
从mysql中导出和导入数据
- mysqldump 数据库名 > 文件名 #导出数据库
mysqladmin create 数据库名 #建立数据库
mysql 数据库名 < 文件名 #导入数据库
忘了mysql的root口令怎么办
- sudo /etc/init.d/mysql stop
sudo mysqld_safe --skip-grant-tables &
sudo mysqladmin -u user password 'newpassword''
sudo mysqladmin flush-privileges
修改mysql的root口令
- sudo mysqladmin -uroot -p password '你的新密码'
其它 下载网站文档
- wget -r -p -np -k http://www.21cn.com
· -r:在本机建立服务器端目录结构;
· -p: 下载显示HTML文件的所有图片;
· -np:只下载目标站点指定目录及其子目录的内容;
· -k: 转换非相对链接为相对链接。
如何删除Totem电影播放机的播放历史记录
如何更换gnome程序的快捷键
- 点击菜单,鼠标停留在某条菜单上,键盘输入任意你所需要的键,可以是组合键,会立即生效;
如果要清除该快捷键,请使用backspace
vim 如何显示彩色字符
- sudo cp /usr/share/vim/vimcurrent/vimrc_example.vim /usr/share/vim/vimrc
如何在命令行删除在会话设置的启动程序
- cd ~/.config/autostart
rm 需要删除启动程序
如何提高wine的反应速度 sudo sed -ie '/GBK/,/^}/d' /usr/share/X11/locale/zh_CN.UTF-8/XLC_LOCALE
--------------------------
09博客园纪念T恤新闻:
分析称RSS阅读器是Web 1.0工具 已逐渐被抛弃网站导航:
博客园首页 个人主页 新闻 社区 博问 闪存 找找看文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/20/1272372.html
posted @
2008-08-20 16:27 破名超难起 阅读(125) |
评论 (0) |
编辑 收藏
Hibernate获取数据的方式有不同的几种,其与缓存结合使用的效果也不尽相同,而Hibernate中具体怎么使用缓存其实是我们很关心的一个问题,直接涉及到性能方面。
缓 存在Hibernate中主要有三个方面:一级缓存、二级缓存和查询缓存;一级缓存在Hibernate中对应的即为session范围的缓存,也就是当 session关闭时缓存即被清除,一级缓存在Hibernate中是不可配置的部分;二级缓存在Hibernate中对应的即为 SessionFactory范围的缓存,通常来讲SessionFactory的生命周期和应用的生命周期相同,所以可以看成是进程缓存或集群缓存,二 级缓存在Hibernate中是可以配置的,可以通过class-cache配置类粒度级别的缓存(class-cache在class中数据发生任何变 化的情况下自动更新),同时也可通过collection-cache配置集合粒度级别的缓存(collection-cache仅在 collection中增加了元素或者删除了元素的情况下才自动更新,也就是当collection中元素发生值的变化的情况下它是不会自动更新的),缓 存自然会带来并发的访问问题,这个时候相应的就要根据应用来设置缓存所采用的事务隔离级别,和数据库的事务隔离级别概念基本一样,没什么多介绍的, ^_^;查询缓存在Hibernate同样是可配置的,默认是关闭的,可以通过设置cache.use_ query_cache为true来打开查询缓 存。根据缓存的通常实现策略,我们可以来理解Hibernate的这三种缓存,缓存的实现通过是通过key/value的Map方式来实现,在 Hibernate的一级、二级和查询缓存也同样如此,一级、二级缓存使用的key均为po的主键ID,value即为po实例对象,查询缓存使用的则为 查询的条件、查询的参数、查询的页数,value有两种情况,如果采用的是select po.property这样的方式那么value为整个结果集,如采用的是from这样的方式那么value为获取的结果集中各po对象的主键ID,这样 的作用很明显,节省内存,^_^
简单介绍完Hibernate的缓存后,再结合Hibernate的获取数据方式来说明缓存的具体使用方式,在Hibernate中获取数据常用的方式主要有四种:Session.load、Session.get、Query.list、Query.iterator。
1、Session.load
在执行session.load时,Hibernate首先从当前session的一级缓存中获取id对应的值,在获取不到的情况下,将根据该对象是否配 置了二级缓存来做相应的处理,如配置了二级缓存,则从二级缓存中获取id对应的值,如仍然获取不到则还需要根据是否配置了延迟加载来决定如何执行,如未配 置延迟加载则从数据库中直接获取,在从数据库获取到数据的情况下,Hibernate会相应的填充一级缓存和二级缓存,如配置了延迟加载则直接返回一个代 理类,只有在触发代理类的调用时才进行数据库查询的操作。
在这样的情况下我们就可以看到,在session一直打开的情况下,要注意在适当的时候对一级缓存进行刷新操作,通常是在该对象具有单向关联维护的时候, 在Hibernate中可以使用象session.clear、session.evict的方式来强制刷新一级缓存。
二级缓存则在数据发生任何变化(新增、更新、删除)的情况下都会自动的被更新。
2、Session.get
在执行Session.get时,和Session.load不同的就是在当从缓存中获取不到时,直接从数据库中获取id对应的值。
3、Query.list
在执行Query.list时,Hibernate的做法是首先检查是否配置了查询缓存,如配置了则从查询缓存中查找key为查询语句+查询参数+分页条 件的值,如获取不到则从数据库中进行获取,从数据库获取到后Hibernate将会相应的填充一级、二级和查询缓存,如获取到的为直接的结果集,则直接返 回,如获取到的为一堆id的值,则再根据id获取相应的值(Session.load),最后形成结果集返回,可以看到,在这样的情况下,list也是有 可能造成N次的查询的。
查询缓存在数据发生任何变化的情况下都会被自动的清空。
4、Query.iterator
在执行Query.iterator时,和Query.list的不同的在于从数据库获取的处理上,Query.iterator向数据库发起的是 select id from这样的语句,也就是它是先获取符合查询条件的id,之后在进行iterator.next调用时才再次发起session.load的调用获取实 际的数据。
可见,在拥有二级缓存并且查询参数多变的情况下,Query.iterator会比Query.list更为高效。
这 四种获取数据的方式都各有适用的场合,要根据实际情况做相应的决定,^_^,最好的方式无疑就是打开show_sql选项看看执行的情况来做分析,系统结 构上只用保证这种调整是容易实现的就好了,在cache这个方面的调整自然是非常的容易,只需要调整配置文件里的设置,而查询的方式则可对外部进行屏蔽, 这样要根据实际情况调整也非常容易。
推荐三篇关于Hibernate缓存机制介绍的文章:
http://gocom.primeton.com/blog/index.php?op=ViewArticle&articleId=467&blogId=37&src=jdon&srcforum=62
http://club.gamvan.com/club/clubPage.jsp?ccStyle=0&tID=10456&ccID=37
http://www.devx.com/dbzone/Article/29685/1954?pf=true文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/16/1269160.html
posted @
2008-08-16 11:03 破名超难起 阅读(81) |
评论 (0) |
编辑 收藏
虽然VirtualBox是个很好用的虚拟机,但是安装完成之后虚拟机仍然无法使用usb设备,没有声音还是需要作进一步配置的,下面是具体配置方法:
1、配置VirtualBox使其识别usb设备
如果不配置VirtualBox的话,每次虚拟机启动时他都会报错的,大体意思是当前虚拟机没有安装使用usb的服务
解决方法如下:
增加用户组usbfs
$ sudo groupadd usbfs
2. 查看usbfs用户组的gid
$ cat /etc/group | grep usbfs
usbfs:x:1002:
把当前用户增加到usbfs组
$ sudo gedit /etc/group
把
usbfs:x:1001:
修改为
usbfs:x:1001:lichao
4. 为USB设备重新设置权限编辑/etc/fstab文件,添加下面两行,注意你的gid可能不是1001
$ sudo gedit /etc/fstab
在末尾加上
# 1001 is the USB group IDI
none /proc/bus/usb usbfs devgid=1001,devmode=666 0 0
重新启动后,应该就可以在客户机中使用USB设备了。
方法:插入一个USB设备后,如U盘,右键点击虚拟机里右下脚的USB图标,选择已经识别的U盘,就可以正常使用了。
注意:(1)在客户机里使用USB设备前要先在主机里卸载。 (2)完成后重启系统
2、使虚拟机支持声音
使用了一段时间后,我突然发现虚拟机居然没有声音,而在操作系统中是有声卡的,而且右下角有调节声音的图标,应该有声音阿
经过仔细查找,我发现在虚拟机声音设置中,虽然控制芯片被设置为了“ICH AC97”,但是声卡类型却被设置为了Null Audio Driver,只要将声卡类型设置为OSS Audio Driver就可以了
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/15/1268427.html
posted @
2008-08-15 10:01 破名超难起 阅读(357) |
评论 (0) |
编辑 收藏
今天很郁闷阿,昨天刚装好的系统,今天就因为一次莫名的操作......重装了
装系统倒不是很费时间,麻烦的是等待系统升级,很郁闷阿,将近一小时,什么也作不了,所以这次重装之后,我决定找到一种一劳永逸的方法,备份升级文件,找了找,还真有,具体过程如下:
备份:
Code
tar cizvf backup.tar.gz /var/cache/apt/archives --exclude=/var/cache/apt/archives/partial/* --exclude=/var/cache/apt/archives/loc
备份成功,在你所对应的/home/user文件夹中可以找到这个名为backup.tar.gz的文件。
清除:
Code
sudo apt-get clean
rm -rf ~/.thumbnails/fail/gnome-thumbnail-factory/*
还原:
Code
sudo apt-get update && sudo tar xzvf backup.tar.gz -C /
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/13/1267439.html
posted @
2008-08-13 23:32 破名超难起 阅读(105) |
评论 (0) |
编辑 收藏
由于linux下没有像windows的ALL IN ONE安装包,而我又不想用eclipse+myeclipse的方式来安装,就在这时,我发现在myeclipse的官方网站上有一个安装包叫pulse
上网查了一下,这个安装包本身没有任何ide安张程序,他可以让你来选择哪些工具你需要下载安装,哪些你不需要,似乎很好用哦,下载下来试试。
装上之后,有很多ide提供下载安装,就选择我最熟悉的MyEclipse6.5吧,下载速度很快,不到10分钟就装好了,打开一看,和windows的界面一样,爽!!以后就用他了
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/12/1266299.html
posted @
2008-08-12 20:09 破名超难起 阅读(186) |
评论 (0) |
编辑 收藏
早就想把微软的东西仍进虚拟机,只是一直没下决心,这次实践了一回,呵呵,还真好使
我用的ubuntu 7.10+sun Virtual Box
去sun的官方网站下载吧,
VirtualBox-1.6.4-Linux_x86.run
这个是最新的,下载后照常安装,其间碰到几个依赖包的安装,在“新立得”里面找一下就好了....
5分钟后,虚拟机装好,开始装windows拉,用了许久的Vista,回顾一下经典的XP,哈哈,蛮不错的,感觉比纯运行xp还要快,一下是截图 :
这下爽拉,在linux下玩魔兽完全没难度拉
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/12/1266297.html
posted @
2008-08-12 20:00 破名超难起 阅读(201) |
评论 (0) |
编辑 收藏
首先去sun公司的网站下载jdk安装文件 jdk-x.bin不要下载jdk-x.rpm.bin,不知为什么装不上,
接下来在终端中执行
./jdk-x.bin
看过协议后键入"yes"同意许可
安装完成后需要修改环境变量
在终端中输入:
gksu gedit /etc/profile
在文件末尾加上如下几句话即可:
#set java environment
JAVA_HOME=/home/lichao/Program_File/jdk
export JRE_HOME=/home/lichao/Program_File/jdk/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
javac一下试试看,应该没问题了
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/12/1266215.html
posted @
2008-08-12 17:48 破名超难起 阅读(83) |
评论 (0) |
编辑 收藏
在终端中键入
sudo apt-get install mysql-server
ok,等一会吧,设置一下root的密码,
安装成功,简单吧,哈哈!!
安装完后最要命的是.....不知道mysql安装到那里了,网上找到了答案,若干个目录阿
ubuntu下mysql安装布局:
/usr/bin 客户端程序和mysql_install_db
/db 数据库和日志文件(自定义的)
/var/run mysqld 服务器
/etc/mysql mysql 配置文件my.cnf
/usr/share/mysql 字符集,基准程序和错误消息
/etc/init.d/mysql 启动mysql服务器
成功后在“系统 -> 系统管理 -> 服务”就可以看到mysql的服务了。
下面要配置了!
mysql默认只能在本机登录,这时就需要设置一下了
在终端中输入
mysql -u root -p
输入正确密码后执行如下sql语句:
- mysql -u root -pvmwaremysql>use mysql;
- mysql>update user set host = '%' where user = 'root';
- mysql>select host, user from user;
可以了,试试看吧!
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/12/1266213.html
posted @
2008-08-12 17:40 破名超难起 阅读(187) |
评论 (0) |
编辑 收藏
这里的方法同样适用于Debian下的Scim输入法的安装。
根据SCIM的文档说明,装SCIM最好用UTF-8的locale。(你也可以使用GB2312以及GBK的locale,使用scim都一样的)
对于一个新装好的没有安装SCIM的Ubuntu系统(新的Ubuntu安装器选择中文安装后,一边都已经装好了scim),只要
apt-get install scim(当然前提是你要设置好源,具体见http://wiki.ubuntu.org.cn/%E5%BF%AB%E9%80%9F%E8%AE%BE%E7%BD%AE%E6%8C%87%E5%8D%97, 有些高校自己内部也有源的,好好找找)
就已经安装好SCIM了!当然还不能用。因为SCIM只是一个输入法平台,还要在上面安装输入法(或者码表)。例如,
apt-get install scim-chinese
就可以使用智能拼音输入法了!当然在使用之前还要先配置一下,配置方法很简单,在/etc/X11/Xsession.d/里新建一个名叫95xinput的文件,文件内容如下
/usr/bin/scim -d
XMODIFIERS="@im=SCIM"
export XMODIFIERS
export GTK_IM_MODULE=scim
保存文件,确认内容无误后,退出X(建议退出X后运行exit命令重新login一次),再进入X的时候就可以用Ctrl+Space调出SCIM了!
就我的试验情况,这样已经可以在qterm里使用SCIM了。
如果你需要其它中文输入法,可以这样
apt-get install scim-tables-zh
这包括了简体中文的五笔、二笔、广东拼音、自然码,和繁体中文的行列、 }頡五代、大易、注音等输入法了。
我现在使用五笔输入法,能输入简繁汉字,词汇也丰富,很好用。
但是现在还不能在基于GTK的软件中调出SCIM,例如我就不能在leafpad里使用SCIM。解决办法很简单,只要安装scim-gtk2-immodule就可以了。
apt-get install scim-gtk2-immodule
安装后无须重启X,只要重新打开基于GTK的软件就可以了,比如我新开一个leafpad,马上就可以使用SCIM了!
这个命令会根据依赖关系自动安装 scim-server-socket, scim-frontend-socket, scim-config-socket,如果没有安装scim,也会自动安装。
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/12/1265876.html
posted @
2008-08-12 13:12 破名超难起 阅读(79) |
评论 (0) |
编辑 收藏
Code
import java.util.*;
import java.io.*;
import java.security.*;
public class MD5 {
public static String hex(byte[] array) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).toUpperCase().substring(1,3));
}
return sb.toString();
}
public static String md5 (String message) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");\\想用SHA加密的话就把MD5换成SHA吧
return hex (md.digest(message.getBytes("CP1252")));
} catch (NoSuchAlgorithmException e) {
} catch (UnsupportedEncodingException e) {
}
return null;
}
public static void main(String[] args) {
System.out.println (md5 ("LiChao"));
}
}
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/04/1260376.html
posted @
2008-08-04 20:25 破名超难起 阅读(110) |
评论 (0) |
编辑 收藏
经过若干天断断续续地研究,终于做出了第一个spring security的实例,真是艰难啊,配置太复杂了,若干个Bean之间存在着这样或那样的关系......
下面给出我的小例子,主要是配置文件拉~~别的东西自己看源码吧!
Code
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- 过滤器链配置,其中filterInvocationDefinitionSource属性为配置过滤器的种类与先后顺序,注意,顺序不能配置错误哦 -->
<bean id="filterChainProxy"
class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor]]>
</value>
</property>
</bean>
<!-- 看看你是否已经登录了,如果登录了就略过下面的过滤器了,直接访问资源 -->
<bean id="httpSessionIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />
<!-- 安全验证入口 -->
<bean id="authenticationEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/index.jsp" /><!--默认登录页面-->
<property name="forceHttps" value="true" /><!--使登录页面通过HTTPS安全地进行显示-->
</bean>
<!-- 身份验证过滤器,就是验证身份用的嘛 -->
<bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<!-- 验证连接名称,对应表单的action -->
<property name="filterProcessesUrl"
value="/j_spring_security_check" />
<!-- 验证失败后去哪 -->
<property name="authenticationFailureUrl"
value="/index.jsp?error=1" />
<!-- 验证成功后去哪 -->
<property name="defaultTargetUrl"
value="/security/security.jsp" />
<!--依靠一个身份验证管理器来验证身份 其实这个才是干活的BEAN-->
<property name="authenticationManager"
ref="authenticationManager" />
</bean>
<!-- 用于处理登录失败异常和权限不足异常 -->
<bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<!--配置出现exception时跳转到登录页-->
<property name="authenticationEntryPoint"
ref="authenticationEntryPoint" />
<!--配置403(权限不足)错误后跳转的页面-->
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<!-- 配置权限不足时跳转到的页面 -->
<bean id="accessDeniedHandler"
class="org.springframework.security.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/error.jsp" />
</bean>
<!-- 安全拦截器,下面看看它是干嘛的 -->
<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<!-- 验证管理者 -->
<property name="authenticationManager"
ref="authenticationManager" />
<!-- 权限决定管理者,他手下的一帮人投票决定登录者是否有权访问该资源 -->
<property name="accessDecisionManager"
ref="accessDecisionManager" />
<!--受保护资源-->
<property name="objectDefinitionSource">
<!-- 下面表示/security/security.jsp需要ROLE_ADMIN权限才能访问 -->
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/security/security.jsp=ROLE_ADMIN]]>
</value>
</property>
</bean>
<!-- 验证管理者,他管理DAO验证提供者来验证 -->
<bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<!-- DAO验证提供者,SPRING SECURITY支持各种验证,这里可以添加相应配置 -->
<ref local="daoAuthenticationProvider" />
</list>
</property>
</bean>
<!-- -->
<bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<!-- 如果所有投票者都弃权则不让访问 -->
<property name="allowIfAllAbstainDecisions">
<value>false</value>
</property>
<!-- 参加投票的BEAN -->
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter">
<!-- 权限的前缀 -->
<property name="rolePrefix" value="ROLE_" />
</bean>
<bean class="org.springframework.security.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<!-- DAO验证提供者依靠userDetailsService获得一个userDetails实例,进而验证权限 -->
<bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<!-- jdbcDaoImpl实现了userDetailsService接口 -->
<property name="userDetailsService">
<ref local="jdbcDaoImpl" />
</property>
</bean>
<bean id="jdbcDaoImpl"
class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
<!-- 根据用户名获得用户名、密码、用户是否启用等信息 -->
<property name="usersByUsernameQuery">
<value>
select username,password,enabled from user where
username=?
</value>
</property>
<!-- 通过用户名获取用户权限 -->
<property name="authoritiesByUsernameQuery">
<value>
select username,authority from authentication where
username=?
</value>
</property>
<!-- DataSource,不用我说了吧 -->
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="org.gjt.mm.mysql.Driver">
</property>
<property name="url" value="jdbc:mysql://localhost:3306/user">
</property>
<property name="username" value="root"></property>
<property name="password" value="hicc"></property>
</bean>
</beans>
这个是最简单的一个例子,配了141行,呼~~继续研究其深入功能,离成功越来越近了
ps.传说spring security2.0有了超级简单的配置方法,还没有学到手,努力ing
源码下载(需要自己添加spring和mysql的jar包)
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/04/1259523.html
posted @
2008-08-04 00:46 破名超难起 阅读(662) |
评论 (0) |
编辑 收藏
你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗?
Code
OutputStreamWriter out =
java.sql.Connection conn =
try { // ⑸
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(
"select uid, name from user");
while (rs.next())
{
out.println("ID:" + rs.getString("uid") // ⑹
",姓名:" + rs.getString("name"));
}
conn.close(); // ⑶
out.close();
}
catch(Exception ex) // ⑵
{
ex.printStackTrace(); // ⑴,⑷
}
作为一个Java程序员,你至少应该能够找出两个问题。但是,如果你不能找出全部六个问题,请继续阅读本文。
本文讨论的不是Java异常处理的一般性原则,因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”(anti-pattern)的违背优秀编码规范的常见坏习惯,帮助读者熟悉这些典型的反面例子,从而能够在实际工作中敏锐地察觉和避免这些问题。
反例之一:丢弃异常
代码:15行-18行。
这段代码捕获了异常却不作任何处理,可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看,它也许可以和C/C++程序的一个恶名远播的问题相提并论——不检查缓冲区是否已满。如果你看到了这种丢弃(而不是抛出)异常的情况,可以百分之九十九地肯定代码存在问题(在极少数情况下,这段代码有存在的理由,但最好加上完整的注释,以免引起别人误解)。
这段代码的错误在于,异常(几乎)总是意味着某些事情不对劲了,或者说至少发生了某些不寻常的事情,我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。不错,调用printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任了。
丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档,可以看到下面这段说明:“特别地,虽然出现ThreadDeath是一种‘正常的情形’,但ThreadDeath类是Error而不是Exception的子类,因为许多应用会捕获所有的Exception然后丢弃它不再理睬。”这段话的意思是,虽然ThreadDeath代表的是一种普通的问题,但鉴于许多应用会试图捕获所有异常然后不予以适当的处理,所以JDK把ThreadDeath定义成了Error的子类,因为Error类代表的是一般的应用不应该去捕获的严重问题。可见,丢弃异常这一坏习惯是如此常见,它甚至已经影响到了Java本身的设计。
那么,应该怎样改正呢?主要有四个选择:
1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。
2、重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。
3、把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。
4、不要捕获异常。
结论一:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。
反例之二:不指定具体的异常
代码:15行。
许多时候人们会被这样一种“美妙的”想法吸引:用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上,在绝大多数情况下,这种做法不值得提倡。为什么呢?
要理解其原因,我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生,catch(Exception ex)就相当于说我们想要处理几乎所有的异常。
再来看看前面的代码例子。我们真正想要捕获的异常是什么呢?最明显的一个是SQLException,这是JDBC操作中常见的异常。另一个可能的异常是IOException,因为它要操作OutputStreamWriter。显然,在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说,catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。
另一方面,除了这两个特定的异常,还有其他许多异常也可能出现。例如,如果由于某种原因,executeQuery返回了null,该怎么办?答案是让它们继续抛出,即不必捕获也不必处理。实际上,我们不能也不应该去捕获可能出现的所有异常,程序的其他地方还有捕获异常的机会——直至最后由JVM处理。
结论二:在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。不要试图处理所有可能出现的异常。
反例之三:占用资源不释放
代码:3行-14行。
异常改变了程序正常的执行流程。这个道理虽然简单,却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到了异常,也要正确释放占用的资源。为此,Java提供了一个简化这类操作的关键词finally。
finally是样好东西:不管是否出现了异常,Finally保证在try/catch/finally块结束之前,执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。
当然,编写finally块应当多加小心,特别是要注意在finally块之内抛出的异常——这是执行清理任务的最后机会,尽量不要再有难以处理的错误。
结论三:保证所有资源都被正确释放。充分运用finally关键词。
反例之四:不说明异常的详细信息
代码:3行-18行。
仔细观察这段代码:如果循环内部出现了异常,会发生什么事情?我们可以得到足够的信息判断循环内部出错的原因吗?不能。我们只能知道当前正在处理的类发生了某种错误,但却不能获得任何信息判断导致当前错误的原因。
printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程,但只提供了一些最基本的信息,未能说明实际导致错误的原因,同时也不易解读。
因此,在出现异常时,最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。
结论四:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。
反例之五:过于庞大的try块
代码:3行-14行。
经常可以看到有人把大量的代码放入单个try块,实际上这不是好习惯。这种现象之所以常见,原因就在于有些人图省事,不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子,虽然东西是带上了,但要找出来可不容易。
一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明Exception,而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception。
结论五:尽量减小try块的体积。
反例之六:输出数据不完整
代码:7行-11行。
不完整的数据是Java程序的隐形杀手。仔细观察这段代码,考虑一下如果循环的中间抛出了异常,会发生什么事情。循环的执行当然是要被打断的,其次,catch块会执行——就这些,再也没有其他动作了。已经输出的数据怎么办?使用这些数据的人或设备将收到一份不完整的(因而也是错误的)数据,却得不到任何有关这份数据是否完整的提示。对于有些系统来说,数据不完整可能比系统停止运行带来更大的损失。
较为理想的处置办法是向输出设备写一些信息,声明数据的不完整性;另一种可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一次性输出。
结论六:全面考虑可能出现的异常以及这些异常对执行流程的影响。
改写后的代码
根据上面的讨论,下面给出改写后的代码。也许有人会说它稍微有点啰嗦,但是它有了比较完备的异常处理机制。
Code
OutputStreamWriter out =
java.sql.Connection conn =
try {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select uid, name from user");
while (rs.next())
{
out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));
}
}
catch(SQLException sqlex)
{
out.println("警告:数据不完整");
throw new ApplicationException("读取数据时出现SQL错误", sqlex);
}
catch(IOException ioex)
{
throw new ApplicationException("写入数据时出现IO错误", ioex);
}
finally
{
if (conn != null) {
try {
conn.close();
}
catch(SQLException sqlex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());
}
}
if (out != null) {
try {
out.close();
}
catch(IOException ioex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());
}
}
}
本文的结论不是放之四海皆准的教条,有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心,务必加上详细、全面的注释。
一方面,不要笑话这些错误,不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途,原因很简单,因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔,它们美丽动人,无孔不入,时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事,不足挂齿,但请记住:勿以恶小而为之,勿以善小而不为。
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/01/1258247.html
posted @
2008-08-01 15:57 破名超难起 阅读(77) |
评论 (0) |
编辑 收藏
请求有效性处理,使用令牌可以有效的防止重复提交。
protected String generateToken(HttpServletRequest request) 创建一个令牌.
protected boolean isTokenValid(HttpServletRequest request) 检查令牌是否有效
protected boolean isTokenValid(HttpServletRequest request,Boolean reset) 检查令牌是否有效,并且重置令牌(如果reset 是true)
protected void resetToken(HttpServletRequest request) 重置令牌
protected void saveToken(HttpServletRequest request) 添加令牌
基本原理:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,
看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给
客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次
提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
实例:
Code
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.yourcompany.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
* MyEclipse Struts
* Creation date: 08-01-2008
*
* XDoclet definition:
* @struts.action validate="true"
* @struts.action-forward name="add" path="/add.jsp"
*/
public class ToAddAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
saveToken(request);
return mapping.findForward("add");
}
}
这个Action主要作用就是在跳转的页面上加入Token,只有加入Token才能实现Token的验证。执行完这个Action后,跳转到的页面会出现类似如下的一个hidden控件
Code
<div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="b030d9188a218097211d9061907cde5d"></div>
那么恭喜你,Token生效拉,注意,跳转到的页面里面,表单指可以用Struts标签来生成,不可以用HTML来生成,不然Token是无效的。
使用Token的第一步完成,第二步,在提交的Action中验证Token是否符合,代码如下:
Code
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.yourcompany.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import com.lc.sqlhelp.Access;
import com.yourcompany.struts.form.AddForm;
/**
* MyEclipse Struts Creation date: 08-01-2008
*
* XDoclet definition:
*
* @struts.action path="/add" name="addForm" input="/form/add.jsp"
* scope="request" validate="true"
* @struts.action-forward name="add_suc" path="/add_suc.jsp"
* @struts.action-forward name="add_fail" path="/add_fail.jsp"
*/
public class AddAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
*
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
AddForm af = (AddForm) form;
if (isTokenValid(request, true))//验证Token是否符合要求
{
String sql = "insert into user (username,password) values('"
+ af.getUsername() + "','" + af.getPassword() + "')";
System.out.println(sql);
Access sh = new Access();
sh.loadMyDriver();
sh.setMyConnection();
sh.createMyStatement();
sh.executeMyUpdata(sql);
sh.closeMyStatement();
sh.closeMyConnection();
return mapping.findForward("add_suc");
}
return mapping.getInputForward();
}
}
这样就完成了防止表单重复提交的功能。
实例源码下载
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/08/01/1258067.html
posted @
2008-08-01 12:07 破名超难起 阅读(109) |
评论 (0) |
编辑 收藏
在用户登录输入密码时,常常会有因为大写锁定开启而造成输入密码错误的情况,如果在用户大写锁定开启时给予提示,就可以尽量避免这种情况的发生。
一下是代码:
Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>检测大写锁定键</title>
<style type="text/css">
<!--
*{margin:0;padding:0;}
body{padding:2em;background:#242424;color:#ccc;}
h1{text-align:center;line-height:200%;}
h3{text-indent:1em;line-height:160%;color:#666;font-weight:normal;font-size:1em;}
h3 a{color:#bbb; text-decoration:none;margin:0 0.5em;}
h3 a:hover{color:#fff;}
p{margin:5em;}
span{margin:0 0.5em;font-size:85.7%;}
-->
</style>
</head>
<body>
<h1>检测大写锁定键 </h1>
<form action="#" method="post">
<p><label for="password">密码:</label><input type="password" id="password" name="password" /><span style="display:none;">大写锁定键被按下,请注意大小写</span></p>
</form>
<script type="text/javascript">
//<![CDATA[
function detectCapsLock(event){
var e = event||window.event;
var o = e.target||e.srcElement;
var oTip = o.nextSibling;
var keyCode = e.keyCode||e.which; // 按键的keyCode
var isShift = e.shiftKey ||(keyCode == 16 ) || false ; // shift键是否按住
if (
((keyCode >= 65 && keyCode <= 90 ) && !isShift) // Caps Lock 打开,且没有按住shift键
|| ((keyCode >= 97 && keyCode <= 122 ) && isShift)// Caps Lock 打开,且按住shift键
){oTip.style.display = '';}
else{oTip.style.display = 'none';}
}
document.getElementById('password').onkeypress = detectCapsLock;
//]]>
</script>
</body>
</html>
文章来源:
http://www.cnblogs.com/xiaoao808/archive/2008/07/31/1257624.html
posted @
2008-07-31 21:18 破名超难起 阅读(243) |
评论 (0) |
编辑 收藏
摘要: 前一段时间朱哥一直在搞视频转换这个东东,我也一直很有兴趣,就尝试了一下。
首先是文件上传功能的完成,做得很粗糙,没有验证上传文件是否为视频文件。利用前一段时间看视频学来的部分代码很轻松搞定。
接下来,就是视频转换了,...
阅读全文
posted @
2008-07-31 16:41 破名超难起 阅读(142) |
评论 (0) |
编辑 收藏