2008年9月23日
转自凡人足迹
参数:
options
返回值:
xmlHttpRequest
使用HTTP请求一个页面。
这是jquery的低级ajax实现。要查看高级抽象,见$.set、$.post等,这些方法更易于理解和使用。但是功能上有限制(例如,没有错误处理函数)。
警告:如果数据类型指定为"script",那么POST自动转化为GET方法。(因为script会作为一个嵌入页面的script标签进行载入)
$.ajax()函数返回它创建的XMLHttpRequest对象。在大部分情况下,你不需要直接操作此对象。通常,这个XMLHttpRequest对象主要用于需要手动中断XMLHttpRequest请求的时候。
注意:如果你指明了下面列出的数据类型,请确保服务端发送了正确的MIME响应类型(如. xml 的类型是 "text/xml")。错误的MIME类型能够导致脚本出现意想不到的问题。请查看AJAX的范例来了解数据类型的更多信息。
$.ajax()函数需要一个参数,一个包含有键/值对的对象,用于初始化并操作请求对象。
在jQuery 1.2版本中,如果你指明了一个JSONP回调函数,你就可以从其它的域中载入JSON类型的数据,写法类似于 "myurl?callback=?" 。jQuery会自动调用正确的方法名称来代替查询字符串,执行你指定的回调函数。或者,你也可以指定jsonp的数据类型的回调函数,此函数会自动添加到Ajax请求中。
参数选项:
async(true) 数据类型: Boolean
默认情况下,所有的请求都是异步发送的(默认为true)。 如果需要发送同步请求, 设置选项为false。注意,同步请求可能会暂时的锁定浏览器, 当请求激活时不能进行任何操作。
beforeSend 数据类型: Function
一个预处理函数用于在发送前修改XMLHttpRequest对象,设置自定义头部等。 XMLHttpRequest作为惟一的参数被传递。这是一个 Ajax 事件。 function (XMLHttpRequest) {
this; // the options for this ajax request
}cache(true) 数据类型: Boolean
jQuery 1.2中新添加的参数, 如果设为false,则会强制浏览器不缓存请求的页面。
complete 数据类型: Function
当请求完成时执行的函数(在成功或失败之后执行)。这个函数有2个参数: XMLHttpRequest对象和一个描述HTTP相应的状态字符串。 这是一个 Ajax 事件。 function (XMLHttpRequest, textStatus) {
this; // the options for this ajax request
}contentType("application/x-www-form-urlencoded") 数据类型: String
发送到服务器的数据的内容类型。默认是 "application/x-www-form-urlencoded", 适合大多数情况。
data 数据类型: Object,String
要发送给服务器的数据。如果不是字符串,那么它会被转化为一个查询字符串。在GET请求中它被添加到url的末尾。要防止这种自动转化,请查看processData选项。 数据对象必须是一组键/值对。如果键对应的值是数组,jQuery会将其值赋给同一个键属性。 例如 {foo:["bar1", "bar2"]} 变为 '&foo=bar1&foo=bar2'。
dataType( Intelligent Guess (xml or html)) 数据类型: String
期待由服务器返回值类型。如果没有明确指定,jQuery会根据实际返回的MIME类型自动的将responseXML或responseText传递给success指定的回调函数。有效的类型(返回的类型的结果值会作为第一个参数传递给success指定的回调函数)有: "xml": 返回一个可以由jQuery处理的XML文档。
"html": 返回文本格式的HTML代码。包括求值后的脚本标记。
"script": 将响应作为javascript语句求值,并返回纯文本。不缓存此脚本,除非设置了cache选项。设置为"script"类型会将post方法转换为get方法。
"json": 将响应作为JSON求值,并返回一个Javascript对象。
"jsonp": 使用JSONP载入一个JSON代码块. 会在URL的末尾添加"?callback=?"来指明回调函数。(jQuery 1.2以上的版本支持)
"text": 文本格式的字符串
error 数据类型: Function
请求失败时执行的函数。函数具有3个参数: XMLHttpRequest对象,一个描述产生的错误类型和一个可选的异常对象, 如果有的化。 这是一个Ajax 事件。function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}global(true) 数据类型: Boolean
是否为当前的请求触发全局AJAX事件处理函数,默认值为true。设置为false可以防止触发像ajaxStart或ajaxStop这样的全局事件处理函数。这可以用于控制多个不同的Ajax事件。
ifModified(false) 数据类型: Boolean
只有响应自上次请求后被修改过才承认是成功的请求。是通过检查头部的Last-Modified值实现的。默认值为false,即忽略对头部的检查
jsonp 数据类型: String
在jsonp请求中重新设置回调的函数。这个值用于代替'callback=?'中的查询字符串。'callback=?'位于get请求中url的末尾或是post请求传递的数据中。因此设置 {jsonp:'onJsonPLoad'} 会将 'onJsonPLoad=?' 传送给服务器。
processData(true) 数据类型: Boolean
在默认的情况下,如果data选项传进的数据是一个对象而不是字符串,将会自动地被处理和转换成一个查询字符串,以适应默认的content-type--"application/x-www-form-urlencoded"。如果想发送domDocuments,就要把这个选项设置为false。
success 数据类型: Function
当请求成功时调用的函数。这个函数会得到二个参数:从服务器返回的数据(根据“dataType”进行了格式化)和一个描述HTTP相应的状态字符串。这是一个 Ajax 事件。 function (data, textStatus) {
// data could be xmlDoc, jsonObj, html, text, etc...
this; // the options for this ajax request
}timeout 数据类型: Number
如果通过$.ajaxSetup设置了一个全局timeout,那么此函数使用一个局部timeout覆盖了全局timeout(单位为毫秒)。例如,你可以设置比较长的延迟给一个特殊的请求,同时其他所有请求使用1秒的延迟。有关全局延迟,见$.ajaxTimeout()。
type("GET") 数据类型: String
请求的类型 ("POST" 或 "GET"), 默认是 "GET"。注意:其他的HTTP请求方法,如PUT和DELETE,在这里也可以使用,当时它们并不被所有的浏览器支持。
url(The current page) 数据类型: String
请求发送的目标URL地址
username 数据类型: String
username可用于在响应一个HTTP连接时的认证请求。 实例
载入并执行一个JavaScript文件。
$.ajax({
type: "GET",
url: "test.js",
dataType: "script"
});保存数据到服务器,完成后通知用户。
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
}
});取得一个HTML页面的最新版本。
$.ajax({
url: "test.html",
cache: false,
success: function(html){
$("#results").append(html);
}
});同步载入数据。在执行请求的时候阻塞浏览器。这是在保证数据的同步性比交互更重要的情况下的一种更好的方法。
var html = $.ajax({
url: "some.php",
async: false
}).responseText;向服务器发送xml文档数据。通过设置processData选项为false,将数据自动转换为string的动作被禁止了。
var xmlDocument = [create xml document];
$.ajax({
url: "page.php",
processData: false,
data: xmlDocument,
success: handleResponse
});load( url, [data], [callback] )参数:
url (String): 装入页面的URL地址。
params (Map): (可选)发送到服务端的键/值对参数。
callback (Function): (可选) 当数据装入完成时执行的函数. function (responseText, textStatus, XMLHttpRequest) {
this; // dom element
}返回值:
jQuery
装入一个远程HTML内容到一个DOM结点。 默认使用get方法发送请求,但如果指定了额外的参数,将会使用post方法发送请求。在 jQuery 1.2中,可以在URL参数中指定一个jQuery选择器,这会过滤返回的HTML文档,只取得文档中匹配选择器的元素。此语法类似于"url #some > selector"。
实例
载入文档的sidebar的导航部分到一个无序列表中。
$("#links").load("/Main_Page #p-Getting-Started li");将feeds.html文件载入到id为feeds的div中。
$("#feeds").load("feeds.html");同上,但是发送了附加的参数,并且在响应结束后执行一个自定义函数。
$("#feeds").load("feeds.php", {limit: 25}, function(){
alert("The last 25 entries in the feed have been loaded");
});jQuery.get( url, [data], [callback] )参数:
url (String): 装入页面的URL地址
Map(可选): (可选)发送到服务端的键/值对参数
callback (Function): (可选) 当远程页面装入完成时执行的函数 function (data, textStatus) {
// data可以是xmlDoc, jsonObj, html, text, 等...
this; // the options for this ajax request
}返回值:
XMLHttpRequest
使用GET请求一个页面。
这是向服务器发送get请求的简单方法。它可以指定一个回调函数,在请求完成后执行(只有在请求成功时)。如果还需要设置error和success回调函数,则需要使用$.ajax。
实例
请求test.php页,忽略返回值.
$.get("test.php");请求test.php页并发送附加数据(忽略返回值).
$.get("test.php", { name: "John", time: "2pm" } );显示从test.php请求的返回值(HTML 或 XML, 根据不同返回值).
$.get("test.php", function(data){
alert("Data Loaded: " + data);
});显示向test.cgi发送附加数据请求的返回值 (HTML 或 XML, 根据不同返回值).
$.get("test.cgi", { name: "John", time: "2pm" },
function(data){
alert("Data Loaded: " + data);
});jQuery.getJSON( url, [data], [callback] )参数:
url (String): 装入页面的URL地址
Map(可选): (可选)发送到服务端的键/值对参数
callback (Function): (可选) 当数据装入完成时执行的函数 function (data, textStatus) {
// data will be a jsonObj
this; // the options for this ajax request
}返回值:
XMLHttpRequest
使用GET请求JSON数据。
在jQuery 1.2版本中,如果你指明了一个JSONP回调函数,你就可以从其它的域中载入JSON类型的数据,写法类似于 "myurl?callback=?" 。jQuery会自动调用正确的方法名称来代替查询字符串,执行你指定的回调函数。或者,你也可以指定jsonp的数据类型的回调函数,此函数会自动添加到Ajax请求中。注意: 请记住, that lines after this function will be executed before callback.
实例
从Flickr JSONP API中载入最新的四幅猫的图片
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
function(data){
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});从test.js载入JSON数据, 从返回的JSON数据读取name值。
$.getJSON("test.js", function(json){
alert("JSON Data: " + json.users[3].name);
});从test.js载入JSON数据, 传递一个附加参数,从返回的JSON数据读取name值。
$.getJSON("test.js", { name: "John", time: "2pm" }, function(json){
alert("JSON Data: " + json.users[3].name);
});显示向test.php发送请求的返回值 (HTML 或 XML, 根据不同返回值).
$.getIfModified("test.php", function(data){
alert("Data Loaded: " + data);
});显示向test.php发送请求的返回值 (HTML 或 XML, 根据不同返回值),提供了一个附加的参数.
$.getIfModified("test.php", { name: "John", time: "2pm" },
function(data){
alert("Data Loaded: " + data);
});列出从pages.php返回的查询结果,将返回的数组转化为一段HTML代码。
var id=$("#id").attr("value");
$.getJSON("pages.php",{id:id},dates);
function dates(datos)
{
$("#list").html("Name:"+datos[1].name+"<br>"+"Last Name:"+datos[1].lastname+"<br>"+"Address:"+datos[1].address);
}jQuery.getScript( url, [callback] )参数:
url (String): 装入页面的URL地址
callback (Function): (可选) 当数据装入完成时执行的函数 function (data, textStatus) {
// data应该是javascript
this; // the options for this ajax request
}返回值:
XMLHttpRequest
使用GET请求JavaScript文件并执行。
在jQuery 1.2前, getScript只能从页面所在的主机载入脚本,1.2中, 你可以从任何主机载入脚本。警告: Safari 2 及其更老的版本不能在全局上下文中正确识别脚本。如果你通过getScript载入函数,请保证设置一个延迟来执行这个脚本。
实例
我们动态的载入一个新的官方jQuery颜色动画插件,载入后绑定一些动画效果到元素上。
$.getScript("http://dev.jquery.com/view/trunk/plugins/color/jquery.color.js", function(){
$("#go").click(function(){
$(".block").animate( { backgroundColor: 'pink' }, 1000)
.animate( { backgroundColor: 'blue' }, 1000);
});
});载入test.js JavaScript文件并执行。
$.getScript("test.js");载入test.js JavaScript文件并执行,当执行结束后显示一条警告信息。
$.getScript("test.js", function(){
alert("Script loaded and executed.");
});jQuery.post( url, [data], [callback], [type] )参数:
url (String): 装入页面的URL地址
Map(可选): (可选)发送到服务端的键/值对参数
callback (Function): (可选) 当数据装入完成时执行的函数 function (data, textStatus) {
// data可能是 xmlDoc, jsonObj, html, text, 等...
this; // the options for this ajax request
}String $.postJSON = function(url, data, callback) {
$.post(url, data, callback, "json");
};返回值:
XMLHttpRequest
使用POST请求一个页面。
这是向服务器发送post请求的简单方法。它可以指定一个回调函数,在请求完成后执行(只有在请求成功时)。如果还需要设置error和success回调函数,则需要使用$.ajax。
ajaxComplete( callback )参数:
callback (Function): 要执行的函数 function (event, XMLHttpRequest, ajaxOptions) {
this; // dom element listening
}返回值:
jQuery
当一个AJAX请求结束后,执行一个函数。这是一个Ajax事件
实例
当AJAX请求完成时显示一条信息。
$("#msg").ajaxComplete(function(request, settings){
$(this).append("<li>Request Complete.</li>");
});ajaxError( callback )参数:
callback (Function): 要执行的函数 function (event, XMLHttpRequest, ajaxOptions, thrownError) {
// thrownError only passed if an error was caught
this; // dom element listening
}返回值:
jQuery
当一个AJAX请求失败后,执行一个函数。这是一个Ajax事件.
实例
当AJAX请求错误时显示一条信息。
$("#msg").ajaxError(function(request, settings){
$(this).append("<li>Error requesting page " + settings.url + "</li>");
});ajaxSend( callback )参数:
callback (Function): 要执行的函数 function (event, XMLHttpRequest, ajaxOptions) {
this; // dom element listening
}返回值:
jQuery
在一个AJAX请求发送时,执行一个函数。这是一个Ajax事件.
实例
当AJAX请求发出后显示一条信息。
$("#msg").ajaxSend(function(evt, request, settings){
$(this).append("<li<Starting request at " + settings.url + "</li<");
});ajaxStart( callback )参数:
callback (Function): 要执行的函数 function () {
this; // dom element listening
}返回值:
jQuery
在一个AJAX请求开始但还没有激活时,执行一个函数。这是一个Ajax事件.
实例
当AJAX请求开始(并还没有激活时)显示loading信息。
$("#loading").ajaxStart(function(){
$(this).show();
});ajaxStop( callback )参数:
callback (Function): 要执行的函数 function () {
this; // dom element listening
}返回值:
jQuery
当所有的AJAX都停止时,执行一个函数。这是一个Ajax事件.
实例
当所有AJAX请求都停止时,隐藏loading信息。
$("#loading").ajaxStop(function(){
$(this).hide();
});ajaxSuccess( callback )参数:
callback (Function): 要执行的函数 function (event, XMLHttpRequest, ajaxOptions) {
this; // dom element listening
}返回值:
jQuery
当一个AJAX请求成功完成后,执行一个函数。这是一个Ajax事件
实例
当AJAX请求成功完成时,显示信息。
$("#msg").ajaxSuccess(function(evt, request, settings){
$(this).append("<li>Successful Request!</li>");
});jQuery.ajaxSetup( options )参数:
Options: 用于Ajax请求的键/值对
为所有的AJAX请求进行全局设置。查看$.ajax函数取得所有选项信息。
实例
设置默认的全局AJAX请求选项。
$.ajaxSetup({
url: "/xmlhttp/",
global: false,
type: "POST"
});
$.ajax({ data: myData });serialize( )返回值:
jQuery
以名称和值的方式连接一组input元素。返回值类似于: single=Single2&multiple=Multiple&multiple=Multiple3&radio=radio2 。在jQuery 1.2中。serialize方法实现了正确表单元素序列,而不再需要插件支持。
实例
连接表单元素的一组查询字符串,可用于发送Ajax请求。
function showValues() {
var str = $("form").serialize();
$("#results").text(str);
}
$(":checkbox, :radio").click(showValues);
$("select").change(showValues);
showValues();serializeArray( )返回值:
jQuery
连接所有的表单和表单元素(类似于.serialize()方法),但是返回一个JSON数据格式。
实例
从form中取得一组值,显示出来
function showValues() {
var fields = $(":input").serializeArray();
alert(fields);
$("#results").empty();
jQuery.each(fields, function(i, field){
$("#results").append(field.value + " ");
});
}
$(":checkbox, :radio").click(showValues);
$("select").change(showValues);
showValues();
2008年9月22日
EditPlus技巧
------------------------------------------------------
技巧中,基于平时我对EditPlus的摸索实践而成,在编译器集成例子中参照了部分官方的文献。有几篇是从网上搜集来的,这里我注明了来源或原始作者。如果你是相应作者,不希望文章放在这里,请通知我,我会及时删掉。 -----Liangjh
自己写的一些里面,不见得有多大的技术含量,只是希望有时能够节省大家的一些时间
------------------------------------------------------
文章或者技巧及原始作者或出处:
正则表达式类
【1】 正则表达式应用——替换指定内容到行尾
【2】 正则表达式应用——数字替换----------------------------Microshaoft@CCF,jiuk2k@CCF
【3】 正则表达式应用——删除每一行行尾的指定字符
【4】 正则表达式应用——替换带有半角括号的多行
【5】 正则表达式应用——删除空行----------------------------江德华
软件技巧类
------------------------------------------------------
【6】 软件技巧——键盘记录的注意事项
【7】 软件技巧——关闭文档标签的便捷方法
【8】 软件技巧——如何去掉 EditPlus 保存文本文件时的添加后缀提示?
【9】 软件技巧——提示找不到语法文件的解决办法
【10】软件技巧——设置editplus支持其它文字,如韩文----------jackywu1978@LJF
【11】软件技巧——FTP 上传的设置----------------------------李应文2.11汉化版
【12】软件技巧——如何禁用备份文件功能?
【13】软件技巧——添加语法文件、自动完成文件、以及剪辑库文件
工具集成类
------------------------------------------------------
【14】工具集成——编译器集成例子(Java、Borland C++、Visual C++、Inno Setup、nsis、C#)
【15】工具集成——让Editplus调试PHP程序----------------------avenger,aukw@CCF
【16】工具集成——打造 PHP 调试环境(二)----------------------老七2.11汉化版
【17】在 WINPE 中集成 EDITPLUS
后续添加
------------------------------------------------------
【18】支持带UTF-8标记/不带UTF-8标记的文件
【19】建立文件关联,以便在资源管理器中双击打开对应语法文件
【20】特别应用,双击单词选择问题
【21】在Editplus中使用CVS版本控制功能---------------------sunbn@CCF
每个步骤都说得很详细了,就没有必要贴图了,体积不要太大才好。
【1】正则表达式应用——替换指定内容到行尾
原始文本如下面两行
abc aaaaa
123 abc 444
希望每次遇到“abc”,则替换“abc”以及其后到行尾的内容为“abc efg”
即上面的文本最终替换为:
abc efg
123 abc efg
解决:
① 在替换对话框,查找内容里输入“abc.*”
② 同时勾选“正则表达式”复选框,然后点击“全部替换”按钮
其中,符号的含义如下:
“.” =匹配任意字符
“*” =匹配0次或更多
注意:其实就是正则表达式替换,这里只是把一些曾经提出的问题加以整理,单纯从正则表达式本身来说,就可以引申出成千上万种特例。
【2】正则表达式应用——数字替换 (Microshaoft@CCF,jiuk2k@CCF)
希望把
asdadas123asdasdas456asdasdasd789asdasd
替换为:
asdadas[123]asdasdas[456]asdasdasd[789]asdasd
在替换对话框里面,勾选“正则表达式”复选框;
在查找内容里面输入“[0-9][0-9][0-9]”,不含引号
“替换为:”里面输入“[\0\1\2]”,不含引号
范围为你所操作的范围,然后选择替换即可。
实际上这也是正则表达式的使用特例,“[0-9]”表示匹配0~9之间的任何特例,同样“[a-z]”就表示匹配a~z之间的任何特例
上面重复使用了“[0-9]”,表示连续出现的三个数字
“\0”代表第一个“[0-9]”对应的原型,“\1”代表第二个“[0-9]”对应的原型,依此类推
“[”、“]”为单纯的字符,表示添加“[”或“]”,如果输入“其它\0\1\2其它”,则替换结果为:
asdadas其它123其它asdasdas其它456其它asdasdasd其它789其它asdasd
■功能增强(by jiuk2k@CCF):
如果将查找内容“[0-9][0-9][0-9]”改为“[0-9]*[0-9]”,对应1 或 123 或 12345 或 ...
也可以这样定制
查找: ([0-9]+)
替换: [\1]或 [$1]
在 \1 或大或 $1 后面加入欲替换目标
■补充(by jiuk2k@CCF)
editplut支持的只是Regular expression 的子集,如果用其它支持全集的替换软件可以如下简单操作
正则表达式应用——数字替换 :
search: ([\d]+)
replace: [\1] or [$1]
editplus:
search: ([0-9]+)
replace: [\1]
【3】正则表达式应用——删除每一行行尾的指定字符
因为这几个字符在行中也是出现的,所以肯定不能用简单的替换实现
比如
12345 1265345
2345
需要删除每行末尾的“345”
这个也算正则表达式的用法,其实仔细看正则表达式应该比较简单,不过既然有这个问题提出,说明对正则表达式还得有个认识过程,解决方法如下
解决:
在替换对话框中,启用“正则表达式”复选框
在查找内容里面输入“345$”
这里“$”表示从行尾匹配
如果从行首匹配,可以用“^”来实现,不过 EditPlus 有另一个功能可以很简单的删除行首的字符串
a. 选择要操作的行
b. 编辑-格式-删除行注释
c. 在弹出对话框里面输入要清除的行首字符,确定
【4】正则表达式应用——替换带有半角括号的多行
几百个网页中都有下面一段代码:
我想把它们都去掉,可是找了很多search & replace的软件,都是只能对“一行”进行操作。
EditPlus 打开几百个网页文件还是比较顺畅的,所以完全可以胜任这个工作。
具体解决方法,在 Editplus 中使用正则表达式,由于“(”、“)”被用做预设表达式(或者可以称作子表达式)的标志,所以查找
“\n”
时会提示查找不到,所以也就无法进行替换了,这时可以把“(”、“)”使用任意字符标记替代,即半角句号:“.”。替换内容为
\n
在替换对话框启用“正则表达式”选项,这时就可以完成替换了
补充:(lucida@******)
对( ) 这样的特殊符号,应该用\( \)来表示,这也是很标准的regexp语法,可以写为
\n
■补充(by jiuk2k@CCF)
editplut支持的只是Regular expression 的子集,如果用其它支持全集的替换软件可以如下简单操作
search:
replace: 空格
【5】正则表达式应用——删除空行
启动EditPlus,打开待处理的文本类型文件。
①、选择“查找”菜单的“替换”命令,弹出文本替换对话框。选中“正则表达式”复选框,表明我们要在查找、替换中使用正则表达式。然后,选中“替换范围”中的“当前文件”,表明对当前文件操作。
②、单击“查找内容”组合框右侧的按钮,出现下拉菜单。
③、下面的操作添加正则表达式,该表达式代表待查找的空行。(技巧提示:空行仅包括空格符、制表符、回车符,且必须以这三个符号之一作为一行的开头,并且以回车符结尾,查找空行的关键是构造代表空行的正则表达式)。
直接在"查找"中输入正则表达式“^[ \t]*\n”,注意\t前有空格符。
(1)选择“从行首开始匹配”,“查找内容”组合框中出现字符“^”,表示待查找字符串必须出现在文本中一行的行首。
(2)选择“字符在范围中”,那么在“^”后会增加一对括号“[]”,当前插入点在括号中。括号在正则表达式中表示,文本中的字符匹配括号中任意一个字符即符合查找条件。
(3)按一下空格键,添加空格符。空格符是空行的一个组成成分。
(4)选择“制表符”,添加代表制表符的“\t”。
(5)移动光标,将当前插入点移到“]”之后,然后选择“匹配 0 次或更多”,该操作会添加星号字符“*”。星号表示,其前面的括号“[]”内的空格符或制表符,在一行中出现0个或多个。
(6)选择“换行符”,插入“\n”,表示回车符。
④、“替换为”组合框保持空,表示删除查找到的内容。单击“替换”按钮逐个行删除空行,或单击“全部替换”按钮删除全部空行(注意:EditPlus有时存在“全部替换”不能一次性完全删除空行的问题,可能是程序BUG,需要多按几次按钮)。
■补充(by jiuk2k@CCF)
editplut支持的只是Regular expression 的子集,如果用其它支持全集的替换软件可以如下简单操作
search: ^\s+
replace: 空格
相关内容还有很多,可以自己参考正则表达式的语法仔细研究一下
【6】软件技巧——键盘记录的注意事项
EditPlus 的键盘记录有些类似于 UltraEdit 的宏操作,不过功能相对单一,录制的文件可编辑性较差。
由于基本无法编辑录制的文件,所以录制的时候为了避免录制失败,推荐纯粹使用键盘操作,以下是比较关键的几个键盘组合:
Ctrl+F = 调出查找对话框
Ctrl+H = 调出替换对话框
Alt+F4 = 关闭作用,比如,关闭查找对话框、关闭替换对话框,等等
其它键盘快捷键在“帮助-快捷键列表”里面可以很容易的查找到,这里就不细说了。
【7】软件技巧——关闭文档标签的便捷方法
右键单击文档标签工具条,弹出菜单中选择“标签选项”,选中“用鼠标中间的按钮关闭”,这里包括鼠标的滚轮。
【8】软件技巧——如何去掉 EditPlus 保存文本文件时的添加后缀提示?
如果你使用 EditPlus 进行文本编辑,那么每次创建文本文件,编辑后保存时,尽管文件类型下拉列表中显示的是文本文件, EditPlus 还是询问你是否添加".txt"后缀,是不是很烦?
解决方法:
① 在程序目录建立一个空的文件“template.txt”
② “工具-参数设置-模板”里面,单击“添加”按钮添加模板,“菜单文本”这里输入“Text”,浏览“template.txt”,之后确定即可
③ “文件-新建-text”,就可以建立一个空的文本文件,保存时,这个文件自动带有扩展名".txt",也就避免了令人头疼的确认
④ 模板设置文件名称为“template.ini”,如果和主程序同一路径,可以使用相对路径
罗嗦了点,不过管用
要自动创建带有某种后缀的文件,方法同上。
【9】软件技巧——提示找不到语法文件 *.stx 的解决办法
原因多为设置的语法文件不存在或者是路径设置不对。这是因为 EditPlus 的语法是设置文件采用的是绝对路径,而在你设置了语法文件之后,再把程序复制到其它目录,因而导致 EditPlus 无法找到该语法文件。
解决办法:
在主程序目录里,找到 Setting.ini 这是 EditPlus 存放语法的文件
查找后缀为“.stx”、“acp”的文本内容,或者查找带有驱动器符号的行,比如
Syntax file=C:\Program Files\EditPlus 2\cpp.stx
那么,就把”C:\Program Files\EditPlus 2\“替换成你当前软件的路径。
其它提示找不到文件的解决方法同上
【10】软件技巧——设置editplus支持其它文字,如韩文
在editplus里打开文件,出来打开文件对话框;然后点击“转换器”后面的那个省略号,会出来自定义转换器对话框;在右边选择你需要的编码方式,添加到左边,然后点确定;最后在下拉框中选择需要的编码方式,然后打开文件即可。
【11】软件技巧——FTP 上传的设置
“文件->远程操作->FTP 上传”在“设置”选项卡中设置好参数(“子目录”前面应该加“/”如“/web/”),点击“确定”回到“FTP 上传”选项卡,然后点击“上传”即可;“批量上传”的设置类似。
【12】软件技巧——如何禁用备份文件功能?
在“参数选择”的文件选项页,禁用“'保存时自动创建备份文件”选项
【13】软件技巧——添加语法文件、自动完成文件、以及剪辑库文件
要添加 *.STX(语法文件)或 *.ACP(自动完成文件):
1. 选择“参数选择→语法”
2. 单击“添加”按钮,命名,在“扩展名”部分输入对应扩展名(不带“.”)
3. 浏览/输入 STX(语法文件部分) 以及 ACP(自动完成文件部分)。
添加剪辑库文件(*.CTL)
复制相应 *.CTL 文件到软件安装目录,重新启动 EditPlus ,则系统自动识别。
作者主页有很多语法自动完成文件下载,地址
http://editplus.com/files.html
【14】工具集成——编译器集成例子(Java、Borland C++、Visual C++、Inno Setup、nsis)
在“工具→参数选择→用户工具”选项页设置,设置步骤
① 设置组名称,这里也可以不设置
② 单击“添加工具→应用程序”按钮并进行如下设置
③ 各种类似"$(FilePath)"的参数可以在文本框右侧的箭头下拉菜单中获取,具体含义如下
参数 描述
$(FilePath) 文件路径(文件全名,含目录和文件名)
$(FileDir) 文件目录(不带文件名)
$(FileName) 文件名(不带目录)
$(FileNameNoExt) 不带扩展名的文件名(不带目录)
$(FileExt) 扩展名(当前文件)
$(ProjectName) 工程名称(当前工程名)
$(CurLine) 当前行号(光标位置处的行号)
$(CurCol) 当前列号(光标位置处的列号)
$(CurSel) 当前文本(插入当前选定文本)
$(CurWord) 当前单词(插入当前单词)
$(WindowList) 显示当前窗口列表并选择特定文件
例子 1. Java 编译器
菜单文本:Java 编译器
命令:c:\java\bin\javac.exe
参数:"$(FilePath)"
初始目录:$(FileDir)
捕获输出:开启
要运行已编译的 Java 类文件,你可以进行如下设置:
菜单文本:Java
命令:c:\java\bin\java.exe
参数:$(FileNameNoExt)
初始目录:$(FileDir)
“命令”部分应当替换为实际的 Java 解释器的路径。
例子 2. Borland C++
菜单文本:Borland C
命令:c:\bc\bin\bcc32.exe
参数:-Ic:\bc\include -Lc:\bc\lib -n$(FileDir) $(FilePath)
初始目录:c:\bc\bin
捕获输出:开启
例子 3. Visual C++
菜单文本:Visual C++
命令:c:\msdev\vc98\bin\cl.exe
参数:"$(FilePath)"
初始目录:$(FileDir)
捕获输出:开启
例子 4. Inno Setup
菜单文本:编译 Inno
命令:C:\Program Files\Inno Setup 4\Compil32.exe”
参数:/cc $(FileName)
初始目录:$(FileDir)
捕获输出:开启
例子 5. nsis
菜单文本:编译 nsis
命令:C:\NSIS\makensis.exe
参数:$(FileName)
初始目录:$(FileDir)
捕获输出:开启
例子 6. C#
菜单文本:编译 C#
命令:C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\csc.exe
参数:$(FileName)
初始目录:$(FileDir)
捕获输出:开启
在上面设置中,在命令部分,必须使用系统中各自编译器的绝对路径。
设置完毕后,你可以在“工具”菜单运行对应工具了,运行结果会显示在底部的输出窗口,你也可以通过快捷键(Ctrl + 0-9) 运行,或者是通过“用户工具栏”的快捷按钮运行。
要运行已编译的 *.exe 文件,你可以进行如下设置(此时可执行文件需要和编译文件同名):
菜单文本:Run
命令:$(FileNameNoExt)
参数:
初始目录:$(FileDir)
【15】工具集成—— 让Editplus调试PHP程序
1:打开Editplus,选择"工具->配置用户工具..."菜单。
2:在弹出的窗口中选择"添加工具->应用程序",给新程序起一个好记的名字,比如这里我们用"Debug PHP",在"菜单文本"中输入"Debug PHP"。点击"命令行"右边的按钮,找到你的php.exe所在的路径,例如这里是"c:\php\php.exe"。再点击"参数"右边的下拉按钮选择"文件路径",最后再把"捕获输出"前面的复选框选上。
3:现在测试一下,新建一个php文件,按快捷键Ctrl+1可以激活刚才我们设置的工具(如果你设置了多个工具,快捷键可能会有所不同),现在你可以看到它已经能正常工作了。但是还有一点不太理想:如果你的PHP程序出错,在输出窗口会提示你第几行出错 ,单击这一行提示,Editplus老是提示你找不到某某文件,是否新建。接下下我们要修正这个功能。
4:打开刚才用户工具设置窗口,找到刚才设置的"Debug PHP"工具。点击"捕获输出"复选框旁边的"输出模式"按钮,会弹出一个定义输出模式的窗体,把"使用默认输出模式"前面的复选框去掉, 在"正则表达式"这一项的文本框中输入" ^.+ in (.+) line ([0-9]+) "(不包括引号),细心的朋友可能会发现,这里使用的也正则表达式的语法。然后,在下面的"文件名"下拉菜单中选择"预设表达式 1",即上边正则表达式中的第一个参数,"行"下拉菜单项选择"预设表达式 2","列"下拉项保持为空。然后保存设置。
5:好了,现在再来试一下吧,双击出错的行数,Editplus就会自动激活出错文件,并把光标定位到出错行,是不是特别方便呢?!
现在,Editplus经过我们的"改造",已经可以即时的调试PHP文件了,虽然还不是"可视化"界面的,但对于一些平常的小程序来查错还是非常好用的。Editplus真是不款不可多得的好工具,如果你有什么使用技巧,不要忘了大家一起分享哦。^O^
如果不能切换错误行号,请尝试作如下修改: (by aukw@CCF)
1.php.ini 中html_errors = Off打开
//如果你不打开,3.中的表达式要修改
2.参数改成:-q -f "$(FilePath)"
//不加"符号的话文件名有空格的文件调试失败。。
//-q不输出html头信息,你去掉也行,不过调试时候你一般用不到那些header信息
3." ^.+ in (.+) line ([0-9]+) " 改成 "^.+ in (.+) on line ([0-9]+)$"
//如果还是不行,请注意调试结果,自己修改表达式来取出文件名和行号
【16】工具集成——打造 PHP 调试环境(二)
1: 把剪辑库定位在 PHP4 Functions 上就可以在编辑时, 利用[插入]->[匹配剪辑]命令,就可以自动完成末输入完整的 PHP 函数(或直接按 F2 键)
2: 类似上面,在选择部分文字后,同样可以自动完成。(同 F2)
3: 在[参数选择]->[设置和语法]->PHP->自动完成, 选择目录下的 php.acp 文件,你可以定制自己的自动完成方式.
4: 想要即时预览文件,可在[参数选择]->[工具]->WEB 服务器中添加本地目录,(注意不要加 http:// , 应是一个有效的站点)。
如: 主机->localhost/php | 根目录->D:\php
主机->localhost/asp | 根目录->D:\asp
主机->localhost/cgi | 根目录->D:\cgi
完成设置后只要脚本文件位于这些目录下(子目录也没问题), 就能够正确解释.
5: 各种语法和模板文件可以在 http://editplus.com/files.html 获得,可根据需要选用和编辑。
6: Ctrl+F11 可显示当前文件中的函数列表.
7: 添加各种用户工具.如:
启动MYSQL服务器管理工具->C:\mysql\bin\winmysqladmin.exe
启动Apache服务器->C:\Apache\bin\Apache.exe -k start
启动Apache服务器->C:\Apache\bin\Apache.exe -k stop (shutdown)
8: DBG 附带有一个 prof_results.php 文件,可剖析 PHP 程序的性能.
虽不是真正的调试器,但已经够了.
OK! 经过改造后,是不是有点象一个 IDE 什么?还差点,没有即时帮助...看我的,再来:
9: 把 php_manual_en.chm (最好是扩展帮助手册)加入到用户工具中, 当遇到需要参考的关键字时, 把光标定位其上, 按下快捷键 Ctrl+1, 看到了吗.
在输入时有想不起来的函数名时, 先按照第 1 条的方法调出函数, 然后...怎么样?
以上有的是对于调试工具的设置,由于此类工具比较多,大家设置时参考以上的基本就差不多了,所以就不过多的列举了。
【17】在 WINPE 中集成 EDITPLUS
可以基于目前的bartpe做得WINPE中,菜单使用nu2menu制作
默认位置为 \programs\editplus\
默认系统位置为光盘的 i386 目录
i386/system32 的 autorun.bat 中添加外壳集成(系统右键)
regedit /s %SystemDrive%\programs\editplus\REG.REG
regsvr32 /s \programs\editplus\EPPSHELL.DLL
(reg.reg保存了epp的工具栏信息,当然注册用户也可以放置注册信息)
复制editplus安装包里面的文件到programs\editplus\,注意,如果有setting.ini,删掉该文件,在nu2menu里面加入以下句子(可以根据需要安排位于特定菜单条目下)
FUNC="@GetProgramDrive()\Programs\EditPlus\editplus.exe">EditPlus 文本编辑
【18】支持带UTF-8标记/不带UTF-8标记的文件 Lei@******提出并测试
这里Byte Order Mark翻译为标记/文件头/标签
参数选择-文件-里面设置“支持不带有UTF-8文件头的UTF-8文件”,我这里翻译标签为UTF-8文件头,如果复选该项,应该是保存为不带标签的Utf-8,如果不复选,应该是保存成带有BOM的UTF-8。
这样就可以打开带签名的UTF-8文件,并且可以正常编辑,但是又不能打开不带签名的了,想要打开不带签名的还需要改回来...不过虽然有点麻烦,但是总算能用了
【19】建立文件关联,以便在资源管理器中双击打开对应语法文件
Editplus中可以设置各种语法,如果希望建立文件关联:
在“参数选择-语法”对话框中,选择一个语法,如C++,在下面的“语法设置”标签里面,选择“关联到资源管理器中”,以后双击对应文件后缀的时候,就会直接启用EditPlus打开了。
【20】特别应用,双击单词选择问题
比如对于下面文本,希望双击“1234”位置,就可以选择“1234”,而不是选择整行
ABCD-1234-EFGH-ACDE
软件默认是选择整行,这时可以自己进行设置,打开“参数选择”,在“常规”选项页的第三个选项里面(双击单词截止府),添加输入“-“,确认,以后就可以实现截止符之间的内容了
【21】在Editplus中使用CVS版本控制功能 sunbn@CCF
CVS是开放源代码的版本控制系统,CVS作为一个免费的优秀的版本管理工具被广泛的使用在许多的软件公司的软件配置管理过程中。
我们经常使用的CVS客户端是WinCVS,或者JBuilder/Eclipse内置的CVS功能。可是有时候编辑html文件、PHP/Perl文件或者Java文件的时候经常使用到轻便的编辑工具——Editplus2.x,往往编辑完了之后需要使用WinCVS再进行更新或者提交操作,来回切换程序窗口很是麻烦。如何让Editplus也能够方便的使用CVS功能呢,其实利用Edit plus的“User Tool”——“用户工具”功能就可以实现。其方便程度甚至快追上一些IDE了,而且经过测试,进行简单的CVS提交和更新动作比WinCVS要快一些。
在设置之前我们还是要安装WinCVS的客户端,因为要用到cvs.exe这个命令行工具完成我们的工作,安装好WinCVS之后,需要将WinCVS的安装路径写到系统的全局变量“Path”中,使系统可以找到cvs.exe这个可执行程序。或者在下面 的设置中指定cvs程序的绝对路径。
具体设置方法如下:
1、菜单中Tools>>Preference,在设置对话框选择“Files”,勾选“reload modified files automatically”,即自动载入被修改的文件。
2、菜单中Tools>>Configure User Tools,点击Group Name,将一个Group名称设置为CVS。
3、在“Group and tool items”下拉框中选择我们新建的CVS Group
4、点击“Add Tool >> ”按钮新增一个Tool并设置相关选项。
login的设置注意要取消掉“Capture Output”因为要在下面的弹出窗口中输入登录的密码。
我们可以在“Output Window”窗口看到以上工具执行的结果:
以上是抛砖引玉,希望能对大家有所帮助,其实在UltraEdit/Emedit等中也可以使用外部工具设置CVS的使用。
另外,需要注意的几点:
1。首先您所编辑的文件是处于CVS控制下的文件,即还是需要使用WinCVS来Checkout你的module(用cvs命令行也可),在Editplus中也可以设置User Tools进行checkout,但是并不常用也不方便。
2。向CVS添加文件和从CVS删除文件也是可以放到User Tools中的,这个大家可以自己试着配置一下。
您正在看的文章来自番禺论坛 http://bbs.pyyrf.com/,原文地址:http://bbs.pyyrf.com/thread-16024-1-1.htmlrn原文来自:http://www.sb1987.cn/post/360/
pageEncoding是jsp文件本身的编码
contentType的charset是指服务器发送给客户端时的内容编码
JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。
第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。
第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。
JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。
第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效
contentType的設定.
pageEncoding 和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了(TOMCAT4.1.27是如此). 但这不是绝对的, 这要看各自JSPC的处理方式. 而pageEncoding不等于contentType, 更有利亚洲区的文字 CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。其他的语言也对应不同的charset,比如日文的字符集是“iso-2022-jp ”,韩文的是“ks_c_5601”。Content-Type的Content还可以是:text/xml等文档类型;Charset选项:ISO-8859-1(英文)、BIG5、UTF-8、SHIFT-Jis、Euc、Koi8-2、us-ascii, x-mac-roman, iso-8859-2, x-mac-ce, iso-2022-jp, x-sjis, x-euc-jp,euc-kr, iso-2022-kr, gb2312, gb_2312-80, x-euc-tw,x-cns11643-1,x-cns11643-2等字符集;Content-Language的Content还可以是:EN、FR等语言代码。
ContentType属性指定了MIME类型和JSP页面回应时的字符编码方式。MIME类型的默认值是“text/html”; 字符编码方式的默认值是“ISO-8859-1”. MIME类型和字符编码方式由分号隔开
pageEncoding的内容只是用于jsp输出时的编码,不会作为header发出去的。
pageEncoding 是通知web server jsp的编码。
jsp文件不像.java,.java在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5或者MS950。而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。所以编译器采用的方法刚好可以让虚拟机得到正确的资料。
但是jsp文件不是这样,它没有这个默认转码过程,但是指定了pageEncoding就可以实现正确转码了。
举个例子:
<%@ page contentType="text/html;charset=utf-8" %>
大都会打印出乱码,因为输入的“你好”是gbk的,但是服务器是否正确抓到“你好”不得而知。
但是如果更改为
<%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>
这样就服务器一定会是正确抓到“你好”了。
2008年9月21日
tomcat中的context.xml元素详解小人物,大博客 Q'e ^ L0J*J4h
元素名
|
属性
|
解释
|
server
|
port
|
指定一个端口,这个端口负责监听关闭tomcat的请求
|
shutdown
|
指定向端口发送的命令字符串
|
service
|
name
|
指定service的名字
|
Connector(表示客户端和service之间的连接)
|
port
|
指定服务器端要创建的端口号,并在这个端口监听来自客户端的请求
|
minProcessors
|
服务器启动时创建的处理请求的线程数
|
maxProcessors
|
最大可以创建的处理请求的线程数
|
enableLookups
|
如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip地址
|
redirectPort
|
指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号
|
acceptCount
|
指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
|
connectionTimeout
|
指定超时的时间数(以毫秒为单位)
|
Engine(表示指定service中的请求处理机,接收和处理来自Connector的请求)
|
defaultHost
|
指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的
|
Context(表示一个web应用程序,通常为WAR文件,关于WAR的具体信息见servlet规范)
|
docBase
|
应用程序的路径或者是WAR文件存放的路径
|
path
|
表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/path/****
|
reloadable
|
这个属性非常重要,如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,我们可以在不重起tomcat的情况下改变应用程序
|
host(表示一个虚拟主机)
|
name
|
指定主机名
|
appBase
|
应用程序基本目录,即存放应用程序的目录
|
unpackWARs
|
如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接从WAR文件中运行应用程序
|
Logger(表示日志,调试和错误信息)
|
className
|
指定logger使用的类名,此类必须实现org.apache.catalina.Logger 接口
|
prefix
|
指定log文件的前缀
|
suffix
|
指定log文件的后缀
|
timestamp
|
如果为true,则log文件名中要加入时间,如下例:localhost_log.2001-10-04.txt
|
Realm(表示存放用户名,密码及role的数据库)
|
className
|
指定Realm使用的类名,此类必须实现org.apache.catalina.Realm接口
|
Valve(功能与Logger差不多,其prefix和suffix属性解释和Logger 中的一样)
|
className
|
指定Valve使用的类名,如用org.apache.catalina.valves.AccessLogValve类可以记录应用程序的访问信息
|
directory
|
指定log文件存放的位置
|
pattern
|
有两个值,common方式记录远程主机名或ip地址,用户名,日期,第一行请求的字符串,HTTP响应代码,发送的字节数。combined方式比common方式记录的值更多
|
2008年8月19日
1、Navicat
Navicat是一个强大的MySQL数据库管理和开发工具。Navicat导航为专业开发者提供了一套强大的足够尖端的工具,但它对于新用户仍然是易于学习。Navicat,使用了极好的图形用户界面(GUI),可以让你用一种安全和更为容易的方式快速和容易地创建、组织、存取和共享信息。
用户可完全控制 MySQL 数据库和显示不同的管理资料,包括一个多功能的图形化管理用户和访问权限的管理工具,方便将数据从一个数据库移转到另一个数据库中(Local to Remote、Remote to Remote、Remote to Local),进行档案备份。
下载:
http://www.navicat.com.cn/
2、Mysql Front
一款小巧的管理Mysql的应用程序. 主要特性包括多文档界面, 语法突出, 拖拽方式的数据库和表格, 可编辑/可增加/删除的域, 可编辑/可插入/删除的记录, 可显示的成员, 可执行的SQL 脚本, 提供与外程序接口, 保存数据到CSV文件等。之前用过,好像已经商业化了。
下载:
http://www.mysqlfront.de/download.html
3、SQLyog
一个易于使用的、快速而简洁的图形化管理MYSQL数据库的工具,它能够在任何地点有效地管理你的数据库,而且它本身是完全免费的。
下载:
http://www.webyog.com/
4、EMS MySQL Manager Lite
图形界面的EMS MySQL Manager给您更方便的管理。
下载:
http://www.ems-hitech.com/
5、Mysql Studio
MySQL是一套稳定、小而美的数据库系统,但是它的管理界面却较为薄弱。MySQL Studio是一套图形化界面的MySQL管理与监视系统,方便的浏览与管理数据库、数据表与资料、权限管理、备份还原、资料导入导出、Agent计划任务等等,让你的MySQL变得更完善。
下载:
http://www.mysqlstudio.com/
6、 MySQL Maestro
是一个管理MYSQL数据库的图形化工具。
下载:
http://www.sqlmaestro.com/
2008年8月16日
1、
UltraEdit(简称:UE,下同)必备!因为这个是修改EXE不可缺少的工具,改兵种名字什么的就靠它了。备选工具WinHex,个人觉得比UE还好用……可能是习惯问题。
2、OllyDbg,这个嘛……是反汇编工具,高级修改需要,一般新人又不懂汇编的就无所谓了,备选工具W32dsm。
3、ExeScope,用来修改游戏中对话框和装备显示的,很多人都改了兵种名字,但忘了改这个,导致在游戏中明明没有这个兵种,但装备却是这个兵种的。(举例:说岳-_\\……1.30和11.24版都有这个问题,说岳中的君主类改为豪杰类了,但是在游戏装备列表中依旧是君主,使人看了觉得奇怪。)备选工具ResHacker.exe(全面超越Exescope的工具)。
4、Stud_PE,怕是有很多朋友都没有用这个工具,也不知道这个工具吧,这个是PE综合工具,功能很强大,支持方面很多就不一一详述了。
2008年7月18日
在Web应用程序开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息, 甚至需要直接对JavaServlet Http的请求(HttpServletRequest),响应(HttpServletResponse)操作.
我们需要在Action中取得request请求参数"username"的值:
ActionContext context = ActionContext.getContext();
Map params = context.getParameters();
String username = (String) params.get("username");
ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放放的是Action在执行时需要用到的对象
一般情况,我们的ActionContext都是通过:ActionContext context = (ActionContext) actionContext.get();来获取的.我们再来看看这里的actionContext对象的创建:static ThreadLocal actionContext = new ActionContextThreadLocal();,ActionContextThreadLocal是实现ThreadLocal的一个内部类.ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突.这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.
下面我们看看怎么通过ActionContext取得我们的HttpSession:
Map session = ActionContext.getContext().getSession();
ServletActionContext
ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了我们上面介绍的ActionContext,它提供了直接与JavaServlet相关对象访问的功能,它可以取得的对象有:
1, javax.servlet.http.HttpServletRequest:HTTPservlet请求对象
2, javax.servlet.http.HttpServletResponse;:HTTPservlet相应对象
3, javax.servlet.ServletContext:Servlet 上下文信息
4, javax.servlet.ServletConfig:Servlet配置对象
5, javax.servlet.jsp.PageContext:Http页面上下文
下面我们看看几个简单的例子,让我们了解如何从ServletActionContext里取得JavaServlet的相关对象:
1, 取得HttpServletRequest对象:
HttpServletRequest request = ServletActionContext. getRequest();
2, 取得HttpSession对象:
HttpSession session = ServletActionContext. getRequest().getSession();
ServletActionContext和ActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的原则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问JavaServlet的相关对象.在使用ActionContext时有一点要注意:不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null.
如果我要取得Servlet API中的一些对象,如request,response或session等,应该怎么做?这里的execute不像Struts 1.x的那样在参数中引入."开发Web应用程序当然免不了跟这些对象打交道.在Strutx 2.0你可以有两种方式获得这些对象:非IoC(控制反转Inversion of Control)方式和IoC方式.
非IoC方式
要获得上述对象,关键Struts 2.0中com.opensymphony.xwork2.ActionContext类.我们可以通过它的静态方法getContext()获取当前Action的上下文对象. 另外,org.apache.struts2.ServletActionContext作为辅助类(Helper Class),可以帮助您快捷地获得这几个对象.
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
如果你只是想访问session的属性(Attribute),你也可以通过ActionContext.getContext().getSession()获取或添加session范围(Scoped)的对象.
IoC方式
要使用IoC方式,我们首先要告诉IoC容器(Container)想取得某个对象的意愿,通过实现相应的接口做到这点.具体实现,请参考例6 IocServlet.java.
例6 classes/tutorial/NonIoCServlet.java
package tutorial;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
publicclass NonIoCServlet extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
@Override
public String execute() {
ActionContext.getContext().getSession().put("msg", "Hello World from Session!");
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
StringBuffer sb =new StringBuffer("Message from request: ");
sb.append(request.getParameter("msg"));
sb.append("<br>Response Buffer Size: ");
sb.append(response.getBufferSize());
sb.append("<br>Session ID: ");
sb.append(session.getId());
message = sb.toString();
return SUCCESS;
}
}
例6 classes/tutorial/IoCServlet.java
package tutorial;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
publicclass IoCServlet extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {
private String message;
private Map att;
private HttpServletRequest request;
private HttpServletResponse response;
public String getMessage() {
return message;
}
publicvoid setSession(Map att) {
this.att = att;
}
publicvoid setServletRequest(HttpServletRequest request) {
this.request = request;
}
publicvoid setServletResponse(HttpServletResponse response) {
this.response = response;
}
@Override
public String execute() {
att.put("msg", "Hello World from Session!");
HttpSession session = request.getSession();
StringBuffer sb =new StringBuffer("Message from request: ");
sb.append(request.getParameter("msg"));
sb.append("<br>Response Buffer Size: ");
sb.append(response.getBufferSize());
sb.append("<br>Session ID: ");
sb.append(session.getId());
message = sb.toString();
return SUCCESS;
}
}
例6 Servlet.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h2>
<s:property value="message" escape="false"/>
<br>Message from session: <s:property value="#session.msg"/>
</h2>
</body>
</html>
例6 classes/struts.xml中NonIocServlet和IoCServlet Action的配置
<action name="NonIoCServlet" class="tutorial.NonIoCServlet">
<result>/Servlet.jsp</result>
</action>
<action name="IoCServlet" class="tutorial.IoCServlet">
<result>/Servlet.jsp</result>
</action>
运行Tomcat,在浏览器地址栏中键入http://localhost:8080/Struts2_Action/NonIoCServlet.action?msg=Hello%20World! 或http://localhost:8080/Struts2_Action/IoCServlet.action?msg=Hello%20World!
在Servlet.jsp中,我用了两次property标志,第一次将escape设为false为了在JSP中输出<br>转行,第二次的value中的OGNL为"#session.msg",它的作用与session.getAttribute("msg")等同.
2008年6月23日
准备java运行环境
Tomcat6运行需要Java环境,需要先下载并安装J2SE5.0以上的版本。
下载地址:http://java.sun.com/javase/downloads/index.jsp
注意:tomcat6.0已经不再需要jdk,而只要jre就可以了,因为它采用了自带的Eclipse JDT来编译jsp,而不是jdk。
如果JDK是zip解压,而不是install安装的,请设置系统环境JAVA_HOME:
在桌面上右键点击【我的电脑】,选择【属性】命令,在出现的对话框中选择【高级】选项卡,然后单击【环境变量】按钮,添加一个环境变量:JAVA_HOME,它的值为JDK所在根目录(比如:c:\jdk,而不是c:\jdk\bin)
tomcat下载安装
tomcat下载地址:http://tomcat.apache.org/
右侧有从3.3到6.x各个版本的下载链接。
windows下tomcat的安装很简单,可以采用exe安装包的方式进行安装。基本上一路确定就可以了,安装用到了java环境,从jdk的安装注册表或者JAVA_HOME这个系统变量里面获得jdk所在位置(这就是为什么非安装的jdk需要配置JAVA_HOME的原因,当然在后面tomcat运行时也是需要的)。
安装后的目录如下:
c:\tomcat6.0
|---bin
|---conf
|---lib
|---logs
|---temp
|---webapps
|---work
相比之前的版本,在bin和lib这两个目录改动比较大,bin目录不再有一堆的bat文件,精简为4个文件。而jar文件统一放到新增的lib目录下,先前版本中下面的3个目录被删除合并(参考tomcat5.0.28的结构):
common(含lib,classes,endorsed三个目录)
share(含lib和classes两个目录)
server(含lib,classes,webapps三个目录)
此外,examples增加了
启动运行tomcat
安装的最后一个步骤,可以选择立即启动;
默认情况下,是通过系统的服务进行启动的,可以把启动方式设置为“自动”
命令行启动:
tomcat/bin/tomcat6 或者tomcat/bin/tomcat6 //TS//tomcat6(注意大写!下同) 二者是等价的。
其他的参数还有:
tomcat/bin/tomcat6 //RS//tomcat6 ---启动tomcat6服务
tomcat/bin/tomcat6 //US//tomcat6 ---更新tomcat6服务参数
tomcat/bin/tomcat6 //IS//tomcat6 ---安装tomcat6服务
tomcat/bin/tomcat6 //DS//tomcat6 ---删除tomcat6服务
安装后的bin目录共有一下几个文件:
bootstrap.jar
tomcat-juli.jar
tomcat6.exe
tomcat6w.exe
其中tomcat6w.exe是监控tomcat运行的,可以直接运行,或者缩小到屏幕右下角成为一个小图标。
直接运行tomcat6w.exe或者“tomcat6w //ES//” 都可以进入监控配置窗口;
或者运行“tomcat6w //MS//”把它缩小到右下角。
web访问测试
启动后,可以通过浏览器进行访问,测试运行是否正常。
用IE或者Firefox等浏览器,输入地址:
http://localhost:8080/ --如果安装时修改了端口,请把8080用修改后的值替换。
如果能够正常浏览到tomcat欢迎信息,就是正确了,否则就要检查安装是否正确、防火墙的设置等。
经常遇到的一个问题是端口冲突,最常见的就是80端口被占用,导致服务无法正常启动。如果通过tomcat6 //TS//tomcat6来启动,马上就能够发现提示信息。修改一下tomcat6\conf\server.xml中的端口就能够解决。
通常使用80端口的有:
1. IIS服务器,因为在windows服务器上,很多都安装了IIS,而IIS默认的端口就是80.
2. skype即时聊天工具,skype的可以穿透防火墙的本领,也是通过占用80端口实现的。
查看端口占用的命令:
进入windows命令行,输入:
netstat -an
这个命令返回有4列:protocol协议、local address本机地址、foreign address来访者地址、status状态
浏览本机地址一列,可以看到当前主机对外服务的IP地址、端口都有哪些。
如果一台机器有192.168.1.100和192.168.1.101两个地址,那么:
0.0.0.0:80表示这台机器上所有80端口都被使用
127.0.0.1:80表示127.0.0.1的80被使用,但.100和.101IP地址的80还未使用。
192.168.1.100:80表示.100IP地址的80端口被使用
192.168.1.101:80表示.101IP地址的80端口被使用
想知道哪个程序使用了某个端口,可以通过天网防火墙或者是卡巴斯基获得。
Tomcat.5.5.16 安装 web 项目时执行的代码主要是 HostConfig 类,其中 deployApps() 执行部署 web 应用的功能;
protected void deployApps() {
File appBase = appBase();
File configBase = configBase();
// Deploy XML descriptors from configBase
deployDescriptors(configBase, configBase.list());
// Deploy WARs, and loop if additional descriptors are found
deployWARs(appBase, appBase.list());
// Deploy expanded folders
deployDirectories(appBase, appBase.list());
}
从上面这段代码,我们可以知道 tomcat 在部署 web 项目是按如下顺序依次部署的;
1.首先部署 $CATALINA_HOME/conf/Catalina/localhost 目录下面的 .xml 文件;
deployDescriptors(configBase, configBase.list());
(1)configBase 的值是通过调用 configBase() 获取的,
File file = new File(System.getProperty("catalina.base"), "conf");
Container parent = host.getParent();
if ((parent != null) && (parent instanceof Engine)) {
file = new File(file, parent.getName());
}
file = new File(file, host.getName());
可以看出 configBase 是由四部分内容组成 ;
System.getProperty("catalina.base") + “conf” + parent.getName()+host.getName()
parent.getName() 和 host.getName() 是分别取 server.xml 中
<Engine name="Catalina" defaultHost="localhost"> 和
<Host name="localhost" appBase="webapps" … 对应的 name 属性值;
由此可以得出 configBase 的值为 $CATALINA_HOME/conf/Catalina/localhost
(2) 按文件名顺序依次读取 configBase 目录下面的 xml 文件部署 web 应用;
第一步,首先获取文件名(不包含 .xml )作为上下文路径
String nameTmp = files[i].substring(0, files[i].length() - 4);
String contextPath = "/" + nameTmp.replace('#', '/');
第二步,解析 xml 文件,分析 docBase 的值;
注意这里的 docBase 的判断很重要,采用和以前版本完全不同的做法;
if (!docBase.isAbsolute()) {
docBase = new File(appBase(), context.getDocBase());
}
首先判断 docBase 是否为绝对路径,如果不是绝对路径,在改为
$CATALINA_HOME/webapps+docBase
// If external docBase, register .xml as redeploy first
if(!docBase.getCanonicalPath().startsWith(appBase().getAbsolutePath()))
{
// 这个判断很重要,这里是判断如果 docBase 路径是以
$ CATALINA_HOME/webapps+docBase 开头的字符串,则忽略掉了
isExternal = true;
...
if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) {
isWar = true;
}
} else{
// Ignore specified docBase
context.setDocBase(null);
}
从上面可以看出, <Context path="/xxxx" docBase="xxxx" . 中 docBase 只有为绝对路径并且该路径不是以 $CATALINA_HOME/webapps 开头,才会生效;否则就忽略掉了;
2.接下来部署 $CATALINA_HOME/webapps/ 目录下以。 War 结尾的文件
deployWARs(appBase, appBase.list());
(1) 首先仍是把文件名 ( 不用 .war) 作为其应用的上下文路径 ;
if (files[i].toLowerCase().endsWith(".war")) {
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i];
int period = contextPath.lastIndexOf(".");
(2) 接下来判断以该上下文路径 contextPath 是否已经装载过了,如果是则直接退出; if (deploymentExists(contextPath))
return;
( 3 ) 继续判断以该上下文命名的部署文件是否存在,如 war 文件为 AAA.war, 则判断在 $CATALINA_HOME/conf/Catalina/localhost/AAA.xml 文件是否存在,如果不存在继续执行以下操作;
File xml = new File
(configBase, file.substring(0, file.lastIndexOf(".")) + ".xml");
if (deployXML && !xml.exists()) {
entry = jar.getJarEntry(Constants.ApplicationContextXml);
configBase.mkdirs();
。。。
先从 wart 文件中读取 META-INF/context.xml 文件,然后把它 copy 到
$CATALINA_HOME/conf/Catalina/localhost/AAA.xml, 注意 war 文件部署文件必须为
context.xml ,且在 META-INF 目录下;
( 4 )接下来操作和上面类似,部署该 web 应用;
3. 最后是以 $CATALINA_HOME/webapps 目录下的文件夹为目标按文件夹名顺序进行部署;
deployDirectories(appBase, appBase.list());
(1)同样先把该文件夹名作为上下文路径进行部署;
File dir = new File(appBase, files[i]);
if (dir.isDirectory()) {
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i];
(2)接下来的步骤就基本上是一样了,首先判断该上下文路径是否已经部署过,如果是则直接退出,否则和上面一样,读取 META-INF/context.xml 文件进行部署;
注意这里和上面的 war 文件部署稍微有点不同,就是它不会 copy 部署文件 context.xml 文件到 $CATALINA_HOME/conf/Catalina/localhost 中去;
TOMCAT部署项目有3种方法:1、直接把项目web文件夹放在webapps里2、修改conf里server.xml文件,添加一个Context,
<Context path="/projectName" reloadable="true" docBase="工程所在路径\web" workdir="工程所在路径\work"></Context>3、在Catalina/localhost目录里,新增一个xml文件,添加一个Context内容,指向项目的目录。<Context path="/目录名" docBase="e:\example" debug="0" reloadable="true" />
优先级别为:3>2>1
第3个方法有个优点,可以定义别名。服务器端运行的项目名称为path,外部访问的URL则使用XML的文件名。这个方法很方便的隐藏了项目的名称,对一些项目名称被固定不能更换,但外部访问时又想换个路径,非常有效。
第2、3还有优点,可以定义一些个性配置,如数据源的配置等
<Server port="8005" shutdown="SHUTDOWN" debug="0">
<!-- 这些指令组件关闭JMX MBeans支持 -->
<!-- 你也可以通过包含你自己的mbean描述文件配置自定义的组件,然后设置
“descriptors”属性为以“;”为分隔的文件名列表严将它添加到默认列表
中,例如:descriptors="/com/myfirm/mypackage/mbean-descriptor.xml"。
-->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0" />
<!-- Global JNDI resources -->
<!-- 全局JNDI资源 -->
<GlobalNamingResources>
<!-- 出于示例目的的测试入口 -->
<Environment name="simpleValue" type="java.lang.Integer" value="30" />
<!-- 可编辑的,用来通过UserDatabaseRealm认证用户的用户数据库 -->
<Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved">
</Resource>
<ResourceParams name="UserDatabase">
<parameter>
<name>factory</name>
<value>org.apache.catalina.users.MemoryUserDatabaseFactory</value>
</parameter>
<parameter>
<name>pathname</name>
<value>conf/tomcat-users.xml</value>
</parameter>
</ResourceParams>
</GlobalNamingResources>
<!-- 一个“Service”是一个或多个共用一个单独“Container”(容器)的“Connectors”
组合(因此,应用程序在容器中可见)。通常,这个容器是一个“Engine”
(引擎),但这不是必须的。
注意:一个“Service”自身不是一个容器,因此,在这个级别上你不可定义
诸如“Valves”或“Loggers”子组件。
-->
<!-- 定义Tomcat的标准独立服务 -->
<Service name="Catalina">
<!-- 一个“Connector”(连接器)代表一个请求被接收和应答所需要的端点。每个连
接器通过相关的“Container”(容器)处理请求。
默认情况下,一个非SSL的HTTP/1.1的连接器被绑定在端口8080。你也可以通过
根据后面的使用说明并取消第二个连接器入口的注释,在端口8443上建立一个
SSL HTTP/1.1的连接器。开放SSL支持需要下面几步(参见Tomcat 5文档中怎样
配置SSL的说明以取得更多的详细信息):
* 如果你的JDK是1.3或1.3以前的版本,下载安装JSSE 1.0.2或以后版本,并放
置JAR文件到“$JAVA_HOME/jre/lib/ext”目录下。
* 带一个“changeit”的口令值执行:
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA (UNIX)
来生成它自己的证书私钥。
默认情况下,当一个web应用程序调用请求时,DNS查询是可行的。这将对性能造
成一些不利的影响,因此,你可以将“enableLookups”设置为“false”来关闭DNS
查询。当DNS查询被关闭时,request.getRemoteHost()将返回包含远程客户IP地
址的字符串。
-->
<!-- 在8080端口上定义一个非SSL的HTTP/1.1连接器 -->
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000" disableUploadTimeout="true" />
<!-- 注意,要关闭连接超时,将connectionTimeout设置为0 -->
<!-- 注意:要使用gzip压缩需要设置如下属性:
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla,traviata"
compressableMimeType="text/html,text/xml"
-->
<!-- 在端口8443上定义一个SSL的HTTP/1.1的连接器 -->
<!--
<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
<!-- 在端口8009上定义一个Coyote/JK2 AJP 1.3连接器 -->
<Connector port="8009" enableLookups="false" redirectPort="8443"
debug="0" protocol="AJP/1.3" />
<!-- 在8082端口上定义一个代理HTTP/1.1连接器 -->
<!-- 参见代理文档以取得这里使用属性的更多的信息。 -->
<!--
<Connector port="8082"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false"
acceptCount="100" debug="0" connectionTimeout="20000"
proxyPort="80" disableUploadTimeout="true" />
-->
<!-- 一个“Engine”(引擎)代表处理每个请求的入口点(在Catalina内)。这个Tomcat
的标准独立引擎实现分析包含在请求中的HTTP头信息,并将请求传送到适当的主机
或虚拟主机上。-->
<!-- 你应该这样设置jvmRoute以便在JK/JK2通道上支持负载平衡:
<Engine name="Standalone" defaultHost="localhost" debug="0" jvmRoute="jvm1">
-->
<!-- 在我们的容器体系中定义最高级别的容器 -->
<Engine name="Catalina" defaultHost="localhost" debug="0">
<!-- 请求转储器值转储非常有用的通过Tomcat这个实例接收到的所有请求的,关于
接收到的请求头和cookies,以及发送出的回应头和cookies的调试信息。如果
你只在意一个特定的虚拟主机或者一个特定应用程序的请求,在对应的<Host>
或<Context>入口中套用这个元素。
对于所有的Servlet(小服务程序)2.4来所,在示例程序中检验
“RequestDumperFilter”过滤是非常容易的(这个过滤器源代码可以在
“$CATALINA_HOME/webapps/examples/WEB-INF/classes/filters”下找到。
请求转储默认情况下是关闭的,如果要使用它,取消下面行的注释符。-->
<!--
<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
-->
<!-- 全局日志设置,除非在更低的级别上覆盖它的设置 -->
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="catalina_log." suffix=".txt" timestamp="true" />
<!-- 因为这个Realm(区域)在这儿,因此这个实例将被全局共享。 -->
<!-- 这个Realm(区域)使用在全局JNDI资源下,由“UserDatabase”配置的用户
数据库。通过使用Realm将使对于这个用户数据库的任何编辑都将会立即可用
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
debug="0" resourceName="UserDatabase"/>-->
<!-- 注释掉旧有的Realm以便我们能很快速的恢复旧有配置。 -->
<!--
<Realm className="org.apache.catalina.realm.MemoryRealm" />
-->
<!-- 下面的属性用于从储存在数据库或从JDBC通道中得到的Realm以取代上面的
Realm配置。-->
<!--
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@ntserver:1521:ORCL"
connectionName="scott" connectionPassword="tiger"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
-->
<!--
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
driverName="sun.jdbc.odbc.JdbcOdbcDriver"
connectionURL="jdbc:odbc:CATALINA"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
-->
<!-- 定义默认的虚拟主机
注意:XML模式确认将不能与Xerces 2.2同工作。
-->
<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<!--
为这个结点定义一个群集,通过定义这个元素,意味着每个管理员都将被改变。
因此,当运行一个群集时,只有确认在必须被聚集和移除其他的地方有你的
web软件。
一个群集有下面这些参数:
className = 这个群集类的全限定名
name = 你的群集的描述名,可以是任何描述
debug = 调试级别,更高意味着更多的输出
mcastAddr = 多播地址,所有的节点都必须有同样的多播地址
mcastPort = 多播端口,对所有的节点都必须有同样的多播端口
mcastBindAddr = 绑定多播套接字到一个指定的地址
mcastTTL = 多播生存期,如果你想要限制你的广播的话
mcastSoTimeout = 多播读取超时
mcastFrequency = 发送“I'm alive”(我还活着)信息的间隔毫秒数
mcastDropTime = 多长时间没有收到“I'm alive”就将这个节点标识为死节点(单位:毫秒)
tcpThreadCount = 用于处理重复引入请求的线程数,最好是每个节点都有相同的线程数
tcpListenAddress = 在有多块以太网卡的主机上的监听TCP群集请求的地址(绑定地址),auto意味着地址由InetAddress.getLocalHost().getHostAddress()取得。
tcpListenPort = tcp监听端口
tcpSelectorTimeout = 在操作系统中有java.nio唤醒错的情况下,使用Selector.select()的超时
毫秒数。设为0则没有超时限制
printToScreen = true意味着管理员的相关信息也将打印输出到std.out
expireSessionsOnShutdown = true 意味着
useDirtyFlag = true意味着我们只能在调用setAttribute,removeAttribute后才能复制一个会话;
false意味着在每个请求后复制会话。
false意味着复制将以下列代码方式工作:
<%
HashMap map = (HashMap)session.getAttribute("map");
map.put("key","value");
%>
replicationMode = 可以是“pooled”、“synchronous”或者“asynchronous”
* Pooled意味着在多个套接字上同步进行复制。例如,先复制数据,然后请求返回。
这与“synchronous”相同,除了它使用一个套接字池,因此,它是多线程的。它是
最快和最高级的设置,使用这个配置也增加了处理复制的tcp线程的域。
* Synchronous指执行请求的线程,它也是向其他节点复制数据的线程,并且直到
所有的节点都己经收到信息后才返回。
* Asynchronous,对每个群集节点而言,这是一个特别的“sender”(发送者)线程,
因此请求线程将复制请求排队到一个小队列中,然后,返回给用户。
这个小队列是一个当会话被添加到队列中,而从先前的请求中,同一个会话己经存在
,这个会话将被放置在队列中以代替重复的两个请求。这几乎从不会发生,除非存在
较大的网络延迟。
-->
<!-- 当配置群集时,你也添加一个值来捕获所有传入的请求,在请求结束时,这个会话可能被子复制,
也可能不被复制。一个会话是否复制取决于下列条件是否发生:
1. useDirtyFlag为真,或者setAttribute或者removeAttribute己经被调用。
2. 会话己经存在(己经被创建了)。
3. 请求没有被“filter”属性所捕获。
这个filter(过滤器)属性用于过滤那些不能修改会话的请求,因此,我们在这个请求结束后不复制
会主。这个过滤器是消极的,例如,你向过滤器发送了一些东西,然后被过滤出去,在那个匹配的过
滤器上不会发生复制。
过滤器属性以分号为分隔,因此你不能换行,即使你想这么做。
filter=".*\.gif;.*\.js;"意味着在进行以.gif和.js结束的URI请求后不复制会话。
-->
<!--
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4001"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"/>
</Cluster>
-->
<!-- 通常,对每一个应用程序,用户必须逐个的认证他们自己。当他们遇到被
某种安全约束所保护的资源时,如果你想让用户只在第一次被认证,那么,
取消下面入口行的注释,然后在这个虚拟主机中包含这个用户的,横跨所有
web应用程序的用户身份识别。-->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn"
debug="0"/>
-->
<!-- 这个虚拟主机的所有请求的访问日志过程。默认情况下,日志文件被创建在相对
于$CATALINA_HOME目录下的logs目录下。通过directory属性,你也可以指定一个
不同的目录,如果你想的话。可以使用相对路径(相对于$CATALINA_HOME),也
可以使用绝对路径。-->
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="common" resolveHosts="false"/>
-->
<!-- 与这个虚拟主机有关系所有上下文所共享的日志。默认情况下(使用FileLogger时),
日志文件被创建在相对于$CATALINA_HOME目录下的logs目录下。如果你希望,你也可
以给directory指定一个不同的路径。可以使用相对于$CATALINA_HOME的相对路径,也
可以使用绝对路径。-->
<Logger className="org.apache.catalina.logger.FileLogger" directory="logs"
prefix="localhost_log." suffix=".txt" timestamp="true" />
<Context path="web上下文路径" docBase="虚拟目录路径" reloadable="true" debug="0"> </Context>
</Host>
</Engine>
</Service>
</Server>
在tomcat文件夹的conf\catalina\localhost(对于Tomcat6版本及其以上,需要自己创建catalina和localhost这两个文件夹)
增加project .xml文件(该文件名的project要和下面的“path=“/xxx"”的xxx相同)
文件内容:
<Context path="/project" reloadable="true" docBase="E:\javastudio\oob" workDir="E:\javastudio\oob\work" />
docBase是项目文件夹的web-inf文件夹的上一层目录 workDir是指Tomcat解析Jsp转换为Java文件,并编译为class存放的文件夹,设置在项目文件夹里面,可以避免移植到其他地方首次读取jsp文件需要重新解析 。一般格式:项目文件夹\work reloadable是指可以重新加载,一般设置为true,方便使用,不需要经常重启Tomcat。 以后启动Tomcat,在浏览器输入http://localhost:8080/project就能访问该项目的welcome文件。
***************
为什么要不修改server.xml呢?在Tomcat6的doc帮助文档中,官方是不提倡修改server.xml来添加虚拟目录的!
而我认为,以上使用的方法,非常方便于项目的移植,移植后,只有修改docBase和workDir的值就行了,甚至可以去掉workDir这个属性