??xml version="1.0" encoding="utf-8" standalone="yes"?> 各个版本的都有,以下列D出来9.2?/p>
Oracle WebLogic Server 9.2 MP3版本 http://download.oracle.com/otn/bea/weblogic/server923_win32.exe.zip http://download.oracle.com/otn/bea/weblogic/server923_linux32.bin.zip http://download.oracle.com/otn/bea/weblogic/server923_solaris32.bin.zip Oracle WebLogic Server 9.2 MP4版本 http://download.oracle.com/otn/bea/weblogic/server924_linux32.zip http://download.oracle.com/otn/bea/weblogic/server924_solaris32.zip Oracle WebLogic Server 10.0 MP2 版本 linux-geum:/etc/init.d # more start_oracle.sh su - oracle -c "/opt/oracle/product/10g/bin/dbstart" su - oracle -c "/opt/oracle/product/10g/bin/lsnrctl start" linux-geum:/etc/init.d # more stop_oracle.sh su - oracle -c "/opt/oracle/product/10g/bin/lsnrctl stop" su - oracle -c "/opt/oracle/product/10g/bin/bin/dbshut"
]]>
#this script is used to start the oracle
ln -s /etc/init.d/start_oracle.sh /etc/rc.d/rc2.d/S16start_oracle
ln -s /etc/init.d/start_oracle.sh /etc/rc.d/rc3.d/S16start_oracle
ln -s /etc/init.d/start_oracle.sh /etc/rc.d/rc5.d/S16start_oracle
#this script is used to stop the oracle
ln -s /etc/init.d/stop_oracle.sh /etc/rc.d/rc2.d/S16stop_oracle
ln -s /etc/init.d/stop_oracle.sh /etc/rc.d/rc3.d/S16stop_oracle
ln -s /etc/init.d/stop_oracle.sh /etc/rc.d/rc5.d/S16stop_oracle
]]>
文g内容
/usr/local/bin/memcached -d -m 512 -u root -l 192.168.1.106 -p 11211 -c 1024 -P /tmp/memcached.pid
]]>
package com.centralsoft.filter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Pattern;
import net.sf.json.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.centralsoft.cache.CacheService;
import com.centralsoft.cache.annotations.Cache;
import com.centralsoft.cache.entity.MemCacheKey;
import com.centralsoft.entity.SysLogDetail;
import com.centralsoft.manager.pub.ThreadBean;
import com.centralsoft.manager.pub.ThreadId;
import com.centralsoft.pub.dao.SysLogDAO;
import com.centralsoft.webservice.pub.DateSHA;
/**
* DAO层AOP拦截器,实现记录用户操作q的所有方法和参数Qƈ实现DAO层缓?br /> *
* @author Administrator
*
*/
@Aspect
@Component
public class AspectAutoDAOBean {
@Autowired
@Qualifier("CacheService")
private CacheService memcache;
@Autowired
@Qualifier("SysLogDAO")
private SysLogDAO SysLogDAO;
@Around("execution(* com.centralsoft.*.dao.Zr*DAO.*(..))")
public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取h事务ID信息
ThreadId threadId = new ThreadBean().getThreadId();
// 调用Ҏ名称
String methodName = joinPoint.getSignature().getName();
// 调用参数
Object[] args = joinPoint.getArgs();
Object object = null;
// 数据库更新操作日?br /> if (Pattern.matches("(save|insert|add|delete|remove|del|update)[\\S]*",
methodName)) {
if (threadId != null && threadId.getTransactionalId() != null) {
// 获取执行h事务ID
String transactionalId = threadId.getTransactionalId();
// 获取执行h用户ID
String userId = threadId.getUserId();
SysLogDetail sysLogDetail = new SysLogDetail();
sysLogDetail.setXh(transactionalId);
sysLogDetail.setUserId(userId);
sysLogDetail.setMethod(methodName);
JSONObject msg = new JSONObject();
// 处理参数
for (Object temp : args) {
// 获取参数cd,不同参数cd数据处理不一?br /> Class<? extends Object> paramClazz = temp.getClass();
String classType = paramClazz.getName();
if (classType.equals("java.lang.String")) {
msg.put("key", temp);
} else if (classType.equals("java.util.HashMap")) {
msg.putAll((HashMap<?, ?>) temp);
} else if (classType.startsWith("com.")) {
try {
Field[] f = paramClazz.getDeclaredFields();
for (Field field : f) {
String fieldName = field.getName();
field.setAccessible(true);
msg.put(fieldName, field.get(temp));
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
sysLogDetail.setMsg(msg.toString());
// 记录DAO数据库操作日?br /> SysLogDAO.insertSysLogDetail(sysLogDetail);
}
// 执行数据库操?br /> object = joinPoint.proceed();
// 数据库查询缓?br /> } else if (Pattern.matches("(query|load|get|select|read)[\\S]*",
methodName)) {
// DAO层缓存注?br /> MemCacheKey cacheKey = new MemCacheKey();
// 获取cache注解属?br /> Cache cache = null;
// 获取hҎ
Class<?> cls = joinPoint.getTarget().getClass();
// 获取class中的所有方?br /> Method[] methods = cls.getMethods();
for (Method m : methods) {
// 获取执行Ҏ前的注解信息?br /> if (m.getName().equals(methodName)) {
cache = m.getAnnotation(Cache.class);
break;
}
}
if (cache != null) {
// 获取memcacheKey,q进行MD5加密
cacheKey = memcacheKey(cache, args);
// 判断~存服务器是否存在该可以?br /> if (memcache.exist(cacheKey.getMemcacheKey())) {
object = memcache.get(cacheKey.getMemcacheKey());
} else {
// 执行数据库操?br /> object = joinPoint.proceed();
// 数据存放进~存
if (cacheKey.getMemcacheKey() != null) {
memcache.put(cacheKey.getMemcacheKey(),
object == null ? "" : object, new Date(cacheKey
.getTime()));
}
}
} else {
// 执行数据库操?br /> object = joinPoint.proceed();
}
} else {
// 执行数据库操?br /> object = joinPoint.proceed();
}
return object;
}
/**
* 获取Ҏ注解中的key获取memcache的含参数key?br /> *
* @param cache
* @param parameterObject
* @return
* @author fei.zhao 2011-10-10
*/
@SuppressWarnings("unchecked")
private static MemCacheKey memcacheKey(Cache cache, Object[] args) {
MemCacheKey tempKey = new MemCacheKey();
String key = "";
boolean flag = true;
StringBuilder keyBuilder = new StringBuilder(32);
// 获取注解中的key?br /> String cacheKey = cache.key();
Object[] cacheArgs = cacheKey.split("\\.");
// 讄h参数在args[]中的序号
// key参数q行循环遍历
for (Object s : cacheArgs) {
// 判断是否是格?,$...
if (s.toString().startsWith("$")) {
// 获取参数名称
String type = s.toString().substring(1);
// 获取参数?br /> Object temp = args[0];
// 获取参数cd,不同参数cd数据处理不一?br /> Class<? extends Object> paramClazz = temp.getClass();
String classType = paramClazz.getName();
if (classType.equals("java.lang.String")) {
keyBuilder.append(temp);
} else if (classType.equals("java.util.HashMap")) {
keyBuilder.append(((HashMap) temp).get(type));
} else if (classType.startsWith("com.")) {
try {
Field f = paramClazz.getDeclaredField(type);// 实体中字D?br /> f.setAccessible(true);// 允许讉KU有字段
keyBuilder.append(f.get(temp));
} catch (SecurityException e) {
flag = false;
e.printStackTrace();
} catch (NoSuchFieldException e) {
flag = false;
e.printStackTrace();
} catch (IllegalArgumentException e) {
flag = false;
e.printStackTrace();
} catch (IllegalAccessException e) {
flag = false;
e.printStackTrace();
}
}
} else {
keyBuilder.append(s);
}
// 每个参数后面d “.”号分?br /> keyBuilder.append(".");
}
if (args.length == 3) {
keyBuilder.append(args[1] + ".").append(args[2]);
}
if (flag == true) {
key = keyBuilder.toString();
tempKey.setMemcacheKey(DateSHA.shaEncrypt(key));
tempKey.setTime(cache.time());
}
return tempKey;
}
}
我们不可能列举所有可能的固Q我们会针对几种最常见的问题进行处理。当然了Q正如前面说到的Q如果我们自׃用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情Q因此在开始之前我们先要介l一下一个开放源码的目Q这个项目就是Apache开源组l中的httpclientQ它隶属于Jakarta的commons目Q目前的版本?.0RC2。commons下本来已l有一个net的子目Q但是又把httpclient单独提出来,可见http服务器的讉Kl非易事?/font>
Commons-httpclient目是专门设计来简化HTTP客户端与服务器进行各U通讯~程。通过它可以让原来很头疼的事情现在L的解冻I例如你不再管是HTTP或者HTTPS的通讯方式Q告诉它你想使用HTTPS方式Q剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程序时l常到的几个问题进行分别介l如何用httpclient来解军_们,Z让读者更快的熟悉q个目我们最开始先l出一个简单的例子来读取一个网늚内容Q然后@序渐q解x前进中的所形侍?/font>
1Q?d|页(HTTP/HTTPS)内容 下面是我们给出的一个简单的例子用来讉K某个面 /* * Created on 2003-12-14 by Liudong */ package http.demo; import java.io.IOException; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; /** * 最单的HTTP客户?用来演示通过GET或者POST方式讉K某个面 * @author Liudong */ public class SimpleClient { public static void main(String[] args) throws IOException { HttpClient client = new HttpClient(); //讄代理服务器地址和端?nbsp; //client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port); //使用GETҎQ如果服务器需要通过HTTPSq接Q那只需要将下面URL中的http换成https HttpMethod method = new GetMethod("http://java.sun.com"); //使用POSTҎ //HttpMethod method = new PostMethod("http://java.sun.com"); client.executeMethod(method); //打印服务器返回的状?/font> System.out.println(method.getStatusLine()); //打印q回的信?/font> System.out.println(method.getResponseBodyAsString()); //释放q接 method.releaseConnection(); } 在这个例子中首先创徏一个HTTP客户?HttpClient)的实例,然后选择提交的方法是GET或者POSTQ最后在HttpClient实例上执行提交的ҎQ最后从所选择的提交方法中d服务器反馈回来的l果。这是使用HttpClient的基本流E。其实用一行代码也可以搞定整个请求的q程Q非常的单! 其实前面一个最单的CZ中我们已l介l了如何使用GET或者POST方式来请求一个页面,本小节与之不同的是多了提交时讑֮面所需的参敎ͼ我们知道如果是GET的请求方式,那么所有参数都直接攑ֈ面的URL后面用问号与面地址隔开Q每个参数用&隔开Q例如:http://java.sun.com?name=liudong&mobile=123456Q但是当使用POSTҎ时就会稍微有一点点ȝ。本节的例子演C向如何查询手机L所在的城市Q代码如下: /* * Created on 2003-12-7 by Liudong */ package http.demo; import java.io.IOException; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; /** * 提交参数演示 * 该程序连接到一个用于查询手机号码所属地的页?/font> * 以便查询LD?330227所在的省䆾以及城市 * @author Liudong */ public class SimpleHttpClient { public static void main(String[] args) throws IOException { HttpClient client = new HttpClient(); client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http"); HttpMethod method = getPostMethod();//使用POST方式提交数据 client.executeMethod(method); //打印服务器返回的状?/font> System.out.println(method.getStatusLine()); //打印l果面 String response = new String(method.getResponseBodyAsString().getBytes("8859_1")); //打印q回的信?/font> System.out.println(response); method.releaseConnection(); } /** * 使用GET方式提交数据 * @return */ private static HttpMethod getGetMethod(){ return new GetMethod("/simcard.php?simcard=1330227"); } /** * 使用POST方式提交数据 * @return */ private static HttpMethod getPostMethod(){ PostMethod post = new PostMethod("/simcard.php"); NameValuePair simcard = new NameValuePair("simcard","1330227"); post.setRequestBody(new NameValuePair[] { simcard}); return post; } } 在上面的例子中页?/font>http://www.imobile.com.cn/simcard.php需要一个参数是simcardQ这个参数gؓ手机LD,x机号码的前七位,服务器会q回提交的手机号码对应的省䆾、城市以及其他详l信息。GET的提交方法只需要在URL后加入参C息,而POST则需要通过NameValuePaircL讄参数名称和它所对应的?/font> 3Q?处理面重定?/font> 在JSP/Servlet~程中response.sendRedirectҎ是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward …>的区别在于后者是在服务器中实现页面的跌{Q也是说应用容器加载了所要蟩转的面的内容ƈq回l客LQ而前者是q回一个状态码Q这些状态码的可能D下表Q然后客Ld需要蟩转到的页面的URLq新加载新的页面。就是这样一个过E,所以我们编E的时候就要通过HttpMethod.getStatusCode()Ҏ判断q回值是否ؓ下表中的某个值来判断是否需要蟩转。如果已l确认需要进行页面蟩转了Q那么可以通过dHTTP头中的location属性来获取新的地址?/font> 状态码 client.executeMethod(post); System.out.println(post.getStatusLine().toString()); post.releaseConnection(); //查是否重定向 int statuscode = post.getStatusCode(); if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) || (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) || (statuscode == HttpStatus.SC_SEE_OTHER) || (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) { //d新的URL地址 Header header = post.getResponseHeader("location"); if (header != null) { String newuri = header.getValue(); if ((newuri == null) || (newuri.equals(""))) newuri = "/"; GetMethod redirect = new GetMethod(newuri); client.executeMethod(redirect); System.out.println("Redirect:"+ redirect.getStatusLine().toString()); redirect.releaseConnection(); } else System.out.println("Invalid redirect"); } 我们可以自行~写两个JSP面Q其中一个页面用response.sendRedirectҎ重定向到另外一个页面用来测试上面的例子?/font> 4Q?模拟输入用户名和口oq行d 本小节应该说是HTTP客户端编E中最常碰见的问题Q很多网站的内容都只是对注册用户可见的,q种情况下就必须要求使用正确的用户名和口令登录成功后Q方可浏览到惌的页面。因为HTTP协议是无状态的Q也是q接的有效期只限于当前请求,h内容l束后连接就关闭了。在q种情况下ؓ了保存用Ld信息必须使用到Cookie机制。以JSP/ServletZQ当览器请求一个JSP或者是Servlet的页面时Q应用服务器会返回一个参敎ͼ名ؓjsessionidQ因不同应用服务器而异Q,值是一个较长的唯一字符串的CookieQ这个字W串g是当前讉K该站点的会话标识。浏览器在每讉K该站点的其他面时候都要带上jsessionidq样的Cookie信息Q应用服务器Ҏdq个会话标识来获取对应的会话信息?/font> 对于需要用L录的|站Q一般在用户d成功后会用戯料保存在服务器的会话中,q样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读取当前请求对应的会话标识以获得对应的会话信息Q然后就可以判断用户资料是否存在于会话信息中Q如果存在则允许讉K面Q否则蟩转到d面中要求用戯入帐号和口oq行d。这是一般用JSP开发网站在处理用户d的比较通用的方法?/font> q样一来,对于HTTP的客L来讲Q如果要讉K一个受保护的页面时必L拟浏览器所做的工作Q首先就是请求登录页面,然后dCookie|再次hd面q加入登录页所需的每个参敎ͼ最后就是请求最l所需的页面。当然在除第一ơ请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前h是否已经通过验证。说了这么多Q可是如果你使用httpclient的话Q你甚至q一行代码都无需增加Q你只需要先传递登录信息执行登录过E,然后直接讉K惌的页面,跟访问一个普通的面没有M区别Q因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实Cq样一个访问的q程?/font> * Created on 2003-12-7 by Liudong */ package http.demo; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.cookie.*; import org.apache.commons.httpclient.methods.*; /** * 用来演示d表单的示?/font> * @author Liudong */ public class FormLoginDemo { static final String LOGON_SITE = "localhost"; static final int LOGON_PORT = 8080; public static void main(String[] args) throws Exception{ HttpClient client = new HttpClient(); client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT); //模拟d面login.jsp->main.jsp PostMethod post = new PostMethod("/main.jsp"); NameValuePair name = new NameValuePair("name", "ld"); NameValuePair pass = new NameValuePair("password", "ld"); post.setRequestBody(new NameValuePair[]{name,pass}); int status = client.executeMethod(post); System.out.println(post.getResponseBodyAsString()); post.releaseConnection(); //查看cookie信息 CookieSpec cookiespec = CookiePolicy.getDefaultSpec(); Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/", false, client.getState().getCookies()); if (cookies.length == 0) { System.out.println("None"); } else { for (int i = 0; i < cookies.length; i++) { System.out.println(cookies[i].toString()); } } //讉K所需的页面main2.jsp GetMethod get = new GetMethod("/main2.jsp"); client.executeMethod(get); System.out.println(get.getResponseBodyAsString()); get.releaseConnection(); } } 5Q?提交XML格式参数 提交XML格式的参数很单,仅仅是一个提交时候的ContentType问题Q下面的例子演示从文件文件中dXML信息q提交给服务器的q程Q该q程可以用来试Web服务?/font> import java.io.File; import java.io.FileInputStream; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.EntityEnclosingMethod; import org.apache.commons.httpclient.methods.PostMethod; /** * 用来演示提交XML格式数据的例?/font> */ public class PostXMLClient { public static void main(String[] args) throws Exception { File input = new File(“test.xml”); PostMethod post = new PostMethod(“http://localhost:8080/httpclient/xml.jsp”); // 讄h的内容直接从文g中读?/font> post.setRequestBody(new FileInputStream(input)); if (input.length() < Integer.MAX_VALUE) post.setRequestContentLength(input.length()); else post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED); // 指定h内容的类?/font> post.setRequestHeader("Content-type", "text/xml; charset=GBK"); HttpClient httpclient = new HttpClient(); int result = httpclient.executeMethod(post); System.out.println("Response status code: " + result); System.out.println("Response body: "); System.out.println(post.getResponseBodyAsString()); post.releaseConnection(); } } 6Q?通过HTTP上传文g httpclient使用了单独的一个HttpMethod子类来处理文件的上传Q这个类是MultipartPostMethodQ该cdl封装了文g上传的细节,我们要做的仅仅是告诉它我们要上传文g的全路径卛_Q下面的代码片段演示如何使用q个cR?/font> MultipartPostMethod filePost = new MultipartPostMethod(targetURL); filePost.addParameter("fileName", targetFilePath); HttpClient client = new HttpClient(); //׃要上传的文g可能比较?因此在此讄最大的q接时旉 client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); int status = client.executeMethod(filePost); 7Q?讉K启用认证的页?/font> 我们l常会碰到这L面Q当讉K它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,q种用户认证的方式不同于我们在前面介l的Z表单的用戯n份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括Q基本、摘要以及NTLM认证。其中基本认证最单、通用但也最不安全;摘要认证是在HTTP 1.1中加入的认证方式Q而NTLM则是微Y公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证q要安全的一U方式?/font> 下面例子是从httpclient的CVS服务器中下蝲的,它简单演C如何访问一个认证保护的面Q?/font> import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.methods.GetMethod; public class BasicAuthenticationExample { public BasicAuthenticationExample() { } public static void main(String[] args) throws Exception { HttpClient client = new HttpClient(); client.getState().setCredentials( "realm", new UsernamePasswordCredentials("username", "password") ); GetMethod get = new GetMethod("https://www.verisign.com/products/index.html"); get.setDoAuthentication( true ); int status = client.executeMethod( get ); System.out.println(status+""+ get.getResponseBodyAsString()); get.releaseConnection(); } } 8Q?多线E模式下使用httpclient 多线E同时访问httpclientQ例如同时从一个站点上下蝲多个文g。对于同一个HttpConnection同一个时间只能有一个线E访问,Z保证多线E工作环境下不生冲H,httpclient使用了一个多U程q接理器的c:MultiThreadedHttpConnectionManagerQ要使用q个cd单,只需要在构造HttpClient实例的时候传入即可,代码如下Q?/font> MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); HttpClient client = new HttpClient(connectionManager); 以后管讉Kclient实例卛_?/font>
}
2Q?以GET或者POST方式向网|交参?/font>
对应HttpServletResponse的常?br />
详细描述
301
SC_MOVED_PERMANENTLY
面已经怹Ud另外一个新地址
302
SC_MOVED_TEMPORARILY
面暂时Ud到另外一个新的地址
303
SC_SEE_OTHER
客户端请求的地址必须通过另外的URL来访?br />
307
SC_TEMPORARY_REDIRECT
同SC_MOVED_TEMPORARILY
下面的代码片D|C如何处理页面的重定?/font>
/*
上面代码中,targetFilePath即ؓ要上传的文g所在的路径?/font>
import org.apache.commons.httpclient.HttpClient;
package com.org.softwore;
import org.apache.commons.httpclient.methods.GetMethod;
public class UTF8GetMethod extends GetMethod {
public static final String ENCODE_UTF8 = "UTF-8";
/**
* 默认构造函?br />
*
* @param url
* 地址
*/
public UTF8GetMethod(String url) {
super(url);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.commons.httpclient.methods.EntityEnclosingMethod#getRequestCharSet
* ()
*/
@Override
public String getRequestCharSet() {
return ENCODE_UTF8;
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.httpclient.HttpMethodBase#getResponseCharSet()
*/
@Override
public String getResponseCharSet() {
return ENCODE_UTF8;
}
}
鼎鼎大名的Spring框架3.0版在12?日由其作者之一——Juergen Hoeller先生在博客里宣告问世Qƈ命ؓ里程版Q给Spring_丝们带来了震撼的快感。笔者即开“快R”拉了两个包回来,遗憾的是参考文档至今还没有出来(仅有API文档)Q这为学习Spring 3.0带来了非常大的困难,但没有阻挡笔者对C品的兴趣?/font>
Spring之父Rod Johnson先生早在2003q就预言EJB死(观点颇具争议)Q攻击EJB之臃肿是在虐待程序员。然而EJB 3.0出来后几乎宣判SpringdQ但?.0版以后Spring火爆E度已经过EJBQ两者的争斗至今仍不停息Q这也是Spring 3.0q文档还没有整理出来匆匆推出的原因。当ӞSpring与EJB有很多各自独特优势之处,例如EJB的分布式q算、标准规范,Spring的IoC、AOP切面~程、偶合集成、MVC{等Q取各自之长在企业中应用如虎ȝ。Spring目前已经加入了J2EE规范QJ2EE世界更加精?.....
或许是用MStruts1那死板的WEB框架Q才对Spring MVC׃释手Q尤其是2.5版本以后Q支持全注解配置方式Q已l很久没有再写qxml文g了?/font>
3.0版是完全兼容2.5Q因此了?.5版的@MVC则更Ҏ接受。正如Arjen Poutsma伙子在他的博客里说的那P3.0时代集中致力于表述性状态{U?RESTQ希望我没有译错,金山词霸译?#8220;休息”)的网l服务和更容易的|络~程。的增加了更多的控制器cdQƈ增强了SOAP/WSDL/WSq些Z分布式体pȝ构?/font>
先回忆下2.5注解方式的@MVCQ来一个示例:
@Controller
public class ArticleController{
@RequestMapping("/articleView")
public String getArticle(@RequestParam("id") String id, HttpServletRequest request){
request.setAttribute("article", service.find(Article.class, id));
return "articleView";
}
}
ArticleController没有实现M接口Q是一个最普通不q的pojoQ如果浏览器来了articleView.do?id=xxxq个hQSpring会找到getArticle()q个ҎQ该ҎW一个参数绑定到了URL上的h参数Q第二个是J2EE标准的request对象(可见Spring MVC是非侵入式的Q不像变态的Struts2)Q事实上q可以给定HttpServletResponse,ModelMap,甚至自己的类型,Spring都会Zg入进来。通过一个逻辑层servicelgҎid参数值去底层查找Article对象Qƈ攑օrequest作用域中Q最后返回的是面视囑Q这个例子中是返回到articleView.jsp中?/font>
上例再变通下Q?/font>
@Controller
public class ArticleController{
@RequestMapping("/articleView_*")
public String getArticle(HttpServletRequest request){
String id = StringUtil.getParam(request.getRequestURI(),"articleView_*");
request.setAttribute("article", service.find(Article.class, id));
return "articleView";
}
}
对于articleView_aaa.doQarticleView_bbbb.doQarticleView_c5h8j2.doQarticleView_xxx.doQ这Lh都会由getArticle()q个Ҏ来应付,是不是很有意思?
Spring 3.0增加了一?strong style="font-weight: bold; line-height: 32px">@ PathVariable注解来支持可变的h路径Q将上面的代码在3.0版中再变通下Q?font style="line-height: 32px" size="4">
@Controller
public class ArticleController{
@RequestMapping("/articleView/${id}") //可以接受articleView/aaa.do,articleView/xxx.do...
public String getArticle(@PathVariable String id, HttpServletRequest request){
request.setAttribute("article", service.find(Article.class, id));
return "articleView";
}
}
再变得复杂些Q?/p>
@Controller
public class ArticleController{
@RequestMapping("/articleList/${pageSize}/channel/*/category/${id}")
public String getArticles((@PathVariable Integer pageSize, @PathVariable int id, HttpServletRequest request){
Integer channelId = StringUtil.getParam(request.getRequestURI(),"channel/*/");
request.setAttribute("articles", service.findScroll(Article.class, pageSize,50,"channel=? and category=?",new Object[]{channelId,id}));
return "articleList";
}
}
它已l灵zdURL地址完全可以自己随意~制?/p>
Ҏ内容协商制的视图解析机制Q?/strong>
2.5版是由@MVC控制器来军_视图解析器,3.0版将变得更加灉|Q似乎可以通过扩展名来转到不同的解析器中,例如h一?pdf文g是如何效果呢?3.0版都会带来不可思议的模式?/p>
HTTPҎ的{换:
先看前台面一DHtml代码
<form:form method="delete">
<p class="submit"><input type="submit" value="Delete Pet"/></p>
</form:form>
HTTP规范中form表单只有两种Ҏ——POST和GETQ?.0做了一个过滤器Q可以{换这些方法至四种——GET, PUT, POST, ?DELETE。控制器接受hQ?/p>
@Controller("/deleteArticle")
public class ArticleController{
service.delete(Article.class, id);
return "message";
}
}
3.0版仅在MVC子集中就增加了很多新Ҏ,如果在IoC、AOP{等其它子集所有的变革Q绝对可以称得上Srping创始人所q的里程版本?.0版用的注解列表如下Q?/p>
? @Autowired
? @Component
? @Controller
? @InitBinder
? @ManagedAttribute
? @ManagedOperation
? @ManagedOperationParameters
? @ManagedOperationParameter
? @ManagedResource
? @PathVariable
? @PostConstruct
? @PreDestroy
? @Repository
? @RequestMapping
? @Required
? @Resource
? @Service
? @Transactional
目前Spring 3版本已经CM2Q应该是M3完成后将推出最l正式版本,我想很快会来_按照Spring的创始h|d.U翰逊的预言Q未来J2EE应用中Spring+Tomcat占dCQ是否引起争议,W者不敢点评,不过Oracle收购Sun后,JavaC是如何Q还无从知晓Q似乎罗?U翰逊对q宗收购案也有些紧张Q因为Oracle不像Sun的第一个谈判者IBM那样有过开放技术的先例(可以回忆下IBM早期的主板ȝ开放掀L兼容机潮至今波涛不熄)。目前国内对C西消化尚慢,我到图书城看了下QSpring 2.5的资料都很难扑ֈ。且很多企业都是qStruts1.x在做开发,管W者这栯会引来很多争议,但Struts1时代的灭亡只是时间问题。Struts2虽然改进了很多,依笔者看Q与Spring MVC相比仍有诸多的不I其看不惯那U变态的侵入模式Q看看它把HttpServletRequest、HttpSession、HttpServletResponse{servlet标准lgq成什么样Q开源时代,臛_我不愿意接受那种变态的潜规则?/p>
W者对Spring框架研究肤浅Q待日后了解掌握更多时会常在博客中述之?br style="line-height: 32px" />
public void create(List<Reply> replyList) { try { // 开始批处理 sqlMapClient.startBatch(); for (Reply reply: replyList) { // 插入操作 sqlMapClient.insert("Reply.create", reply); } // 执行批处? sqlMapClient.executeBatch(); } catch (Exception e) { e.printStackTrace(); } }
public void create(List<Reply> replyList) { try { // 开始事? sqlMapClient.startTransaction(); // 开始批处理 sqlMapClient.startBatch(); for (Reply reply: replyList) { // 插入操作 sqlMapClient.insert("Reply.create", reply); } // 执行批处? sqlMapClient.executeBatch(); // 提交事务 sqlMapClient.commitTransaction(); } catch (Exception e) { e.printStackTrace(); } finally { try { // l束事务 sqlMapClient.endTransaction(); } catch (SQLException e) { e.printStackTrace(); } } }
public void create(List<Reply> replyList) { if (!CollectionUtils.isEmpty(replyList)) { // 注意使用同一个SqlMapClient会话 SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient(); try { // 开始事? sqlMapClient.startTransaction(); // 开始批处理 sqlMapClient.startBatch(); for (Reply reply : replyList) { // 插入操作 sqlMapClient.insert("Reply.create", reply); } // 执行批处? sqlMapClient.executeBatch(); // 提交事务 交给Springl一控制 // sqlMapClient.commitTransaction(); } catch (Exception e) { e.printStackTrace(); } finally { try { // l束事务 sqlMapClient.endTransaction(); } catch (SQLException e) { e.printStackTrace(); } } } }
@SuppressWarnings("unchecked") public void create(final List<Reply> replyList) { // 执行回调 sqlMapClientTemplate.execute(new SqlMapClientCallback() { // 实现回调接口 public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { // 开始批处理 executor.startBatch(); for (Reply reply : replyList) { // 插入操作 executor.insert("Reply.create", reply); } // 执行批处? executor.executeBatch(); return null; } }); }
1. 配置文g
Log4J配置文g的基本格式如下:
#配置根Logger
log4j.rootLogger = [ level ] , appenderName1 , appenderName2 , …
#配置日志信息输出目的地Appender
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.optionN = valueN
#配置日志信息的格式(布局Q?br />
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.optionN = valueN
其中 [level] 是日志输出别,共有5U:
FATAL 0
ERROR 3
WARN 4
INFO 6
DEBUG 7
Appender 为日志输出目的地QLog4j提供的appender有以下几U:
org.apache.log4j.ConsoleAppenderQ控制台Q,
org.apache.log4j.FileAppenderQ文ӞQ?br />
org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文ӞQ?br />
org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文ӞQ?br />
org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)
LayoutQ日志输出格式,Log4j提供的layout有以下几U:
org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)
打印参数: Log4J采用cMC语言中的printf函数的打印格式格式化日志信息Q如?
%m 输出代码中指定的消息
%p 输出优先U,即DEBUGQINFOQWARNQERRORQFATAL
%r 输出自应用启动到输出该log信息耗费的毫U数
%c 输出所属的cȝQ通常是所在类的全?
%t 输出产生该日志事件的U程?
%n 输出一个回车换行符QWindowsq_?#8220;\r\n”QUnixq_?#8220;\n”
%d 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss , SSS}Q输出类|2002q?0?8?nbsp; 22 Q?10 Q?28 Q?921
%l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main(TestLog4.java: 10 )
2. 在代码中初始化Logger:
1Q在E序中调用BasicConfigurator.configure()ҎQ给根记录器增加一个ConsoleAppenderQ输出格式通过PatternLayout设ؓ"%-4r [%t] %-5p %c %x - %m%n"Q还有根记录器的默认U别是Level.DEBUG.
2Q配|放在文仉Q通过命o行参C递文件名字,通过PropertyConfigurator.configure(args[x])解析q|;
3Q配|放在文仉Q通过环境变量传递文件名{信息,利用log4j默认的初始化q程解析q|;
4Q配|放在文仉Q通过应用服务器配|传递文件名{信息,利用一个特D的servlet来完成配|?/p>
3. Z同的 Appender 讄日志输出U别Q?br /> 当调试系l时Q我们往往注意的只是异常别的日志输出Q但是通常所有别的输出都是攑֜一个文仉的,如果日志输出的别是BUGQ?那就慢慢L吧?br /> q时我们也许会想要是能把异常信息单独输出C个文仉该多好啊。当然可以,Log4j已经提供了这L功能Q我们只需要在配置中修改Appender的Threshold p实现,比如下面的例子:
[配置文g]
### set log levels ###
log4j.rootLogger = debug , stdout , D , E
### 输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n
### 输出到日志文?###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG ## 输出DEBUGU别以上的日?br />
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 保存异常信息到单独文?###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/error.log ## 异常日志文g?br />
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR ## 只输出ERRORU别以上的日?!!
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
[代码中用]
public class TestLog4j {
public static void main(String[] args) {
PropertyConfigurator.configure( " D:/Code/conf/log4j.properties " );
Logger logger = Logger.getLogger(TestLog4j. class );
logger.debug( " debug " );
logger.error( " error " );
}
}
q行一下,看看异常信息是不是保存在了一个单独的文gerror.log?/p>
log4j.properties 使用
一.参数意义说明
输出U别的种c?br />
ERROR、WARN、INFO、DEBUG
ERROR Z重错?主要是程序的错误
WARN Z般警告,比如session丢失
INFO Z般要昄的信息,比如dd
DEBUG 为程序的调试信息
配置日志信息输出目的?br />
log4j.appender.appenderName = fully.qualified.name.of.appender.class
1.org.apache.log4j.ConsoleAppenderQ控制台Q?br />
2.org.apache.log4j.FileAppenderQ文Ӟ
3.org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文Ӟ
4.org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文Ӟ
5.org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)
配置日志信息的格?br />
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
1.org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
2.org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
3.org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
4.org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)
控制台选项
Threshold=DEBUG:指定日志消息的输出最低层ơ?br />
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?br />
Target=System.errQ默认情况下是:System.out,指定输出控制?br />
FileAppender 选项
Threshold=DEBUF:指定日志消息的输出最低层ơ?br />
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?br />
File=mylog.txt:指定消息输出到mylog.txt文g?br />
Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?br />
RollingFileAppender 选项
Threshold=DEBUG:指定日志消息的输出最低层ơ?br />
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?br />
File=mylog.txt:指定消息输出到mylog.txt文g?br />
Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?br />
MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小Ӟ会自动滚动Q即原来的内容Udmylog.log.1文g?br />
MaxBackupIndex=2:指定可以产生的滚动文件的最大数?br />
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
日志信息格式中几个符h代表的含义:
-X? X信息输出时左寚wQ?br />
%p: 输出日志信息优先U,即DEBUGQINFOQWARNQERRORQFATAL,
%d: 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss,SSS}Q输出类|2002q?0?8?22Q?0Q?8Q?21
%r: 输出自应用启动到输出该log信息耗费的毫U数
%c: 输出日志信息所属的cȝQ通常是所在类的全?br />
%t: 输出产生该日志事件的U程?br />
%l: 输出日志事g的发生位|,相当?C.%M(%F:%L)的组?包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main (TestLog4.java:10)
%x: 输出和当前线E相兌的NDC(嵌套诊断环境),其用到像java servletsq样的多客户多线E的应用中?br />
%%: 输出一?%"字符
%F: 输出日志消息产生时所在的文g名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信?br />
%n: 输出一个回车换行符QWindowsq_?\r\n"QUnixq_?\n"输出日志信息换行
可以?与模式字W之间加上修饰符来控制其最宽度、最大宽度、和文本的对齐方式。如Q?br />
1)%20cQ指定输出category的名Uͼ最的宽度?0Q如果category的名U小?0的话Q默认的情况下右寚w?br />
2)%-20c:指定输出category的名Uͼ最的宽度?0Q如果category的名U小?0的话Q?-"h定左寚w?br />
3)%.30c:指定输出category的名Uͼ最大的宽度?0Q如果category的名U大?0的话Q就会将左边多出的字W截掉,但小?0的话也不会有I格?br />
4)%20.30c:如果category的名U小?0pI格Qƈ且右寚wQ如果其名称长于30字符Q就从左边较q输出的字符截掉?br />
?文g配置Sample1
log4j.rootLogger=DEBUG,A1,R
#log4j.rootLogger=INFO,A1,R
# ConsoleAppender 输出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
# File 输出 一天一个文?输出路径可以定制,一般在根\径下
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=blog_log.txt
log4j.appender.R.MaxFileSize=500KB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
文g配置Sample2
下面l出的Log4J配置文g实现了输出到控制収ͼ文gQ回滚文Ӟ发送日志邮Ӟ输出到数据库日志表,自定义标{全套功能?br />
log4j.rootLogger=DEBUG,CONSOLE,A1,im
#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE
log4j.addivity.org.apache=true
###################
# Console Appender
###################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#####################
# File Appender
#####################
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
########################
# Rolling File
########################
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
####################
# Socket Appender
####################
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
########################
# Log Factor 5 Appender
########################
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
########################
# SMTP Appender
#######################
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=chenyl@yeqiangwei.com
log4j.appender.MAIL.SMTPHost=mail.hollycrm.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=chenyl@yeqiangwei.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
########################
# JDBC Appender
#######################
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
###################
#自定义Appender
###################
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@yeqiangwei.com
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
?高使用
实验目的Q?br />
1.把FATALU错误写?000NT日志
2. WARNQERRORQFATALU错误发送email通知理?br />
3.其他U别的错误直接在后台输出
实验步骤Q?br />
输出?000NT日志
1.把Log4j压羃包里的NTEventLogAppender.dll拷到WINNT\SYSTEM32目录?br />
2.写配|文件log4j.properties
# ?000pȝ日志输出
log4j.logger.NTlog=FATAL, A8
# APPENDER A8
log4j.appender.A8=org.apache.log4j.nt.NTEventLogAppender
log4j.appender.A8.Source=JavaTest
log4j.appender.A8.layout=org.apache.log4j.PatternLayout
log4j.appender.A8.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
3.调用代码Q?br />
Logger logger2 = Logger.getLogger("NTlog"); //要和配置文g中设|的名字相同
logger2.debug("debug!!!");
logger2.info("info!!!");
logger2.warn("warn!!!");
logger2.error("error!!!");
//只有q个错误才会写入2000日志
logger2.fatal("fatal!!!");
发送email通知理员:
1. 首先下蝲JavaMail和JAF,
http://java.sun.com/j2ee/ja/javamail/index.html
http://java.sun.com/beans/glasgow/jaf.html
在项目中引用mail.jar和activation.jar?br />
2. 写配|文?br />
# 日志发送到email
log4j.logger.MailLog=WARN,A5
# APPENDER A5
log4j.appender.A5=org.apache.log4j.net.SMTPAppender
log4j.appender.A5.BufferSize=5
log4j.appender.A5.To=chunjie@yeqiangwei.com
log4j.appender.A5.From=error@yeqiangwei.com
log4j.appender.A5.Subject=ErrorLog
log4j.appender.A5.SMTPHost=smtp.263.net
log4j.appender.A5.layout=org.apache.log4j.PatternLayout
log4j.appender.A5.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
3.调用代码Q?br />
//把日志发送到mail
Logger logger3 = Logger.getLogger("MailLog");
logger3.warn("warn!!!");
logger3.error("error!!!");
logger3.fatal("fatal!!!");
在后台输出所有类别的错误Q?br />
1. 写配|文?br />
# 在后台输?br />
log4j.logger.console=DEBUG, A1
# APPENDER A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
2Q调用代?br />
Logger logger1 = Logger.getLogger("console");
logger1.debug("debug!!!");
logger1.info("info!!!");
logger1.warn("warn!!!");
logger1.error("error!!!");
logger1.fatal("fatal!!!");
--------------------------------------------------------------------
全部配置文gQlog4j.properties
# 在后台输?br />
log4j.logger.console=DEBUG, A1
# APPENDER A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
# ?000pȝ日志输出
log4j.logger.NTlog=FATAL, A8
# APPENDER A8
log4j.appender.A8=org.apache.log4j.nt.NTEventLogAppender
log4j.appender.A8.Source=JavaTest
log4j.appender.A8.layout=org.apache.log4j.PatternLayout
log4j.appender.A8.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
# 日志发送到email
log4j.logger.MailLog=WARN,A5
# APPENDER A5
log4j.appender.A5=org.apache.log4j.net.SMTPAppender
log4j.appender.A5.BufferSize=5
log4j.appender.A5.To=chunjie@yeqiangwei.com
log4j.appender.A5.From=error@yeqiangwei.com
log4j.appender.A5.Subject=ErrorLog
log4j.appender.A5.SMTPHost=smtp.263.net
log4j.appender.A5.layout=org.apache.log4j.PatternLayout
log4j.appender.A5.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
全部代码QLog4jTest.java
/*
* 创徏日期 2003-11-13
*/
package edu.bcu.Bean;
import org.apache.log4j.*;
//import org.apache.log4j.nt.*;
//import org.apache.log4j.net.*;
/**
* @author yanxu
*/
public class Log4jTest
{
public static void main(String args[])
{
PropertyConfigurator.configure("log4j.properties");
//在后台输?
Logger logger1 = Logger.getLogger("console");
logger1.debug("debug!!!");
logger1.info("info!!!");
logger1.warn("warn!!!");
logger1.error("error!!!");
logger1.fatal("fatal!!!");
//在NTpȝ日志输出
Logger logger2 = Logger.getLogger("NTlog");
//NTEventLogAppender nla = new NTEventLogAppender();
logger2.debug("debug!!!");
logger2.info("info!!!");
logger2.warn("warn!!!");
logger2.error("error!!!");
//只有q个错误才会写入2000日志
logger2.fatal("fatal!!!");
//把日志发送到mail
Logger logger3 = Logger.getLogger("MailLog");
//SMTPAppender sa = new SMTPAppender();
logger3.warn("warn!!!");
logger3.error("error!!!");
logger3.fatal("fatal!!!");
}
}
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/azheng270/archive/2008/03/12/2173430.aspx