|
2008年8月21日
1. Change to aliyun repository 2. Chinese input method sudo apt-get install ibus-pinyin
#remmeber to logout and re-logon to change system 'Region&Language' setting 3. Shadowsocks and genpac sudo apt install -y shadowsocks-libev
#sudo vi /etc/shadowsocks-libev/shadowsock.json { "server":"x.x.x.x", "server_port":xx, "local_port":1080, "password":"xxxxx", "timeout":60, "method":"aes-256-cfb" }
nohup ss-local -c /etc/shadowsocks-libev/shadowsock.json >/dev/null 2>&1 & sudo apt install phython-pip sudo -H pip install genpac
如果pip error "TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'" sudo python -m pip install --upgrade --force pip
mkdir pac cd pac touch user-rules.txt
genpac --pac-proxy "SOCKS5 127.0.0.1:1080" --gfwlist-proxy="SOCKS5 127.0.0.1:1080" --output="autoproxy.pac" --gfwlist-url="https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt" --user-rule-from="user-rules.txt" 配置系统自动代理为: /home/xxx/pac/autoproxy.pac 4. JDK8
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html download and setup environment variable manually
5.gcloud
http://ubuntuhandbook.org/index.php/2014/10/google-cloud-sdk-made-into-canonical-partners-repository/
官方说明: http://source.android.com/source/initializing.html
环境:
Ubuntu 12.04 64bit
JDK6(installation: http://www.gaggl.com/2012/04/installing-java6-jdk-on-ubuntu-12-04/)
$ make -v
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
$ python -V
Python 2.7.3
android 当前 mainfest version: 4.2
按照官方说明从下载到运行emulator,没有nexus,所以没做实际机器烧录。步骤请根据官方说明做,以下只列出过程遇到的问题: 1.repo sync 经常出现断线,网上有很多参考办法,我是每次忽略这些错误,直到运行完毕退出,我再重新运行: repo sync -f 知道所有代码下载完毕(4.2的有16G) 2.每次跑emulator都要cd到代码目录先进行环境初始化 source build/envsetup.sh lunch full-eng 3.emulator出错 $ emulator emulator: WARNING: system partition size adjusted to match image file (229 MB > 200 MB)
Spring 声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的 try… catch … finally 代码。 我们在使用 Spring 声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划分时,需要进行事务定义,也就是配置事务的属性。 Spring 在 TransactionDefinition 接口中定义这些属性 , 以供 PlatfromTransactionManager 使用 , PlatfromTransactionManager 是 spring 事务管理的核心接口。 l getTimeout() 方法,它返回事务必须在多少秒内完成。 l isReadOnly() , 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。 l getIsolationLevel() 方法返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。 在 TransactionDefinition 接口中定义了五个不同的事务隔离级别: l ISOLATION_DEFAULT 这是一个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别 . 另外四个与 JDBC 的隔离级别相对应 l ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。 例如 : Mary的原工资为 1000, 财务人员将 Mary 的工资改为了 8000 ,但未提交事务 与此同时, Mary正在读取自己的工资 Mary 发现自己的工资变为了 8000 ,欢天喜地! 而财务发现操作有误,而回滚了事务 ,Mary 的工资又变为了 1000. 像这样 ,Mary 记取的工资数 8000 是一个脏数据。 l ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。 l ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生 ( 不可重复读 ) 。 在事务 1 中, Mary 读取了自己的工资为 1000, 操作并没有完成 在事务 2 中,这时财务人员修改了 Mary 的工资为 2000, 并提交了事务 . 在事务 1 中,Mary 再次读取自己的工资时,工资变为了 2000 在一个事务中前后两次读取的结果并不致,导致了不可重复读。 使用 ISOLATION_REPEATABLE_READ 可以避免这种情况发生。 l ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。 目前工资为 1000 的员工有 10人。 事务 1, 读取所有工资为 1000 的员工。 共读取 10 条记录 这时另一个事务向 employee表插入了一条员工记录,工资也为 1000 事务 1 再次读取所有工资为 1000 的员工 共读取到了 11 条记录,这就产生了幻像读。 ISOLATION_SERIALIZABLE 能避免这样的情况发生。但是这样也耗费了最大的资源。 getPropagationBehavior () 返回事务的传播行为,由是否有一个活动的事务来决定一个事务调用。 在 TransactionDefinition 接口中定义了七个事务传播行为: l PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。 使用 spring 声明式事务, spring 使用 AOP 来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。 单独调用 methodB 方法 相当于 Spring 保证在 methodB 方法中所有的调用都获得到一个相同的连接。在调用 methodB 时,没有一个存在的事务,所以获得一个新的连接,开启了一个新的事务。 单独调用 MethodA 时,在 MethodA 内又会调用 MethodB. 执行效果相当于 调用 MethodA 时,环境中没有事务,所以开启一个新的事务 . 当在 MethodA 中调用MethodB 时,环境中已经有了一个事务,所以 methodB 就加入当前事务。 l PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器, PROPAGATION_SUPPORTS 与不使用事务有少许不同。 单纯的调用 methodB 时, methodB 方法是非事务的执行的。 当调用 methdA时 ,methodB 则加入了 methodA 的事务中 , 事务地执行。 l PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。 当单独调用 methodB 时,因为当前没有一个活动的事务,则会抛出异常 throw new IllegalTransactionStateException("Transaction propagation ''mandatory'' but no existing transaction found"); 当调用 methodA 时, methodB 则加入到 methodA 的事务中,事务地执行。 l PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。 当单独调用 methodB 时,相当于把 methodb 声明为 REQUIRED 。开启一个新的事务,事务地执行。 当调用 methodA 时 情况有些大不一样 . 相当于下面的效果。 在这里,我把 ts1 称为外层事务, ts2 称为内层事务。从上面的代码可以看出, ts2 与ts1 是两个独立的事务,互不相干。 Ts2 是否成功并不依赖于 ts1 。如果 methodA 方法在调用 methodB 方法后的 doSomeThingB 方法失败了,而 methodB 方法所做的结果依然被提交。而除了 methodB 之外的其它代码导致的结果却被回滚了。 使用PROPAGATION_REQUIRES_NEW, 需要使用 JtaTransactionManager 作为事务管理器。 l PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。 当单独调用 methodB 时,不启用任何事务机制,非事务地执行。 当调用 methodA 时,相当于下面的效果 使用 PROPAGATION_NOT_SUPPORTED, 也需要使用 JtaTransactionManager 作为事务管理器。 l PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常 单独调用methodB ,则非事务的执行。 调用 methodA 则会抛出异常 l PROPAGATION_NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中 . 如果没有活动事务 , 则按 TransactionDefinition.PROPAGATION_REQUIRED 属性执行 这是一个嵌套事务 , 使用 JDBC 3.0 驱动时 , 仅仅支持 DataSourceTransactionManager 作为事务管理器。需要 JDBC 驱动的 java.sql.Savepoint 类。有一些 JTA 的事务管理器实现可能也提供了同样的功能。 使用 PROPAGATION_NESTED ,还需要把 PlatformTransactionManager 的nestedTransactionAllowed 属性设为 true; 而 nestedTransactionAllowed 属性值默认为false; 如果单独调用 methodB 方法,则按 REQUIRED 属性执行。 如果调用 methodA 方法,相当于下面的效果 当 methodB 方法调用之前,调用 setSavepoint 方法,保存当前的状态到 savepoint 。如果 methodB 方法调用失败,则恢复到之前保存的状态。但是需要注意的是,这时的事务并没有进行提交,如果后续的代码 (doSomeThingB() 方法 ) 调用失败,则回滚包括 methodB 方法的所有操作。 嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。 PROPAGATION_NESTED 与 PROPAGATION_REQUIRES_NEW 的区别: 它们非常类似 , 都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW 时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务这是一个真正的嵌套事务。同时它需要 JTA 事务管理器的支持。 使用 PROPAGATION_NESTED 时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。 DataSourceTransactionManager 使用 savepoint 支持PROPAGATION_NESTED 时,需要 JDBC 3.0 以上驱动及 1.4 以上的 JDK 版本支持。其它的JTA TrasactionManager 实现可能有不同的支持方式。 PROPAGATION_REQUIRED 应该是我们首先的事务传播行为。它能够满足我们大多数的事务需求。
参考这篇文章: http://blog.csdn.net/bluishglc/article/details/6632280 一。Maven的执行方式 maven对构建(build)的过程进行了抽象和定义,这个过程被称为构建的生命周期(lifecycle)。生命周期(lifecycle)由多个阶段(phase)组成,每个阶段(phase)会挂接一到多个goal。goal是maven里定义任务的最小单元,goal分为两类,一类是绑定phase的,就是执行到某个phase,那么这个goal就会触发,另外一类不绑定,就是单独任务,这就相当于ant里的target。
1。以phase来构建 例如: mvn clean mvn compile mvn test mvn package 表明maven会执行到某个生命周期(lifecycle)的某个阶段(phase) 这个phase以及它前面所有phase绑定的目标(goal)都会执行, 每个phase都会邦定maven默认的goal或者没有goal, 或者自定义的goal。 也可以通过传入参数跳过(skip)某些phase,例如: mvn install -Dmaven.test.skip=true 1。以goal来构建 这类就是没有绑定phase的goal,但是这类goal却通常会有个执行前提,就是project必须执行到某个phase, 那么执行这个goal,其实也会触发maven执行到前提要求的phase。 例如jetty:run是个非绑定phase的goal,它的前提是 test-compile,这个前提是由plugin的代码逻辑制定的/** * @goal run * @requiresDependencyResolution runtime * @execute phase="test-compile" * @description Runs jetty6 directly from a maven project */ public class Jetty6RunMojo extends AbstractJettyRunMojo { ... }
二。Maven lifecycle, phase概览 Maven预设了三个Lifecycle ,各包含了下列Phases.- Clean Lifecycle
- Default Lifecycle
- validate
- initialize
- generate-sources
- process-sources
- generate-resources
- process-resources
- compile
- process-classes
- generate-test-sources
- process-test-sources
- process-test-resources
- test-compile
- process-test-classes
- test
- prepare-package
- package
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install
- deploy
- Site Lifecycle
- pre-site
- site
- post-site
- site-deploy
1.Window
- java -classpath .;jar1;jar2 MainClass
注意: -classpath参数必须放于前面。
- java -jar jar1
jar包的MANIFEST.MF文件:
Manifest-Version: 1.0
Main-Class: com.Main1
Class-Path: jar1.jar;jar2.jar
注意: 使用-jar参数,那么主jar包必须含有MANIFEST.MF信息,并且指定Main-Class & Class-Path。命令行的-classpath参数将被忽略
2.Linux 区别: 目录分隔符由\变成/ jar包分隔符由;变成: Window测试环境是Sun java version "1.6.0_14" 其他版本没有验证
1.绑定本地接口,自动生成代理对象 复制下面链接代码 // Endpoint Address String endpointAddress = "http://localhost:8111/helloWorld"; // Add a port to the Service service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress); HelloService hw = service.getPort(HelloService.class);
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8888
Java Keytool Commands for Creating and ImportingThese commands allow you to generate a new Java Keytool keystore file, create a CSR, and import certificates. Any root or intermediate certificates will need to be imported before importing the primary certificate for your domain. - Generate a Java keystore and key pair
keytool -genkey -alias mydomain -keyalg RSA -keystore keystore.jks -keysize 2048 - Generate a certificate signing request (CSR) for an existing Java keystore
keytool -certreq -alias mydomain -keystore keystore.jks -file mydomain.csr - Import a root or intermediate CA certificate to an existing Java keystore
keytool -import -trustcacerts -alias root -file Thawte.crt -keystore keystore.jks - Import a signed primary certificate to an existing Java keystore
keytool -import -trustcacerts -alias mydomain -file mydomain.crt -keystore keystore.jks - Generate a keystore and self-signed certificate (see How to Create a Self Signed Certificate using Java Keytool for more info)
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048
Java Keytool Commands for CheckingIf you need to check the information within a certificate, or Java keystore, use these commands. - Check a stand-alone certificate
keytool -printcert -v -file mydomain.crt - Check which certificates are in a Java keystore
keytool -list -v -keystore keystore.jks - Check a particular keystore entry using an alias
keytool -list -v -keystore keystore.jks -alias mydomain
Other Java Keytool Commands- Delete a certificate from a Java Keytool keystore
keytool -delete -alias mydomain -keystore keystore.jks - Change a Java keystore password
keytool -storepasswd -new new_storepass -keystore keystore.jks - Export a certificate from a keystore
keytool -export -alias mydomain -file mydomain.crt -keystore keystore.jks - List Trusted CA Certs
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts - Import New CA into Trusted Certs
keytool -import -trustcacerts -file /path/to/ca/ca.pem -alias CA_ALIAS -keystore $JAVA_HOME/jre/lib/security/cacerts
第一种方式:适合于全部HTML标签
<acronym title="World Wide Web">
WWW
</acronym>
第二种方式:IMG之类的标签例如:
<img src="#" alt="鼠标移动到上方会显示并且未加载图片时也会显示">
第三种方式:input之类的标签例如:
<input type="button" value="确定" title="鼠标移动到上方会显示并且未加载图片时也会显示">
|
第一:简单的使用axis2包自己实现调用
package common;
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class WebServiceUtils
{
// ----------------------------------------------------- Properties
public static int TIMEOUT = 100000;
// ----------------------------------------------------- Constructors
// ----------------------------------------------------- Methods
/**
*
* 调用axis2的webservice的方法
*
* @return
*/
@SuppressWarnings("unchecked")
static public Object[] invokeWebService( String url, String nameSpace, String method, Object[] args, Class[] returnTypes )
throws AxisFault
{
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
EndpointReference targetEPR = new EndpointReference( url );
options.setTo( targetEPR );
options.setTimeOutInMilliSeconds( TIMEOUT );
QName opName = new QName( nameSpace, method );
Object[] results = serviceClient.invokeBlocking( opName, args, returnTypes );
return results;
}
}
第二:
public static OMElement getEchoOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("echo", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Echo String "));
method.addChild(value);
return method;
}
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setAction("urn:echo");
//Blocking invocation
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
System.out.println(result);
System.out.println(options.getTo());
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
第三:
利用插件生成客户端
private static String URL="http://localhost:8080/axis2/services/WeatherService";
public static void main(String[] args) throws RemoteException {
try {
WeatherServiceStub stub;
if (args != null && args.length != 0) {
stub = new WeatherServiceStub(args[0]);
} else {
stub = new WeatherServiceStub(URL);
}
WeatherServiceStub.SetWeather setWether = new WeatherServiceStub.SetWeather();
WeatherServiceStub.Weather wether = new WeatherServiceStub.Weather();
wether.setForecast("east");
wether.setRain(true);
wether.setTemperature(12.3f);
wether.setForecast("big");
setWether.setWeather(wether);
stub.setWeather(setWether);
WeatherServiceStub.GetWeatherResponse gw = new WeatherServiceStub.GetWeatherResponse();
System.out.println(gw.get_return());
} catch (AxisFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
本文部分来自CSDN博客,转载请标明出处:http://blog.csdn.net/yhhah/archive/2009/05/07/4158487.aspx
IE的 script 元素支持onreadystatechange事件,不支持onload事件。
FF的script 元素不支持onreadystatechange事件,只支持onload事件。
如果要在一个<script src="xx.js"> 加载完成执行一个操作,FF使用onload事件就行了,IE下则要结合onreadystatechange事件和this.readyState
var loadScript = function(fileName,callback) {
var scriptTag = document.createElement("script");
scriptTag.src = fileName;
document.body.appendChild(scriptTag);
if (callback) {
scriptTag.onload = callback;//ff
scriptTag.onreadystatechange = function()//ie
{
if (scriptTag.readyState == "loaded") {
callback();
}
}
}
}
关键是查询v$locked_object
select sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
lo.locked_mode
from v$locked_object lo,
dba_objects ao,
v$session sess
where ao.object_id = lo.object_id and lo.session_id = sess.sid;
或者
select * from v$session t1, v$locked_object t2 where t1.sid = t2.SESSION_ID;
杀掉进程:
alter system kill session 'sid,serial#';
--创建临时表空间
create temporary tablespace dbuser_temp
tempfile 'D:\oracle\product\10.1.0\oradata\btx\dbuser_temp01.dbf'
size 32m
autoextend on
next 32m maxsize 2048m
extent management local;
--创建数据表空间
create tablespace dbuser_data
logging
datafile 'D:\oracle\product\10.1.0\oradata\btx\dbuser_data01.dbf'
size 32m
autoextend on
next 32m maxsize 2048m
extent management local;
--或者自己控制增长规则
--pctincreate表示下一次增长是前一次增长的110%
create tablespace dbuser_data logging datafile 'D:/oracle/product/10.1.0/oradata/btx/DBUSER_DATA01.DBF' size 32m autoextend on next 5m maxsize unlimited default storage (initial 32m next 5m pctincrease 10);
--修改表空间
alter tablespace dbuser_data add datafile 'D:/oracle/product/10.1.0/oradata/btx/DBUSER_DATA02.DBF' size 32m autoextend on next 5m maxsize unlimited;
--创建用户与指定默认数据表空间与默认临时表空间
create user dbuser identified by dbuser
default tablespace dbuser_data
temporary tablespace dbuser_temp;
--修改用户表空间
alter user dbuser default tablespace dbuser_data temporary tablespace dbuser_temp;
--为用户赋权
grant connect,resource to dbuser;
修改表空间
查询oracle表空间使用状况
SELECT b.tablespace_name "表空间名",total 表空间大小,free 表空间剩余大小,
(total-free) 表空间使用大小,
ROUND((total-free)/total,4)*100 "使用率 %"
FROM (SELECT tablespace_name,SUM(bytes) free FROM DBA_FREE_SPACE
GROUP BY tablespace_name ) a,
(SELECT tablespace_name,SUM(bytes) total FROM DBA_DATA_FILES
GROUP BY tablespace_name) b
WHERE a.tablespace_name=b.tablespace_name ;
恢复表数据:
alter table 表名 enable row movement;
flashback table 表名 TO TIMESTAMP to_timestamp('2009-08-07 18:34:00','yyyy-mm-dd hh24:mi:ss');
恢复存储过程:
select text from dba_source as of timestamp to_timestamp('2009-03-06 09:45:00', 'YYYY-MM-DD HH24:MI:SS') where owner='IPRA' and name= 'P_IPACCHECK_NC' order by line;
需要sys用户
否则不够权限
或者登录数据库所在主机,使用数据库管理者的系统用户登录
视图:(受权限过滤了)
all_tables 所有表
all_indexs 所有索引
all_tab_columns 所有列,可以查看列的类型
(dba权限包括所有)
dba_tables
dba_tab_columns
dba_free_space 各对象的剩余空间
dba_data_files 各数据空间的文件信息
dba_tablespaces 表空间信息
常用字符函数
函数
|
描述
|
LOWER(char)
|
将字符串表达式char中的所有大写字母转换为小写字母
|
UPPER(char)
|
将字符串表达式char中的所有小写字母转换为大写字母
|
INITCAP(char)
|
首字母转换成大写
|
SUBSTR(char,start,length)
|
返回字符串表达式char中从第start开始的length个字符
|
LENGTH(char)
|
返回字符串表达式char的长度
|
LTRIM(char)
|
去掉字符串表达式char后面的空格
|
ASCII(char)
|
取char的ASCII值
|
CHAR(number)
|
取number的ASCII值
|
REPLACE(char,str1,str2)
|
将字符串中所有str1换成str2
|
INSTR(char1,char2,start,times)
|
在char1字符串中搜索char2字符串,start为执行搜索操作的起始位置,times为搜索次数
|
常用日期函数
函数
|
描述
|
SYSDATE
|
返回系统当前日期和时间
|
NEXT_DAY(day,char)
|
返回day指定的日期之后并满足char指定条件的第一个日期,char所指条件只能为星期几
|
LAST_DAY(day)
|
返回day日期所指定月份中最后一天所对应的日期
|
ADD_MONTH(day,n)
|
返回day日期在n个月后(n为正数)或前(n为负数)的日期
|
MONTH_BETWEEN(day1,day2)
|
返回day1日期和day2日期之间相差得月份
|
ROUND(day[,fmt])
|
按照fmt指定格式对日期数据day做舍入处理,默认舍入到日
|
TRUNC(day,[,fmt])
|
按照fmt指定格式对日期数据day做舍入处理,默认截断到日
|
数据类型转换函数
函数
|
描述
|
TO_CHAR
|
将一个数字或日期转换成字符串
|
TO_NUMBER
|
将字符型数据转换成数字型数据
|
TO_DATE
|
将字符型数据转换为日期型数据
|
CONVERT
|
将一个字符串从一个字符集转换为另一种字符集
|
CHARTORowid
|
将一个字符串转换为Rowid数据类型
|
RowIDTOCHAR
|
将一个Rowid数据类型转换为字符串
|
NEXTTORAW
|
将一个十六进制字符串转换为RAW数据类型
|
RAWTOHEX
|
将一个RAW类型的二进制数据类型转换为一个十六进制表达的字符串
|
TO_MULTI_BYTE
|
将一个单字节字符串转换为多字节字符串
|
TO_SINGLE_BYTE
|
将一个多字节字符串转换为单字节字符串
|
集合函数
函数
|
描述
|
AVG
|
计算一列值的平均值
|
COUNT
|
统计一列中值的个数
|
MAX
|
求一列值中的最大值
|
MIN
|
求一列值中的最小值
|
SUM
|
计算一列值的总和
|
STDDEV
|
计算一列值的标准差
|
VARIANCE
|
计算一列值的方差
|
1、
encodeURIComponent(”[string]“)
decodeURIComponent(”[encodedString]“)
2、
encodeURI(”[string]“)
decodeURI(”[encodedString]“)
3、
escape(”[string]“)
unescape(”[encodedString]“)
1、对每个字节进行编码;
2、空格转为”+”号;
3、安全字符不编码。安全字符:大小写英文字母(a-z以及A-Z) 阿拉伯数字(0-9) \’ ( ) * - . _ !
4、其他字节以十六进制显示并加”%”前缀,例如用%25代表%号。
设置客户端字符集:
# 常用中文字符集
set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
# 常用unicode字符集
set NLS_LANG=american_america.AL32UTF8
exp 用户名/密码@主机 file=导出文件的文件名 tables=(逗号分割表名) log=aibsm.log feedback=200
1.Json的对象形式
{
property0 : true, //property0是一个布尔型的值
property1 : 0, //property1是一个数值型的值
property2 : "123", //property2是一个字符串型的值
property3 : function(){...} //property3是一个函数
}
使用key-value对构造json对象,注意属性的key和value使用“:”分开,属性之间使用“,”分开,注意最后的属性没有“,”,什么符号都不要有。将此结构直接赋值给js的对象,则可以使用这个对象调用这些属性。
例如:var obj1 = {
property0 : true, //property0是一个布尔型的值
property1 : 0, //property1是一个数值型的值
property2 : "123", //property2是一个字符串型的值
property3 : function(){...}, //property3是一个函数
property4 : { p1 : p1Value, p2 : p2Value } //property4本身又是一个对象
}
那么可以调用
alert(obj1.property0);
obj1.property3();
……
在Java Web开发中,服务端负责输出这串字符到jsp页面的js,就可以使用了。
关键的是,字符串中可能具有js需要避免的特殊字符,建议查看一下spring的JavascriptUtils的javaScriptEscape方法就知道如何做啦
如果是Ajax调用的话,就是用prototype库的方法,将字符串转换为json对象
new Ajax.Request(" http://url/", {
method: "get",
onSuccess: function(transport) {
var json = transport.responseText.evalJSON();
// TODO: document.write(json.xxx);
}
prototype库的官网: http://prototypejs.org/
});
2. Json的数组形式
其实js中的数组更像是一个Map对象,因为它的key不只是整数,还可以是字符串。
var array;
array["key0"] = key0Value;
array["key1"] = key1Value;
摘要: 基本javascript事件的列表介绍 阅读全文
摘要: 首先介绍一个网站,我很多书本都是在上面下载的,很好。http://www.freebookspot.in/
我现在学习的书本是:Pro Javascript Design Pattern
首先简单地为优雅的Javascript代码开个头
运用设计模式的三大原因:
可维护性
沟通交流性
性能追求
不使用设计模式的两大原因:
复杂性
性能追求
阅读全文
最大公约数:使用轮转相除法,它的原理是:(n1>n2)n1与n2的最大公约数等于n2与n1%n2的最大公约数,即
gcd(n1, n2)=gcd(n2, n1%n2)
最大公约数
1 public class MaxDivisor {
2 public static void main(String[] args){
3 int int1 = (int) Math.ceil(Math.random()*1000);
4 int int2 = (int) Math.ceil(Math.random()*1000);
5 System.out.print(int1+" " + int2+"\n");
6 System.out.println(findMaxDivisor(int1, int2));
7 }
8
9 public static int findMaxDivisor(int int1, int int2){
10 if(int1==int2) return int1;
11 else if(int1<int2){
12 int1 += int2;
13 int2 = int1 - int2;
14 int1 -= int2;
15 }
16 int temp;
17 while((temp = int1%int2) != 0){
18 return findMaxDivisor(int2, int1%int2);
19 }
20 return int2;
21 }
22 }
23
素数筛选法:原理是:
1)0与1不是素数;
2)素数的2倍以上倍数不是素数
所以剔除这些剩下的就是素数了
素数筛选法
1 public class PrimeNum {
2 public static void primeNum(){
3 boolean[] array = new boolean[6500];
4 for(int i = 0; i<array.length; i++){
5 array[i] = true;
6 }
7 array[0] = array[1] = false;
8 int end = (int) Math.ceil(Math.sqrt(array.length-1));
9 for(int i=2; i<end; i++){
10 if(array[i] == true)
11 for(int j = i+i; j<array.length; j+=i){//若i是素数,则排除i的倍数
12 array[j] = false;
13 }
14 }
15 StringBuilder sb = new StringBuilder();
16 for(int i = 0; i<array.length; i++){
17 if(array[i] == true)
18 sb.append(i).append(" ");
19 }
20 System.out.println(sb.toString());
21 }
22
23 public static void main(String[] args){
24 primeNum();
25 }
26 }
27
http://wiki.ubuntu.org.cn/Tomcat%E8%AE%BE%E7%BD%AEJSP%E7%8E%AF%E5%A2%83
jms:
(Java Message Service)
JMS定义了Java中访问消息中间件的接口。
JMS只是接口,并没有给予实现,实现JMS接口的消息中间件叫JMS Provider,这样的消息中间件可以从Java里通过JMS接口进行调用。
JMS 消息模型
JMS消息由两部分构成:header和body。header包含消息的识别信息和路由信息,body包含消息的实际数据。
根据数据格式,JMS消息可分为以下五种:
BytesMessage 消息是字节流。
MapMessage 消息是一系列的命名和值的对应组合。
ObjectMessage 消息是一个流化的Java对象。
StreamMessage 消息是Java中的输入输出流。
TextMessage 消息是一个字符串,这种类型将会广泛用于XML格式的数据。
cms:
Content Management System,CMS其实就是内容管理系统,,,可以理解为,CMS帮你把一个网站的程序部分的事全做完了 你要做的只是一个网站里面美工的部份,搞几个静态网页模板,一个门户级的网站就出来了!
CMS,大概2004以前,如果想进行网站内容管理,基本上都是靠手工维护,但千变万化的信息流,但没有好的程序支持,还继续靠手工完成是不可能的事,如果有一个好的系统来支撑你的网站,那将节省大量的人力物力,开发者就可能给客户一个软件包,可以用它定期人工修改网站。只要你配置安装好,你的编辑,在线记者,更新员只要定期更新数据,剩下的事就交给CMS去处理
基本类型:
布尔类型:boolean不能够自动也不能强制转换成其他类型,但是可以进行&,&&,|,||运算
字符类型:char(16)其他基本类型不能够自动转变为字符类型,但可以强制转换为char,但是可以有截断现象
整形类型:byte(8),short(16),int(32),long(64)初始化的时候都是使用整数字面量直接赋值,但是byte与byte,short与short变量相加,默认都得到int的值,所以必须强制转换才能够返回原来类型的值(例如:(byte)(b1+b2))
浮点类型:float(32),double(64)浮点数的字面量默认都是double类型,所以需要强制转换成float才能够初始化float,或者加上f或F后缀。(例如float f1 = 1.4F或者float f1 = (float)1.4
整形还可以使用八进制(以0开头的整形数字字面量)、十六进制(以0x开头的整形字面量)初始化;
浮点型:字面量不可以是八进制十六进制,但int可以自动转化为浮点,所以仍然可以使用8进制16进制初始化,但是可以使用浮点计数法初始化,同样可以加上f或d后缀,例1.23e+33F等
字符型char可以直接使用
unicode转义符:
\uXXXX 四个16进制的数,在文本里面就是代表着某个字符,所以可以'\uXXXX'初始化一个char,可以\u0022\uXXXX\u0022初始化一个String,因为刚好\u0022代表双引号。当然\uXXXX不能是双引号,否则就编译出错了。
自动类型转换:byte---short---int---long---float---double
但是short与char不能够相互自动转换,但是可以相互强制转换
整型字面量可以初始化char,只要不超过65535的范围,也就是也能够使用8进制16进制初始化,但是整型变量不能够赋值给char;
char可以自动转换成int及以上
变量声明与定义:
int[] intArray; //OK
int intArray[]; //OK
前面的加上 “= new int[变量or常量]” 都是可以的,但是“= new int(5)”是错误的
int[] intArray[]; //OK,但是代表的是数组的数组
int[5] intArray; //False
int intArray[5]; //False
三目运算符:
?:返回不同类型问题,跟C++稍微不同,无论返回值在第一表达式还是第二表达式,返回值都是根据高阶类型返回,例子:
true ? 'a' : 9 返回结果是字符类型,所以字符类型是高阶类型
true ? 'a' : 9.0 返回结果是浮点类型(对于double和float都是),所以浮点比字符类型高阶
ture ? 9 : 9.0 返回结果是浮点类型,明显
true ? "abc" : 9 返回结果是字符串类型,因为字符类型较高阶
true ? 对象1实例 : 对象2实例 返回结果是最大共同父类,所以如果其中一个是另外一个的子类,那么就返回父类,如果互不继承关系,则返回Object。
String总结:
首先声明,==判断是判断对象引用的实例是否相同,即实例是否真正在相同的位置
Object默认的equals方法与==是一样的(就是引用相同实例),String类重写equals方法和hashCode方法,只要内容相同就返回ture(一般自己写的类也建议重写equals方法和hashCode方法)。所以这时候==与equals就具有不相同意义了。
http://www.javaeye.com/topic/122206
1. 首先String不属于8种基本数据类型,String是一个对象。
因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。
2. new String()和new String("")都是申明一个新的空字符串,是空串不是null;
3. String str="string";
String str1="string";
String str2=new String ("string");
String str3="str" + new String("ing");
关于常量池概念,java虚拟机在常量池中只维持一个字符串的示例,所以str与str1引用都是引用常量池里面的共同实例,关键的是只有常量池里面的String才是唯一的,new空间里面的并不是。
但是str2,str3(而且str2与str3的空间地址也肯定不一样的,引用的是新建空间堆里的实例,所以str==str1,str!=str2,str1!=str2,str1!=str3,str2!=str3
但是它们几个使用equals都是返回true的,因为String类的hashCode函数根据内容返回hashCode码,这个码相同,则equals就返回true了,具体的equals与hashCode解释可以参照《java核心技术 卷1 基础知识》
注意:成员函数intern() :
当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;
所以:
String str1="string";
String str2=new String ("string");
str1==str2.intern() 返回true
参考java core总结,java 5与之前的不同包括:
1.泛型编程
2.包装类的自动打包拆包
3.格式化输出:增加printf函数
4.StringBuilder类:非线程安全的StringBuffer
5.可变参数列表:声明方式public void mymethod(String arg1,Object… args),记住...号
6.增强的for循环:for(type variable:数组或数组列表)
7.静态导入:import static 导入类 就可以使用本地方法一样使用导入类的静态方法
8.协变的返回类型,即override的函数可以返回原函数返回类型的子类型,而不是要求相同返回类型
9.控制台输入
10.内容窗格授权:Jframe、JDialog、JApplet可以使用add和setLayout函数,以前需要getContentPane().add(component)和getContentPane().setLayout(manager);
测试:定义为“在受控的条件下对应用程序进行操作,以对程序质量进行评估”。
质量:可以定义为“产品的优点(特性)减去其中存在的问题(bug)”。
测试的重要性:测试的反面是不测试,即把程序验证工作都丢到软件开发完毕或者交付给客户。辩驳观点是:越迟发现程序的问题,修复其的成本越高。
测试人员做什么:保证程序的bug是影响最小的bug,将程序的bug降到最小风险。
测试与QA(Quality Assurance)的区别:QA关注软件工程的过程,通过改善过程提高软件的质量,他不对软件进行剖析以找出问题,而只是验证软件是否满足一套已定义的质量标准和用户协议。
测试更关心的是剖析软件,观察软件的运行,并在质量内部层次进行报告,发现软件的bug。
测试人员素质:验证、检测、防范、反映。
bug:是没有预料到的行为,软件做了某些认为是错误的事情。
自动化测试:使用软件工具来代替手工进行的一系列动作,通常使用脚本或者代码驱动应用程序,可以通过可视用户界面完成,或者直接命令模拟客户端功能。
构建版本验证测试(Build verification test, BVT)针对软件最新版本而做的一些列自动化测试;回归测试(Regression testing)测试以前曾经正常工作的场景,确保代码修改后没有打破原来的功能或者产生其他方面的副作用。
线程生命周期:新建线程、排队、运行、等待、死亡,明显包含了下面线程生存期的三种状态。
线程生存期三种状态:就绪、运行、等待(挂起)
与线程相关的一些函数区别:
线程暂停或者停止:stop、suspend、sleep、wait
成员方法stop会解除由线程获得的所有锁定,并且使线程进入死亡状态,相当于run方法的被强制中断;
成员方法suspend仍然持有线程之前的所有锁定,并且使线程进入等待状态,需要使用resume重激活;
静态方法 sleep不释放对象锁,可以指定暂停线程的mini Seconds数,暂停当前线程;
成员方法wait导致本线程放弃对象锁,进入挂起状态,并且需要通过notify或者notifyAll来使线程进入就绪状态;
线程池机制:
线程池管理器:创建销毁线程池、将工作线程放入线程池
工作线程:执行任务(即任务接口)的线程,在没有任务时候等待
任务队列:提供线程申请缓冲机制
任务接口:规定任务的入口、任务执行完后的收尾工作、任务的执行状态
ZIP压缩IO涉及类(包括操作文件夹压缩)
ZipEntry标识zip文件中单个文件的入口,它也支持路径加文件名,所以通过配置它,可以建立目录层次的zip文件(见下例子)
ZipOutputStream,write数据到zip文件的对象
ZipInputStream,从zip文件中read数据的对象,其实基本上这个没有作用
ZipFile,获取zip文件里面单个文件入口,getInputStream()等信息的对象,初始化ZipFile zf = new ZipFile(zip压缩文件的File对象);
Enumeration entries = =zf.entries()可以获得所有的zip文件里面的文件入口。
原理就是:entry指定单个文件相对zip压缩文件内部根目录的位置,Stream操作输出输入,ZipFile代表的就是整个zip文件
示例代码
1 package zipLearning;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.util.zip.ZipEntry;
7 import java.util.zip.ZipOutputStream;
8
9 public class testZip {
10 private static final int BUFFER_SIZE = 100;
11
12 public static void main(String[] args) {
13 if (args.length == 2) {
14 File file = new File(args[0]);
15 if (file.exists())
16 file.delete();
17 zip(new File(args[0]), new File(args[1]).listFiles());
18 } else {
19 System.err.println("Command Parameters Error!");
20 System.out
21 .println("usage testZip zip_target_name in_file_or_dir_name");
22 }
23 }
24
25 public static void zip(File zipFile, File[] zippedFiles) {
26 try {
27 byte[] buffer = new byte[BUFFER_SIZE];
28 FileOutputStream fs = new FileOutputStream(zipFile);
29 ZipOutputStream zipOut = new ZipOutputStream(fs);
30
31 for (int i = 0, n = zippedFiles.length; i < n; i++) {
32 if (zippedFiles[i] == null || !zippedFiles[i].exists())
33 continue;
34 if (zippedFiles[i].isDirectory()) {
35 zip(zippedFiles[i].listFiles(), zipOut, buffer,
36 zippedFiles[i].getName());
37 continue;
38 }
39 ZipEntry zipAdd = new ZipEntry(zippedFiles[i].getName());
40 zipAdd.setTime(zippedFiles[i].lastModified());
41 zipOut.putNextEntry(zipAdd);
42
43 FileInputStream in = new FileInputStream(zippedFiles[i]);
44 while (true) {
45 int readSize = in.read(buffer, 0, buffer.length);
46 if (readSize < 0) {
47 break;
48 }
49 zipOut.write(buffer, 0, readSize);
50 }
51 in.close();
52 }
53 zipOut.close();
54 fs.close();
55 } catch (Exception e) {
56 e.printStackTrace();
57 }
58 }
59
60 public static void zip(File[] zippedFiles, ZipOutputStream zipOut,
61 byte[] buffer, String base) throws Exception {
62 base = base + "/";
63 for (int i = 0, n = zippedFiles.length; i < n; i++) {
64 if (zippedFiles[i] == null || !zippedFiles[i].exists())
65 continue;
66
67 if (zippedFiles[i].isDirectory()) {
68 zip(zippedFiles[i].listFiles(), zipOut, buffer, base
69 + zippedFiles[i].getName());
70 continue;
71 }
72
73 ZipEntry zipAdd = new ZipEntry(base + zippedFiles[i].getName());
74 zipAdd.setTime(zippedFiles[i].lastModified());
75 zipOut.putNextEntry(zipAdd);
76
77 FileInputStream in = new FileInputStream(zippedFiles[i]);
78 while (true) {
79 int readSize = in.read(buffer, 0, buffer.length);
80 if (readSize < 0) {
81 break;
82 }
83 zipOut.write(buffer, 0, readSize);
84 }
85 in.close();
86 }
87 }
88 }
89
JAR压缩类与ZIP是几乎一模一样对应的分别为:JarEntry JarFile JarInputStream JarOutputStream
GZIP格式,只提供GZIPInputStream和GZIPOutputStream类,因为其作用是单纯的压缩与解压,不维护文件结构。多数用于基于流的数据传送过程实现数据压缩。用法就如Bufer Stream一样,是stream之间的又一个过滤类,只是Buffer提供缓冲,而GZIP提供压缩。
例如需要网络传送压缩就可以这样做:
客户端:
Socket socket = new Socket(服务器地址字符串, 服务器端口);
BufferOutputStream out = new BufferOutPutStream(new GZIPOutputStream(socket.getOutputStream()));
然后就可以操作数据输出了
服务器端:
ServerSocket sSocket = new ServerSocket(服务器端口);
Socket socket = sSocket.accept();
BufferInputStream in = new BufferInputStream(new GZIPInputStream(socket.getInputStream()));
然后就可以读入数据了。
明显网络数据传送就加了一个压缩,性能就可以提高了。
摘要: 元字符
\w 匹配字母或数字或下划线或汉字等。等效于Unicode字符类别 [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]。如果用ECMAScript选项指定了符合 ECMAScript的行为,则\w只等效于[a-zA-Z_0-9]。
\b 单词的开头或结尾,如果需要更精确的说法,\b匹配这样的位置:它的前一个字符和后一个字符不全是\w
. 除换行符以外的所有字符
* 表示数量,任意数量,所以 .* 加起来就表示除换行符以外的任意数量字符,\w*表示任意字符
+ 是和*类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。
\d 单个数字
\s 匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等。
^ 匹配你要用来查找的字符串的开头,$匹配结尾。和忽略大小写的选项类似,有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^和$的意义就变成了匹配 阅读全文
Pattern类:
例子:
Pattern pattern = Pattern.compile("[,\\s]+");
String[] result = pattern.split("one two three,four,five, six");
for(int i = 0; i<result.length; i++){
System.out.println(result[i]);
}
输出结果是:
one
two
three
four
five
six
Pattern类的静态方法compile用来编译正则表达式,在此[,\\s]+表示若干个","或者若干个空格匹配
split方法使用正则匹配将字符串切割成各子串并且返回
Matcher类:
注意,Matcher的获得是通过Pattern.matcher(CharSequence charSequence);输入必须是实现了CharSequence接口的类
常用方法:
matches()判断整个输入串是否匹配,整个匹配则返回true
例如下面会输出true
String str1 = "hello";
Pattern pattern1 = Pattern.compile("hello");
Matcher matcher1 = pattern1.matcher(str1);
System.out.println(matcher1.matches());
lookingAt()从头开始寻找,找到匹配则返回true
例如下面会输出true
String str2 = "hello yangfan!";
Pattern pattern2 = Pattern.compile("hello");
Matcher matcher2 = pattern2.matcher(str2);
System.out.println(matcher2.lookingAt());
find()扫描输入串,寻找下一个匹配子串,存在则返回true
例如下面将会将所有no替换成yes
Pattern pattern = Pattern.compile("no");
Matcher matcher = pattern.matcher("Does jianyue love yangfan? no;" +
"Does jianyue love yangfan? no;Does jianyue love yangfan? no;");
StringBuffer sb = new StringBuffer();
boolean find = matcher.find();
while(find){
matcher.appendReplacement(sb, "yes");
find = matcher.find();
}
matcher.appendTail(sb);
System.out.println(sb.toString());
初始化:
StringTokenizer st = new StringTokenizer(String str);
默认的分隔符,即空白符(空格、制表符、回车)
或者
StringTokenizer st = new StringTokenizer(String str, String token);
使用token作为分隔符
常用函数:
st.countTokens()返回token的数量
st.hasMOreTokens()判断时候当前位置之后是否还有token
st.nextToken()返回当前位置到下一个token之前或者字符串结束之前的字符串
简单示例:
String str = "wo shi li jian yue, what your name? yangfan?";
String[] stringArray = new String[100];
StringTokenizer st = new StringTokenizer(str, ",");
int i;
for(i = 0; st.hasMoreTokens(); i++){
stringArray[i] = st.nextToken();
}
for(int j = 0; j<i; j++){
System.out.println(stringArray[j]);
}
以","为分隔符,将会输出","之前和之后的两行字符串
创建 Filter(过滤器)
实际开发中都需要开发一些很有用的过滤器,来解决中文表单提交问题啊,给请求和响
应加入 GZIP压缩功能啊,用户权限控制啊,等等,然而遗憾的 MyEclipse不支持直接创建
过滤器。在这里只好手工创建一个解决 Tomcat表单提交中文问题的过滤器。
选择菜单 File > New > Class,来创建一个名为 TomcatFormFilter 的类,包名为
filters。然后把类的代码修改为如下所示:
package filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class TomcatFormFilter implements Filter {
/**
* Request.java
* 对 HttpServletRequestWrapper 进行扩充, 不影响原来的功能并能提供所
有的 HttpServletRequest
* 接口中的功能. 它可以统一的对 Tomcat 默认设置下的中文问题进行解决而只
需要用新的 Request 对象替换页面中的
* request 对象即可.
*/
class Request extends HttpServletRequestWrapper
{
public Request(HttpServletRequest request) {
super(request);
}
/**
* 转换由表单读取的数据的内码.
* 从 ISO 字符转到 GBK.
*/
public String toChi(String input) {
try {
byte[] bytes = input.getBytes("ISO8859-1");
return new String(bytes, "GBK");
}
catch (Exception ex) {
}
return null;
}
/**
* Return the HttpServletRequest holded by this object.
*/
private HttpServletRequest getHttpServletRequest()
{
return (HttpServletRequest)super.getRequest();
}
/**
* 读取参数 -- 修正了中文问题.
*/
public String getParameter(String name)
{
return
toChi(getHttpServletRequest().getParameter(name));
}
/**
* 读取参数列表 - 修正了中文问题.
*/
public String[] getParameterValues(String name)
{
String values[] =
getHttpServletRequest().getParameterValues(name);
if (values != null) {
for (int i = 0; i < values.length; i++) {
values[i] = toChi(values[i]);
}
}
return values;
}
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse
response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpreq = (HttpServletRequest)request;
if(httpreq.getMethod().equals("POST")) {
request.setCharacterEncoding("GBK");
} else {
request = new Request(httpreq);
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws
ServletException {
}
}
清单 8.5 过滤器代码
然后修改 web.xml 加入 Servlet 定义,修改后的代码清单如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<description>
This is the description of my J2EE component
</description>
<display-name>
This is the display name of my J2EE component
</display-name>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>servlets.LoginServlet</servlet-class>
</servlet>
<filter>
<filter-name>TomcatFormFilter</filter-name>
<filter-class>filters.TomcatFormFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TomcatFormFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login.aspx</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
清单 8.6加入了过滤器的 web.xml 内容
清单中的粗斜体部分就是新加入的过滤器的映射信息。
一.继承关系和关联聚集关系映射
1.整个类层次使用一张表
2.每个叶结点使用一张表,该表保存了该类自己的和所继承的所有属性
3.每个类使用一张表,该表只保存OID以及对应类自己的属性(不含所继承的属性)
1.“1对1”或“1对多”关系的映射,简单地利用外键即可
2.“多对多”关系的映射,引入一个新的表,专门记录这种“多对多”关系
二.编程步骤:事前准备包括建立一个project并且加入外部库
新建一个Project HibernateSample,然后在Project上点右键,选择Properties Java Build Path Libraries。选择Add External JARs,然后将Hibernate目录下的hibernate3.jar,以及Hibernate目录下的lib文件夹中所有的jar文件添加进来。
另外我们还必须有MySQL的JDBC驱动,用上面的办法同样把mysql-connector-java-3.1.12-bin.jar添加进我们的Build Path中。
1.创建数据库(例如User表)
2.建立对应数据库的类的属性与操作(例如User类)
3.编写映射数据库表hibernate mapping,命名为***.hbm.xml(例如User.hbm.xml)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="sample.User" table="user">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native" />
</id>
<property name="name" column="name" type="java.lang.String" />
<property name="age" column="age" type="java.lang.Integer" />
</class>
</hibernate-mapping>
明显可见关注点包括
A)class中包中的类与数据库中table的对应
B)property中 类中ID和属性与table中字段的对应
4.编写Hibernate配置文件hibernate configurarion file,通常命名:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 是否显示实际操作数据库时的SQL -->
<property name="show_sql">true</property>
<!-- SQL方言,这边设定的是MySQL -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC驱动程序 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:mysql://localhost/Sample</property>
<!-- 数据库用户名 -->
<property name="connection.username">root</property>
<!-- 数据库密码 -->
<property name="connection.password">123456</property>
<!-- 以下设置对象与数据库表格映像文件 -->
<mapping resource="sample/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
关注点包括:
A)数据库路径, 数据库用户名, 数据库密码,
B)还有就是指定数据库映射文件mapping resource
5.配置log4j.properties
在src目录下点右键,选择import,然后选择General File System,接着选择Hibernate文件夹下的etc文件夹,再选择log4j.properties文件,最后选择Finish。
关键配置文件:
hbm是映射配置
cfg是密码,用户,以及hbm指定配置
properties是用于配置当前数据库连接的属性配置
6.编程操作数据库过程
使用对象增加数据项:
A)Configuration配置Configuration config = new Configuration().configure();
B)Session工厂获得SessionFactory sessionFactory = config.buildSessionFactory();
C)Session获得Session session = sessionFactory.openSession();
D)Transaction事务启动Transaction tx = session.beginTransaction();
E)建立映射数据的实体类(例如User的一个实例)
F)session操作(例如session.save(user)插入到数据库一个user的对象)
G)关键的Transaction事务提交,tx.commit();
H)清理包括Transaction对象,session对象,sessionFactory对象的有顺序清理
使用Criteria查询数据
A)配置Configuration,SessionFactory,Session与上面相同
B)创建Criteria criteria=session.createCriteria(User.class);
C)创建User列表List users = criteria.list();
D)使用迭代器Iterator iterator = users.iterator();
E)iterator.hasNext(),iterator.next()的使用
F)criteria.add(Expression.eq("name","hibernateUser2"));加上查询约束
G)users = criteria.list();将会按照查询约束得到列表.
使用鼓励的HQL的Query查询
A)创建Query例如Query query = session.createQuery("from User");
B)获得数据List uers = query.list();
C)遍历器使用Iterator iterator = users.iterator();又如iterator.hasNext();和iterator.next();
D)使用过滤查询
query = session.createQuery("from User user where user.name like ?");
query.setParameter(0, "hibernateUser2");Query的setParameter()方法第一个参数是指定 ? 出现的位置,从 0 开始,第二个参数则是设定查询条件。
然后再List uers = query.list();获得的将是满足username==hibernateUser2的条件的结果
E)清除session和sessionFactory使用close方法.
hibernate_rar
- validate: validate the project is correct and all necessary information is available
- compile: compile the source code of the project
- test: test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
- package: take the compiled code and package it in its distributable format, such as a JAR.
- integration-test: process and deploy the package if necessary into an environment where integration tests can be run
- verify: run any checks to verify the package is valid and meets quality criteria
- install: install the package into the local repository, for use as a dependency in other projects locally
- deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
There are two other Maven lifecycles of note beyond the default list above. They are
- clean: cleans up artifacts created by prior builds
- site: generates site documentation for this project
官网文章:http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
1 String lastUrl = request.getHeader("Referer");
不好意思,下面的说错了(所以都标红了),不过的确这个方法在有框架的时候性能还不清楚,
貌似是:
在多个框架中,IE的情况是:如果将在frame触发的链接显示在frame2中,frame2的Referer就不会改变。firefox的情况是,会变,所以firefox处理的更好。
请有识之士教导。
使用到方法来获得上一次路径的请注意了,如果页面涉及到框架frame的话,请留意firefox与IE的不同。
假如页面具有整个页面,上,左,右三个frame四个所谓的windows,假设每一个frame都有自己地址栏,当然真实的地址栏只有整个页面的一个。
我出现的情况是:
1)firefox中:一个右frame的jsp页面进入的struts的action,在这个action使用这个函数,能够获得右frame地址栏原来的字符串。在右frame页面里使用这个函数,也能够获得右frame原来的地址栏的字符串。
算是比较正常吧,获得所谓的referer的字符串嘛。
2)IE中:一个右frame的jsp页面进入的一个action,使用这个函数,获得的是整个页面的地址栏原来的字符串。在右frame页面里使用这个函数,却获得的是右frame地址栏原来的字符串。
这样就不正常啦,我在action里使用获得的竟然是整个页面的地址栏原来的字符串,那样我new ActionForward(这个url)的时候,就会出现框架嵌套框架啦。
这些问题应该是跟浏览器的实现有关。
我用这个函数主要是想实现返回上一步的功能。但是上一步的路径获得那么可预测,这种方法获得之前页面看来是不能信赖地用的。
下面的stirng对象变量都缩写成str
四个方法search,split,replace, match
详细解说
search用法:str.search("子串")
如果str中存在子串,则返回子串开头字符在str中的索引(即位置,当然是0或者正数),若str中不存在匹配子串则返回-1
例如:"JavaScript regular expressions are powerful!".search("pow")返回的是35,因为pow在前面字符串的第35位置
split用法:str.split("分隔字符")
返回由str中由用户所定分隔字符的各字符串,字符串间由,号隔开
例如: "10 / 3 / / 4 / 7 / 9".split ("/"),返回的是10, 3,空格, 4, 7, 9,认真看一下会发现数字与逗号间也有空格
文章中有这句话:Using split() with a regular expression argument (rather than a string argument) allows you the flexibility of ignoring multiple whitespace or delimiter characters.
我这里明显用的是普通字符串参数,下面用的是正则式参数
"10 / 3 / / 4 / 7 / 9".split(/[ \/]+/);
返回的是:10,3,4,7,9,注意这个串与上面串在空格的不同,数字与逗号间没有空格,这就是所谓的忽略空格
replace用法:str.replace("匹配子串","替换匹配子串的串")
如果匹配子串在原串中找不到,将不进行替换,返回是原串,若能找到匹配子串,则返回替换后的串
例如:var s = "Hello. Regexps are fun.";s = s.replace(".", "!");
叹号将代替第一个点号然后返回串,这是此函数特点,只替换第一处匹配的地方,如果要替换每处匹配的地方,需要用到正则式,正则式的作用很大,但是我只会皮毛,在此不举例。
match用法:str.match("匹配子串")
若没有匹配子串,则返回空,若存在匹配子串,则返回子串
The prefix "tx" for element "tx:advice" is not bound
这个错误的原因很简单是:
我们在定义申明AOP的时候。。没有加载schema。
具体表现如下:
<beans>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- aop代理设置-->
<aop:config proxy-target-class="true">
....
</aop:config>
</beans>
这时会抛出异常不认<TX>标签。。起先还以为是没有加载JAR包呢。。
后来读AOP文档才发现<beans>中要加入“xmlns:aop”的命名申明,并在“xsi:schemaLocation”中指定aop配置的schema的地址
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
这些才是最关键的地方。。后面的配置不变。。。。
如果在/sandh/web-inf/classes下面没有ehcache.xml这个文件,会报这个错误,No configuration found.
Configuring ehcache from ehcache-failsafe.xml found in the classpath:.....这个文件是hibernate缓存配置文
件
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="10000"
timeToLiveSeconds="10000"
overflowToDisk="true"
/>
<cache name="com.hour41.hibernate.vo.common.City"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="10000"
timeToLiveSeconds="10000"
overflowToDisk="true"
/>
</ehcache>
上面配置了默认类缓存和城市类缓存策略:
<diskStore>表示当内存缓存中对象数量超过类设置内存缓存数量时,将缓存对象写到硬盘,path=”java.io.tmpdir
”表示把数据写到这个目录下。Java.io.tmpdir目录在运行时会根据相对路径生成。
<defaultCache>表示设定缓存的默认数据过期策略。
<cache>表示设定用具体的命名缓存的数据过期策略。
name表示具体的缓存命名。
maxElementsInMemory表示cache中最大允许保存的对象数据量。
eternal表示cache中数据是否为常量。
timeToIdleSeconds表示缓存数据钝化时间
timeToLiveSeconds表示缓存数据的生命时间。
overflowToDisk表示内存不足时,是否启用磁盘缓存。
将上面代码另存为ehcache.xml存放在lib/classes里面即可!
1:配置文件applicationContext.xml问题
org.springframework.orm.hibernate3.HibernateTransactionManager 与
org.springframework.orm.hibernate3.LocalSessionFactoryBean出现问题.
解决方法:
这两个出现红色的小x其实是与三大框架集成的时候,包冲突有关,首先删除asm-2.2.3.jar 然后加入
spring-hibernate3.jar,commons-pool.jar,commons-dbcp.jar包,上述的问题解决!
2:asm包问题
spring与hibernate的冲突.两个框架都依赖asm.jar包spring的版本是asm-2.23.jar.hibernate依赖的是asm.jar
方法1:只删除asm-2.23.jar包
方法2:所有asm开头的jar包,和一个cglib-2.1.3.jar都删除,上网下载一个最新的asm-all-3.0.jar加进去
两种方法都试一下,有些人方法1行,方法2不行,有些人相反。
3:使用MeEclipse的时候,可能的警告:
java. lang.NoClassDefFoundError: org/ objectweb/ asm/Code Visitor
CGLIB Enhancement failed
解决方案:
在使用Spring的AOP编程时,会用到这几个lib:
asm-2.2.2.jar
asm-commons-2.2.2.jar
asm-util-2.2.2.jar
Hibernate使用如下lib:
asm.jar
asm-attrs.jar
其中asm-2.2.2.jar与asm.jar存在类上的冲突!!!
使用其中之一或两者都使用,可能会出现如下错误:
java.lang.NoClassDefFoundError: org/objectweb/asm/CodeVisitor
java.lang.NoClassDefFoundError: org/objectweb/asm/commons/EmptyVisitor
java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit。。。。。。
解决办法是:
1.去掉类路径上的关于Hibernate的3个lib
asm.jar
asm-attrs.jar
cglib-2.1.3.jar
2.加入Spring中的以下4个lib
asm-2.2.2.jar
asm-commons-2.2.2.jar
asm-util-2.2.2.jar
cglib-nodep-2.1_3.jar
3:注意以上的删包要确保tomcat服务器里面的包也被删了,否则有残留的时候,测试出错。
所以在框架集成时经常遇到,包冲突与少包问题,大家注意一下!哈哈!
“从 char 数据类型到 datetime 数据类型的转换导致 datetime 值越界”
错误的注意罗,下面是SQL Server下两种变量的详细介绍,时间值越界的明显就会报这个错误
datetime和smalldatetime
代表日期和一天内的时间的日期和时间数据类型。
datetime
从1753年1月1日到9999年12月31日的日期和时间数据,精确度为百分之三秒。如下表所示,把值调整到.000、.003、或.007秒的增量。(曾经试过使用1752有错,1753就没有错了,郁闷啊!)
microsoft®sqlserver™拒绝所有其不能识别为1753年到9999年间的日期的值。
smalldatetime
从1900年1月1日到2079年6月6日的日期和时间数据精确到分钟。29.998秒或更低的smalldatetime值向下舍入为最接近的分钟,29.999秒或更高的smalldatetime值向上舍入为最接近的分钟。
--returnstimeas12:35
selectcast(2000-05-0812:35:29.998assmalldatetime)
go
--returnstimeas12:36
selectcast(2000-05-0812:35:29.999assmalldatetime)
go
注释
microsoftsqlserver用两个4字节的整数内部存储datetime数据类型的值。第一个4字节存储basedate之前或之后的天数。基础日期是系统参考日期。不允许早于1753年1月1日的datetime值。另外一个4字节存储以午夜后毫秒数所代表的每天的时间。
smalldatetime数据类型存储日期和每天的时间,但精确度低于datetime。sqlserver将smalldatetime的值存储为两个2字节的整数。第一个2字节存储1900年1月1日后的天数。另外一个2字节存储午夜后的分钟数。日期范围从1900年1月1日到2079年6月6日,精确到分钟。
第一条:javascript非常脆弱,请一定要小心,不要敲错一个单词,也不要异想天开地理解js函数,出现一点差错都搞死人。改善方法是:多点copy,使用firefox的firebug也是调试javascript的好方法。
1.getElementsByTagName(tagName)可以使用很多元素对象来调用,我没有全试过,所以不敢打包票,不过基本上就是你想要用到的标签,都可以使用它来获得他的子标签array,不管几层以内。
2.getElementById只能用用document对象来调用,你试一下看看div能否使用这个函数找到他的子标签,答案是否的。 页面上的id可以直接用作变量名来引用标签对象。
3.getElementsByName也只能用在document对象,然后不是任意一个标签都有name,注意有些标签没有name的,你异想天开地为任何标签都加个name属性,结果就是这个name并不能用来索引这个标签。
4.form元素里面的input元素可以通过.id或者.name的方式获得其中元素, 即使隔着div和table都可以. 但是div和table是无法这样从form中获得的, form里面的元素也无法从table和div中使用这种方法获得.
注意"s"的区别,唯一性
innerHTML属性可以改变span里面的值, 但是innerText却不行,不知道为什么.
最好的调试方法,alert函数。
以上不敢包正确,但是的确是我自己测试以后得来的,改变了自己以前很多的想法,原来设计者搞得那么卑鄙的,弄死人了。
欢迎补充,有关[]的使用来代替函数查找,我还没有试验。
javascript是经典的敏感性语言,小小问题都会导致整体功能出错。
自己调用document.form[0].submit()的时候,会出现submit is not a function错误(使用firefox的firebug调试,非常好用),原因是页面的form中出现具有name=submit的元素,这样会影响到javascript调用submit()函数,改掉那个name=submit的元素即可。
另外submit提交struts1.2的action时候,如果后面跟有?method=***等的参数,那么注意,这个函数里面不要出现有method等关键字。
例如函数:
function changeAction(methodArg, wayArg){
with (document.forms[0]) {
action="<html:rewrite page='/BgdInfoReportAction.do'/>?method="+ methodArg + "&way=" + wayArg;
submit();
}
}
使用?method=***是在使用dispatchAction时候的做法原来我的参数名称是method和way,
结果报错:Action[/BgdInfoReportAction] does not contain method named post
原因是?后的method变得没有效,那么这个submit提交使用默认的post方法提交(servlet默认分为post和get方法嘛),
后来我将method改成methodArg和way改成wayArg,这个action就能够正确执行。
我重复测试改与不改的效果,仍然与上面一样。总结原因可能是是javascript的一些关键字冲突,所以尽量使用特殊一点的字符串作为变量名。
安装cvsnt
直接双击运行cvsnt安装文件,安装过程中可以选择以经典、自定义和完全三种方式安装,在自定义方式中可以选择安装路径。安装完成后,在控制面板里出现一个CVSNT Server的项目,图标是一条鱼~~
配置cvsnt
安装完成cvsnt后,就可以从控制面板中那条鱼来配置cvsnt了。首先,你要新建一个目录用来存放cvs仓库,我用的是G:\CVSROOT。这里需要先了解两个概念:cvs仓库和模块。我是这样理解的,cvs仓库相当于VS里一个解决方案,它可以包含多个项目,即模块。
打开cvsnt的控制面板后,可以看到7个选项卡,分别是:Server Information,用于查看服务器信息及一些简单的统计信息;Respository configuration,配置CVS仓库,包括添加、删除等;Server Setting,配置服务器运行的一些参数,诸如端口、加密、压缩等选项;Capatiblity Options,有关兼容性的选项,在这里主要配置一个兼容非cvsnt客户端的版本响应为cvs 1.11.2;Plugins,插件配置,安装完成可以不用管的~;Advanced,安装完成后也不用管了;About,在这里可以管理cvsnt服务的状态,停止或启动cvsnt和cvsnt lock服务。
其实简单来说,custom换默认设置安装完成后,要设置的东西只有两个:cvs仓库和服务器设置。
服务器设置:设置Run as为系统管理员帐号Administrator,或者新建一个本地用户,专门用于cvs。使用一个新建的本地帐户的好处是可以使用NTFS的权限控制来保证服务器的安全,例如我当前的用户是flora。
CVS仓库设置:进入Respository configuration选项卡,点击Add,出现添加CVS仓库的对话框,Type选择Standard即可,然后在Location里输入之前新建的用于存放CVS仓库的文件夹,我用的是D:\cvs,在Name里会自动转换成一个可以用的CVS仓库的别名,比如我用的是“/cvs”,其他的都默认,确定后cvsnt会询问你所添加的CVS仓库目录没有初始化,是否进行初始化,点“是”就行了,cvsnt会自动初始化指定的目录,初始化完成之后,可以在里面看到一个CVSROOT的文件夹,这个文件夹存储很多配置信息的。
用户设置:配置完CVS仓库后,为了使CVS能使用帐号进行访问而不是使用windows用户,需要添加普通使用用户。
打开cvs control panel(在开始菜单里面的快捷方式或者控制面板),server setting中run as 选择具有windows管理者权限的用户,应用。例如我当前的flora。在cvs control panel的about中重启一下cvs。
打开一个cmd,设置一下cvsroot环境变量,输入:
set cvsroot=:pserver:flora@127.0.0.1/cvs
注意,这里的flora是当前windows用户名,既run as中选择的那个,/cvs是之前添加的CVS仓库的别名,如果你的设置不同,请把它们替换成自己的值,以后不再说明。
接着cvs login命令登录CVS服务器,因为添加用户时没有设置密码,因此可以不输入密码直接回车登录:
添加普通新用户
cvs passwd -a -r flora jianyue
jianyue是你想新添加的用户名 flora指定现在用具有admin权限的用户来创建jianyue用户
否则出现错误信息:Only administrators can add or change another's password
这条命令后就可以设置这个用户的密码。
成功后可以使用这个用户了
在Myeclipse中连接cvs服务器:
在还没有没有添加cvs版本控制的工程上(已添加了的,菜单会有所不同)
在工程名上右键->team->share project->create a new repository location,填入必须的信息,像我的是本地的,就填:
host:localhost
Repository path:cvs(上面配置时候的那个仓库别名)
填上合适的用户名与密码,我这里是jianyue 密码hello
端口与类型,如果服务器没有修改过的话,都用默认的就行
这样子,这个工程文件就会被上传到CVSROOT目录上,本地的文件系统打开这个目录,也可以看见被上传的工程。
以后就可以方便的使用版本控制了。
上面的方法对于忘记用户密码的情况也可以解决,在cmd使用系统用户登陆cvs,就可以按照上面步骤重建那个用户,修改其密码,
cvs会默认覆盖这个用户。
出现warning log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester.sax).信息的经典处理方法:
在eclipse下工程的src目录下新建文件名为: log4j.properties
内容为:
log4j.rootLogger=WARN, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=(%r ms) [%t] %-5p: %c#%M %x: %m%n
log4j.logger.com.genuitec.eclipse.sqlexplorer=DEBUG
log4j.logger.org.apache=WARN
log4j.logger.org.hibernate=WARN
项目编译的时候会自动copy到WEB-INF/class目录下,这样tomcat启动的时候,就可以启动log4j消息机制。
这个机制的最大好处是将一般不会显示出来的问题显示在console上,方便发现隐秘的错误,特别是当你不知道哪里错,
但是网站的确有问题的时候。
在tomcat的目录conf\Catalina\localhost下,可以增加xml文件,来指向file系统中任意一处作为网站系统的子根目录,例如:
atcs.xml文件:
<!--
Context configuration file for the Tomcat Host Manager Web App
$Id: host-manager.xml 303743 2005-03-11 22:39:26Z remm $
-->
<Context path="/atcs" docBase="D:\WorkSpace\Huadu_Atcs3\WebContent"
privileged="true" antiResourceLocking="false" antiJARLocking="false">
</Context>
其中docBase指向站点的根目录,path与文件名相同(在此为atcs),这个path最好也要与docBase下的WEB-INF下的web.xml里面的
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>atcs.root</param-value>
</context-param>
paraam-value相同。
三者相同的情况下,才可以正确的访问网站(访问方式:http://localhost:8080/atcs)这样就作为localhost的一个子站点可以运行了。
常见错误:多个工程目录下的web.xml文件的<param-value>atcs.root</param-value>相同,就算在tomcat的conf下配置不同的名,例如配置atcs2.xml指向另外一个工程目录,但是恰巧那个工程下的web.xml里面也配置相同的webAppRootKey,那么将会出现其中一个工程不能够访问的问题。
网页出现经典的The requested resource (/atcs/) is not available错误!
问题发现方法:在myEclipse下配置log4j,之后会将一些不会报出来的错误亦会报出来,根据信息就可以发现是相同的webAppRootKey覆盖问题。在此我的log4j的报错信息:
Web app root system property already set to different value: 'atcs.root' = [D:\workspace2\Huadu_Atcs3\WebContent\] instead of [D:\WorkSpace\Huadu_Atcs3\WebContent\] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!
log4j的配置问题参考:http://www.blogjava.net/jianyue/archive/2008/08/21/223500.html
|