2009年6月3日
#
1、在本地数据库中创建如下表:
-- Create table
create table TMP_CR_PERSONS
(
SPECIALTY VARCHAR2(50),
USER_GROUP VARCHAR2(50),
USER_NAME VARCHAR2(50),
USER_CATEGORY VARCHAR2(50)
)
2、创建DBLINK:
create database link LK2PMS connect to XXX identified by XX
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.5.99)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = oradb9)
)
)'
3、创建视图,查询变更清单:
CREATE OR REPLACE VIEW V_TMP_CR_LIST AS
SELECT D.CHANGE_REQUEST_CODE,
D.PROJECT_NAME,
D.PRODUCT_NAME,
D.MODULE_NAME,
D.TYPE,
D.PRIVILEGE,
D.PROPOSE_TIME,
WF.TRANSACTOR,
WF.TASKNAME,
P.SPECIALTY,
P.USER_GROUP,
P.USER_CATEGORY
FROM PMS_CHANGE@lk2pms D,
(SELECT MAX(ID) ID
FROM WFT_FLOWCONTROL@lk2pms WF
WHERE WF.WORKFLOWID = 'ChangeRequest'
GROUP BY WF.WORKID) MX,
WFT_FLOWCONTROL@lk2pms WF,
TMP_CR_PERSONS P
WHERE WF.ID = MX.ID
AND WF.WORKID = D.CHANGE_REQUEST_ID
AND D.CHANGE_REQUEST_CODE LIKE 'CR%'
AND WF.TRANSACTOR = P.USER_NAME
AND D.STATE NOT IN ('结束','终止','拒绝');
4、创建统计视图:
CREATE VIEW V_TMP_CR_STAT AS
SELECT T.USER_GROUP, T.USER_NAME, COUNT(V.CHANGE_REQUEST_CODE) TOTAL
FROM V_TMP_CR_LIST V, TMP_CR_PERSONS T
WHERE V.TRANSACTOR(+) = T.USER_NAME
GROUP BY CUBE(T.USER_GROUP, T.USER_NAME);
1、当然是访问老系统中的,应该都采用兼容视图
2、在访问网公司系统的时候,出现内存不能写的错误提示,让后直接页面加载失败,解决办法是,找到用SOGOU浏览器加载页面后,发现需要安装JITDSign这个插件,所以手工找到JITDSign.cab,解压后直接运行“regsvr32 JITDSign.ocx”,再刷新页面,OK了。
3、其他问题暂未发现。
1、利用命令“D:\FWMS\code\trunk\main\ear\ejb>dir /a:d /b”,列举出所有的EJB模块清单
2、结合上面的清单,结合正则“^(.*)$”,替换为“<ant antfile="${FWMS_code}/ear/ejb/$1/META-INF/build.xml" dir="${FWMS_code}/ear/ejb/$1/META-INF" target="ejbdoclet"/>”形式,并将得到的ant元素清单放置到工程下build.xml的“Generating_Code”target中。
3、基于如下正则,利用UE批量替换properties文件中的project.path:
查找:(project.path.*)
目标:project.path=../../../APP-INF/classes;../../../APP-INF/lib/activation.jar;../../../APP-INF/lib/ant.jar;../../../APP-INF/lib/apachepoi.jar;../../../APP-INF/lib/axis.jar;../../../APP-INF/lib/axis-ant.jar;../../../APP-INF/lib/bsh2.0.jar;../../../APP-INF/lib/classes12.zip;../../../APP-INF/lib/commons-
文件:build.properties
路径:D:\FWMS\code\trunk\main\ear\ejb\
(注意需要选中搜索子目录项)
4、上述完成之后,执行build_code.bat 即可完成EJB的编译
5、设置ct-config.xml中相关内容,最后是启动weblogic 并设置数据源,同时发布应用。
6、发布启动weblogic的时候,报“java.lang.OutOfMemoryError: PermGen space”异常,在C:\bea\weblogic92\common\bin的commEnv.cmd中,查看到其内存设置为“set MEM_ARGS=-Xms128m -Xmx256m”;在C:\bea\user_projects\domains\fwms_domain\bin下startWebLogic.cmd中,添加“set MEM_ARGS=-Xms256m -Xmx512m -XX:MaxPermSize=128m”,适当加大内存。
此处的CAS是指Central Authentication Service,也即统一认真服务,这里采用的是JASIG提供的相关服务端及客户端类库,结合TOMCAT进行测试。
1、下载相关的服务器端和客户端类库,官网是:
http://www.jasig.org/cas/,目前我采用的是:
服务器端:cas-server-3.3.4-release.zip
客户端:cas-client-2.0.11.zip
2、配置TOMCAT的SSL,具体可见上一篇博文:
在%CATALINA_HOME%/conf/server.xml中,添加:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="F:\eclipse\workspace\httpc\tomcat3.keystore"
keystorePass="123456"/>
配置OK后,可通过访问“https://localhost:8443/examples/servlets/servlet/HelloWorldExample”来进行验证
3、配置CAS服务器端:
将cas-server-3.3.4-release.zip中modules文件夹下的cas-server-webapp-3.3.4.war的解压到TOMCAT的webapps目录下。
重启TOMCAT后,可以通过访问“http://localhost:8080/cas/login”并输入相同的用户名密码来进行验证。
另:需要特别说明,cas应用中默认配置的是SimpleTestUsernamePasswordAuthenticationHandler,该处理类只要保持用户名、密码一直即可通过验证。
4、配置CAS客户端:
在webapps\examples\WEB-INF中,对web.xml添加如下内容:
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
<param-value>https://localhost:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://localhost:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>localhost:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlets/servlet/HelloWorldExample</url-pattern>
</filter-mapping>
同时,将cas-client-2.0.11.zip中的casclient.jar,拷贝到webapps\examples\WEB-INF\lib中,重启TOMCAT即可进行验证。
5、验证CAS:
a、在浏览器中访问“http://localhost:8080/examples/servlets/servlet/HelloWorldExample”
b、基于前面配置的过滤器,浏览器会定向CAS的认证页面“https://localhost:8443/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2Fexamples%2Fservlets%2Fservlet%2FHelloWorldExample”
c、在CAS的认证页面中输入相同的用户名密码test/test后,执行登录
d、浏览器提示安全警告,点击确定后即转入到“http://localhost:8080/examples/servlets/servlet/HelloWorldExample?ticket=ST-1-xWK9nwArDLbjCwYiXOqu-cas”,同时页面打出“Hello World”,配置成功。
HTTP Client是一个客户端HTTP协议的类库
1、首先是下载APACHE HTTP CLIENT相关的JAR,目前我引入到工程中的相关文件时:
httpclient-4.0.3.jar
httpcore-4.0.1.jar
httpmime-4.0.3.jar
commons-codec-1.4.jar
commons-logging-1.1.1.jar
JAR包之前的引用关系在README等相关说明中已有。
2、下载并运行TOMCAT,我下载的是TOMCAT6(对应的是JDK5),主要注意的是需要配置CATALINA_HOME这个环境变量。
3、制作服务器端证书,下面是我一个示例:
C:\Documents and Settings\dingjunxing>keytool -genkey -alias tomcat3 -keystore F
:\eclipse\workspace\httpc\tomcat3.keystore
输入keystore密码: 123456
您的名字与姓氏是什么?
[Unknown]: localhost
您的组织单位名称是什么?
[Unknown]: sz
您的组织名称是什么?
[Unknown]: sz
您所在的城市或区域名称是什么?
[Unknown]: shenzhen
您所在的州或省份名称是什么?
[Unknown]: guangdong
该单位的两字母国家代码是什么
[Unknown]: cn
CN=localhost, OU=sz, O=sz, L=shenzhen, ST=guangdong, C=cn 正确吗?
[否]: y
输入<tomcat3>的主密码
(如果和 keystore 密码相同,按回车): 123456
4、根据服务器证书导出客户端证书,有两种方式,一种为采用IE,下面提供一个利用KEY TOOL导出的方式:
keytool -export -file tomcat3.cert -alias tomcat3 -keystore F:\eclipse\workspace\httpc\tomcat3.keystore
注意:上面命令行必须进入到%java_home%/jre/lib/security中。
5、将获取到的客户端证书导入:
C:\Program Files\Java\jdk1.5.0_15\jre\lib\security>keytool -import -keystore cac
erts -file F:\eclipse\workspace\httpc\tomcat3.cert
输入keystore密码: 123456
Owner: CN=localhost, OU=sz, O=sz, L=shenzhen, ST=guangdong, C=cn
发照者: CN=localhost, OU=sz, O=sz, L=shenzhen, ST=guangdong, C=cn
序号: 4cc55438
有效期间: Mon Oct 25 17:56:08 CST 2010 至: Sun Jan 23 17:56:08 CST 2011
认证指纹:
MD5: E4:2E:BE:AC:A1:5D:E0:95:C7:95:93:BF:B3:F3:EE:5E
SHA1: F8:9A:BB:FA:C8:C5:8A:D2:FA:98:A1:95:64:65:42:9A:8F:0B:4A:7D
信任这个认证? [否]: y
认证已添加至keystore中
6、TOMCAT中相关设置,主要是修改CATALINA_HOME下的conf/server.xml,在其中添加如下一个连接器:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="F:\eclipse\workspace\httpc\tomcat3.keystore" keystorePass="123456"/>
7、运行相关代码:
package org.apache.http.examples.client;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
/**
* This example demonstrates how to create secure connections with a custom SSL
* context.
*/
public class ClientCustomSSL {
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File("tomcat3.keystore"));
try {
trustStore.load(instream, "123456".toCharArray());
} finally {
instream.close();
}
SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
Scheme sch = new Scheme("https", socketFactory, 8443);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
HttpGet httpget = new HttpGet("https://localhost:8443/docs");
System.out.println("executing request" + httpget.getRequestLine());
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
if (entity != null) {
entity.consumeContent();
}
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
运行结果正常,当然也可以通过在浏览器中输入“https://localhost:8443/”的方式进行访问。
在网上找到一份比较老的参考文档:http://www.ibm.com/developerworks/cn/webservices/ws-casestudy/part4/
1、列举出来其需要的几项功能:
该服务主要需要具备三项功能:
- 用户注册:用户在统一身份认证服务中注册帐号,以后这个帐号可以在所有使用统一身份认证服务的应用系统中使用。
- 帐号关联:如果用户之前已经在相关的应用系统中拥有帐号,同时也已经设置了相应的权限,那么用户能够将这些应用
系统的帐号与统一身份认证服务的帐号进行关联,使得用户登录统一身份认证服务之后,就能够自动使用相关的应用系统用户来访问应用系统。
- 用户认证:为应用系统提供用户身份认证,兼顾两个应用方式:
-
- 应用系统使用统一身份认证服务作为它的用户系统,用户与应用系统进行交互,进行登录操作,应用
系统将用户提供的用户名/密码等转发给统一身份认证服务以检验其是否通过授权。
- 用户首先登录统一身份认证服务,并获取权限令牌,以后可以使用这个权限令牌访问其他的应用系
统,应用系统接收该权限令牌时应当与统一身份认证服务进行交互,以检验访问的合法性。
用户注册
用户注册(包括用户更新注册信息)的流程可以使用下图来表示。其中主要包含了两个流程:新用户注册和用户更新注册信息。
新用户注册:
- 用户向统一身份认证服务发出新用户注册请求
- 服务查询用户注册库,如果该用户可以注册(没有同名ID等违背约束条件的情况发生),那么将该用户的信息保存到
用户注册库中。
- 当保存完毕后,统一身份认证服务响应用户,注册完成。
用户更新注册信息:
- 用户向统一身份认证服务发出用户注册信息更新请求。
- 服务查询用户注册库,如果该用户信息可以更新(有该ID存在,同时提供的密码也是正确的等等),那么将该用户的
信息将在用户注册库中更新。
- 当保存完毕后,统一身份认证服务响应用户,更新完成。
帐号关联
帐号关联操作可以使用下图来表示。图中仅包含一个登记新的帐号关联的操作,相关的修改、删除操作被省略了,有兴趣的读者可
以自行给出
登记新的帐号关联:
- 用户向统一身份认证服务发出帐号关联注册请求,用户提供了应用系统的标识A,同时提供了可以在该应用系统中使用
的用户信息(可能包含用户名和密码等)。
- 服务首先向该应用系统A征询,用户信息是否合法。如果合法则响应服务。
- 如果收到合法响应,那么服务就将这个帐号关联注册信息保存到用户注册库中,以后该用户登录统一身份认证服务之
后,就能够使用相应的应用系统A。
- 当注册库完成保存操作后,统一身份认证服务响应用户,注册完成。
身份认证组件模式
统一身份认证服务的一个基本应用模式是以应用系统的身份认证组件的形式工作,在这个应用模式下,主导地位的是应用系统。在
这种情况下,应用系统自身没有用户系统,因此本模式下涉及的帐号一定是统一身份认证服务的用户帐号。
流程描述如下:(仅描述正常流程)
- 用户使用在统一认证服务注册的用户名和密码(也可能是其他的授权信息,比如数字签名等)登陆应用系统A
- 应用系统A,将用户名和密码连同自己的标识(应用系统A的标识)一起转发给统一认证服务,要求统一认证服务完成
登录操作。
- 统一认证服务核查自己的应用系统注册库(使用UDDI Registry,我将在后面解释为什么使用UDDI
Registry)看看应用系统A是否已经是统一认证服务的用户系统。同时在用户注册库中核查由应用系统A转发过来的用户名和密码。
- 待核查完毕后,统一认证服务响应应用系统A,登录完成。
- 应用系统A创建一个系统会话(Session,系统A自己的机制),并将应用系统A自己的权限令牌返回给用户,
以后用户端可以通过这个权限令牌持续访问应用系统A,直至登出系统或是会话超时。
统一认证模式
统一认证模式是以统一身份认证服务为核心的服务使用模式。用户登录统一身份认证服务后,即可使用所有支持统一身份认证服务
的应用系统。
流程描述如下:(仅描述正常流程)
- 用户使用在统一认证服务注册的用户名和密码(也可能是其他的授权信息,比如数字签名等)登陆统一认证服务;
- 统一认证服务创建了一个会话,同时将与该会话关联的访问认证令牌返回给用户;
- 用户使用这个访问认证令牌访问某个支持统一身份认证服务的应用系统;
- 该应用系统将访问认证令牌传入统一身份认证服务,认证访问认证令牌的有效性;
- 统一身份认证服务确认认证令牌的有效性;
- 应用系统接收访问,并返回访问结果,如果需要提高访问效率的话,应用系统可选择返回其自身的认证令牌已使得用户
之后可以使用这个私有令牌持续访问。
此外,关于访问认证令牌的失效,有两个策略,一个是由用户主动发起声明,声明其拥有的访问认证令牌不再有效,这类似注销的
操作,另一个是用户一段时间内没有使用这个认证令牌,认证令牌自动失效,这类似超时的处理。
信任代理模式
在Internet应用环境下,安全性和信任的重要性是显而易见的,对于商用系统而言,避免非法访问和入侵是他所需要考虑
的几个重要问题之一,没有比商用数据丢失或是商用系统被违规使用更糟糕的了。
在信任代理模式下,一个组织可以为他所有需要提供安全信任保障的应用系统设置一个统一身份认证服务,对这些应用系统的访问
全部由统一身份认证服务代理。
流程描述如下:(仅描述正常流程)
- 用户使用在统一认证服务注册的用户名和密码(也可能是其他的授权信息,比如数字签名等)登陆统一认证服务;
- 统一认证服务创建了一个会话,同时将与该会话关联的访问认证令牌返回给用户;
- 用户使用这个访问认证令牌访问某个支持统一身份认证服务的应用系统,不过用户并不将请求消息直接交给应用系统,
而是传给统一身份认证服务,在消息中标识了最终的应用系统的ID。
- 统一认证服务访问应用系统注册库(UDDI
Registry),获取了应用系统的访问入口(统一认证服务可以将这个访问入口缓存在本地,以减少以后与应用系统注册库的交互次数)。并确认这个应用系
统的确是支持统一身份认证服务的;
- 统一认证服务将请求消息转发给指定的应用系统,如果该应用系统使用自己的用户系统的话,那么该消息应当包含了预
先定义好的相关联的用户名和密码等。
- 应用系统将请求结果返回给统一认证服务,最后统一认证服务将响应消息返回给用户,完成调用。
在该模式下,所有应用系统仅接收来自统一认证服务的访问请求,这样,解决方案提供商可以将主要的安全方面的投入部署在统一
认证服务那端。
FreeTTS是一个语音合成库,今天进行了相关的试用。
1、下载完毕之后,构建工程,拷贝到LIB中的JAR有:en_us.jar、freetts.jar、jsapi.jar、freetts-jsapi10.jar
2、jsapi.jar因为采用的授权不同于freetts,所以需要运行jsapi.exe并同意后来获取
3、需要将speech.properties拷贝到user.home或者java.home/lib下
4、编写基于JSAPI的HelloWorld程序:
import java.util.Locale;
import javax.speech.Central;
import javax.speech.EngineList;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
public class HelloWorld {
public HelloWorld() {
}
public static void listAllVoices(String modeName) {
System.out.println("All " + modeName + " Mode JSAPI Synthesizers and Voices:");
SynthesizerModeDesc required = new SynthesizerModeDesc(null, modeName, Locale.US, null, null);
EngineList engineList = Central.availableSynthesizers(required);
for (int i = 0; i < engineList.size(); i++) {
SynthesizerModeDesc desc = (SynthesizerModeDesc) engineList.get(i);
System.out.println(" " + desc.getEngineName() + " (mode=" + desc.getModeName() + ", locale="
+ desc.getLocale() + "):");
Voice voices[] = desc.getVoices();
for (int j = 0; j < voices.length; j++)
System.out.println(" " + voices[j].getName());
}
}
public static void main(String args[]) {
// 利用 FreeTTS 读出Good job
try {
SynthesizerModeDesc desc = new SynthesizerModeDesc("FreeTTS en_US general synthesizer", "general",
Locale.US, null, null);
Synthesizer synthesizer = Central.createSynthesizer(desc);
if (synthesizer == null) {
System.exit(1);
}
synthesizer.allocate();
synthesizer.resume();
desc = (SynthesizerModeDesc) synthesizer.getEngineModeDesc();
Voice voices[] = desc.getVoices();
for (Voice v : voices) {
synthesizer.getSynthesizerProperties().setVoice(v);
synthesizer.speakPlainText("good job", null);
synthesizer.waitEngineState(0x10000L);
}
synthesizer.deallocate();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
5、编写基于FreeTTS的测试程序:
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
public class FreeTTSHelloWorld {
public FreeTTSHelloWorld() {
}
public static void listAllVoices() {
System.out.println();
System.out.println("All voices available:");
VoiceManager voiceManager = VoiceManager.getInstance();
Voice voices[] = voiceManager.getVoices();
for (int i = 0; i < voices.length; i++)
System.out.println(" " + voices[i].getName() + " (" + voices[i].getDomain() + " domain)");
}
public static void main(String args[]) {
listAllVoices();
System.out.println();
VoiceManager voiceManager = VoiceManager.getInstance();
Voice helloVoice = voiceManager.getVoice("kevin16");
if (helloVoice == null) {
System.exit(1);
}
helloVoice.allocate();
helloVoice.speak("GOOD JOB KINKDING");
helloVoice.deallocate();
System.exit(0);
}
}
1、此处有一篇比较好RSS原理介绍文章:
http://www.sunnychen.org/article.asp?id=82
2、编写相关的实现代码:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
/**
* 简单HTTP服务器
*
* @author kinkding
*/
public class MyHTTPServer implements Runnable {
ServerSocket server;
int port = 80;
public MyHTTPServer() throws IOException {
server = new ServerSocket(port);
new Thread(this).start();
System.out.println("HTTP服务器已经启动");
}
public void run() {
while (true) {
try {
Socket client = server.accept();
System.out.println("接收到客户端:" + client);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("HTTP/1.0 200 OK");
out.println("Content-Type:text/html;charset=GBK");
out.println();// HTTP协议:空行表示信息结束
this.sendRss(out);
out.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void sendRss(PrintWriter out) throws IOException {
// 按照RSS 2.0 的规则进行生成
out.println("<?xml version=\"1.0\" encoding=\"GBK\"?>");
out.println("<rss version=\"2.0\">");
out.println("<channel>");
out.println("<title>科技要闻-CT新闻</title>");
out.println("<link>http://localhost</link>");
out.println("<language>zh-cn</language>");
out.println("<description>科技要闻-CT新闻</description>");
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
out.println("<pubDate>" + formatter.format(date) + "</pubDate>");
// 封装条目
List<Message> msgs = this.queryMsgs();
for (Message m : msgs) {
out.println("<item>");
out.println("<title>" + m.name + "</title>");
out.println("<pubDate>" + formatter.format(m.time) + "</pubDate>");
out.println("<description>" + m.desc + "</description>");
out.println("<link>http://localhost/" + m.id + "</link>");
out.println("<guid>http://localhost/" + m.id + "</guid>");
out.println("</item>");
}
out.println("</channel>");
out.println("</rss>");
}
private List<Message> queryMsgs() {
List<Message> msgs = new ArrayList<Message>();
try {
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://localhost:5432/postgres";
Connection connection = DriverManager.getConnection(url, "postgres", "admin");
Statement stmt = connection.createStatement();
// 查询前5条记录进行显示
ResultSet rs = stmt.executeQuery("SELECT * FROM tbl_messages order by msg_time desc limit 5");
while (rs.next()) {
Message msg = new Message();
msg.id = rs.getInt("msg_id");
msg.name = rs.getString("msg_name");
msg.desc = rs.getString("msg_desc");
msg.time = rs.getTimestamp("msg_time");
msgs.add(msg);
}
rs.close();
stmt.close();
connection.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return msgs;
}
public static void main(String[] args) {
try {
new MyHTTPServer();
} catch (IOException e) {
e.printStackTrace();
}
}
class Message {
int id;
String name;
String desc;
Timestamp time;
}
}
3、配置postgresql,本机安装的是9.0版本,特别需要注意的是,安装目录中不能有空格。(直接exe方式安装的话,会自动生成一个服务);
同时还需要额外到官网下载相关的jdbc驱动,因我本机JAVA是1.5,所以选择的是JDBC3的驱动包:
postgresql-9.0-801.jdbc3.zip
4、编写相关的脚本:
create table tbl_messages(
msg_id integer PRIMARY KEY,
msg_name text,
msg_desc text,
msg_time timestamp
);
INSERT INTO tbl_messages (msg_id,msg_name, msg_desc, msg_time) VALUES (1, '腾讯正式起诉360不正当竞争','北京时间10月14日晚间消息,新浪科技今天在腾讯官网获悉,腾讯已于近日正式起诉360,要求奇虎及其关联公司停止侵权、公开道歉并作出赔偿。', current_timestamp);
INSERT INTO tbl_messages (msg_id,msg_name, msg_desc, msg_time) VALUES (2, '国奥“抢人“引中超多队不满',' 本届国奥队集训计划的安排,意味集训的26人将错过中超联赛的最后四轮比赛。受影响最大的大连实德俱乐部只同意杨博宇一人按时去报到,吕鹏、王选宏和赵宏略三人将在联赛结束后才能去参加集训。', current_timestamp);
INSERT INTO tbl_messages (msg_id,msg_name, msg_desc, msg_time) VALUES (3, '外交部就日朝官员访华及南海问题等答问',' 2010年10月14日,外交部发言人马朝旭主持例行记者会。', current_timestamp);
INSERT INTO tbl_messages (msg_id,msg_name, msg_desc, msg_time) VALUES (4, '智利总统称将追究矿难责任','据外电报道,智利圣何塞铜矿救援行动取得了令人感动的成功,也吸引了全世界关注的目光,不过,在救援行动完成后,圣何塞铜矿的“命运”又将何去何从?智利总统皮涅拉14日表示,该矿将永久性关闭,同时,将责成当局对相关责任人进行惩罚。', current_timestamp);
INSERT INTO tbl_messages (msg_id,msg_name, msg_desc, msg_time) VALUES (5, '鲁能只是所谓领头羊',' 本周六,上海申花就将北上长春,客场挑战长春亚泰。对于这个几个赛季都没有战胜的对手来说,本场比赛异常关键。赛前,老布对这个对手异常重视,在他看来,长春这个对手绝非一般,而对于本场比赛,老布也明确表示,自己要率领球队,赢得本场比赛的胜利,打破从未战胜过长春的尴', current_timestamp);
INSERT INTO tbl_messages (msg_id,msg_name, msg_desc, msg_time) VALUES (6, '英第二大警察局通过Twitter公布每起案件','北京时间10月14日晚间消息,据国外媒体报道,英国第二大警察局大曼彻斯特警察局周四表示,计划将所处理的每一起案件在24小时内发布到Twitter网站上。', current_timestamp);
5、运行:
在浏览器中输入
http://localhost/进行访问即可。
在javaeye上看到Nutz,挺新鲜的一个东西,下面是试用的相关记录。
1、在数据库中创建相关的表:
CREATE TABLE tbl_test_person(
ID NUMBER(10) PRIMARY KEY,
NAME VARCHAR2(100),
remark VARCHAR2(1000)
);
2、编写相关json格式数据源配置文件datasource.json:
{
dataSource : {
type : "org.apache.commons.dbcp.BasicDataSource",
events : {
depose : 'close'
},
fields : {
driverClassName : 'oracle.jdbc.driver.OracleDriver',
url : 'jdbc:oracle:thin:@10.10.5.161:1521:oradb10',
username : 'fwmstest',
password : 'fwmstest'
}
}
}
3、编写相关的POJO:
package test;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Table;
@Table("tbl_test_person")
public class Person {
@Column
private int id;
@Column
private String name;
@Column
private String remark;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String toString() {
return "id:" + id + ",name:" + name + ",remark:" + remark;
}
}
4、配置相关的引用JAR:
ORACLE的驱动包classes12.zip
APACHE的commons-dbcp-1.3.jar包(最开始直接下载的是commons-dbcp-1.4.jar,但工程环境是1.5,所以运行的时候直接报java.lang.UnsupportedClassVersionError: Bad version number in .class file)以及相关的commons-pool-1.5.5.jar
log4j-1.2.16.jar
5、编写MAIN程序:
package test;
import java.util.List;
import org.apache.commons.dbcp.BasicDataSource;
import org.nutz.dao.Dao;
import org.nutz.dao.impl.NutDao;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.impl.NutIoc;
import org.nutz.ioc.loader.json.JsonLoader;
public class MainApp {
public static void main(String[] args) {
Ioc ioc = new NutIoc(new JsonLoader("test/datasource.json"));
BasicDataSource ds = ioc.get(BasicDataSource.class, "dataSource");
Dao dao = new NutDao(ds);
// 插入10条数据
for (int i = 0; i < 10; i++) {
Person p = new Person();
p.setId(i + 1);
p.setName("good" + i);
p.setRemark("remark" + i);
dao.insert(p);
}
// 查询所有记录
List<Person> list = dao.query(Person.class, null, null);
for (Person p : list) {
System.out.println(p);
}
}
}
6、程序运行结果如下:
控制台的输出:
2010-10-14 12:59:56 WARN [main] !!You are using default SystemLog! Don't use it in Production environment!!
id:1,name:good0,remark:remark0
id:2,name:good1,remark:remark1
id:3,name:good2,remark:remark2
id:4,name:good3,remark:remark3
id:5,name:good4,remark:remark4
id:6,name:good5,remark:remark5
id:7,name:good6,remark:remark6
id:8,name:good7,remark:remark7
id:9,name:good8,remark:remark8
id:10,name:good9,remark:remark9
数据库中,执行查询语句,也对上了号。
1、编写相关的备份脚本backup.bat:
@echo off
mysqldump -uroot -pXXX test>D:\db_backup\test%date:~0,10%.sql
其中“%date:~0,10%”表示取出日期后截取前10个字符,因为在目标机器运行%date%得到的是“2010-10-13 星期三”,不符合要求。
2、执行过程中,报如下错误:
mysqldump: Got error: 1045: Access denied for user:
'root@localhost ' (Using password: NO) when trying to connect
原因是权限不够,处理措施如下:
C:\Documents and Settings\Administrator.SPARK001>mysql -uroot -pXXX
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1450
Server version: 5.0.67-community MySQL Community Edition (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'root' WITH GRANT OPTION;
Query OK, 0 rows affected (0.06 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
3、运行bat文件后,即生成了“test2010-10-13.sql”类的文件,最后通过设置WINDOWS系统工具中的任务计划功能,即可实现自动备份。
基于APACHE COMMONS中的NET包提供的FTP客户端类库实现,下面是具体的代码:
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
public class ClientTest {
public static void main(String[] args) {
ClientTest main = new ClientTest();
FTPClient ftp = new FTPClient();
// 设置一个监听
ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
try {
ftp.connect("localhost", 2121);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
System.out.println("FTP server refused connection");
}
// 登录
ftp.login("admin", "admin");
main.uploadFile(ftp);
main.listFiles(ftp);
main.downloadFile(ftp);
main.deleteFile(ftp);
main.listFiles(ftp);
// 退出
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (Exception e2) {
}
}
}
}
// 列举文件
private void listFiles(FTPClient ftp) throws IOException {
System.out.println("------------START------------");
for (FTPFile f : ftp.listFiles()) {
System.out.println(f.getName() + " " + f.getSize());
}
System.out.println("------------END------------");
}
// 上传文件
private void uploadFile(FTPClient ftp) throws IOException {
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
InputStream input = new FileInputStream("res/conf/dushu.jpg");
ftp.storeFile("dushu.jpg", input);
input.close();
}
// 下载文件
private void downloadFile(FTPClient ftp) throws IOException {
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
OutputStream output = new FileOutputStream("res/conf/dushu_down.jpg");
ftp.retrieveFile("dushu.jpg", output);
output.close();
}
// 删除文件
private void deleteFile(FTPClient ftp) throws IOException {
ftp.deleteFile("dushu.jpg");
}
}
输出如下:
220 Service ready for new user.
USER admin
331 User name okay, need password for admin.
PASS admin
230 User logged in, proceed.
TYPE I
200 Command TYPE okay.
PASV
227 Entering Passive Mode (127,0,0,1,13,12)
STOR dushu.jpg
150 File status okay; about to open data connection.
226 Transfer complete.
------------START------------
SYST
215 UNIX Type: Apache FtpServer
PASV
227 Entering Passive Mode (127,0,0,1,13,14)
LIST
150 File status okay; about to open data connection.
226 Closing data connection.
dushu.jpg 83694
------------END------------
TYPE I
200 Command TYPE okay.
PASV
227 Entering Passive Mode (127,0,0,1,13,16)
RETR dushu.jpg
150 File status okay; about to open data connection.
226 Transfer complete.
DELE dushu.jpg
250 Requested file action okay, deleted /dushu.jpg.
------------START------------
PASV
227 Entering Passive Mode (127,0,0,1,13,18)
LIST
150 File status okay; about to open data connection.
226 Closing data connection.
------------END------------
QUIT
221 Goodbye.
最后,提供一张自己拍的读书图:
直接在命令行中,使用FTP命令进行FTP的相关操作:
C:\Documents and Settings\dingjunxing>ftp
ftp> open localhost 2121
Connected to DINGJX.
220 Service ready for new user.
User (DINGJX:(none)): admin
331 User name okay, need password for admin.
Password:
230 User logged in, proceed.
ftp> dir
200 Command PORT okay.
150 File status okay; about to open data connection.
-rw------- 1 user group 67646 Oct 11 17:50 03_photos.ico
226 Closing data connection.
ftp: 收到 67 字节,用时 0.03Seconds 2.16Kbytes/sec.
ftp> ls
200 Command PORT okay.
150 File status okay; about to open data connection.
03_photos.ico
226 Closing data connection.
ftp: 收到 15 字节,用时 0.00Seconds 15000.00Kbytes/sec.
ftp> get 03_photos.ico
200 Command PORT okay.
150 File status okay; about to open data connection.
226 Transfer complete.
ftp: 收到 67680 字节,用时 0.02Seconds 4230.00Kbytes/sec.
ftp> delete 03_photos.ico
250 Requested file action okay, deleted /03_photos.ico.
ftp> put 03_photos.ico
200 Command PORT okay.
150 File status okay; about to open data connection.
226 Transfer complete.
ftp: 发送 67680 字节,用时 0.02Seconds 4230.00Kbytes/sec.
ftp> put F:\eclipse\workspace\ftpserver\res\ftpserver.jks
200 Command PORT okay.
150 File status okay; about to open data connection.
226 Transfer complete.
ftp: 发送 1242 字节,用时 0.00Seconds 1242000.00Kbytes/sec.
ftp> mkdir test
257 "/test" created.
ftp> bye
221 Goodbye.
该文为转载,原文地址:http://hi.baidu.com/xianyang1981/blog/item/f17d6f6d8650c0f842169427.html
一、ftp的port和pasv模式的工作方式
FTP使用2个TCP端口,首先是建立一个命令端口(控制端口),然后再产生一个数据端口。国内很多教科书都讲ftp使用21命令端口和20数据端口,这个应该是教书更新太慢的原因吧。实际上FTP分为主动模式和被动模式两种,ftp工作在主动模式使用tcp 21和20两个端口,而工作在被动模式会工作在大于1024随机端口。FTP最权威的参考见RFC 959,有兴趣的朋友可以仔细阅读ftp://nic.merit.edu/documents/rfc/rfc0959.txt的文档了解FTP详细工作模式和命令。目前主流的FTP Server服务器模式都是同时支持port和pasv两种方式,但是为了方便管理安全管理防火墙和设置ACL了解FTP Server的port和pasv模式是很有必要的。
1.1 ftp port模式(主动模式)
主动方式的FTP是这样的:客户端从一个任意的非特权端口N(N>1024)连接到FTP服务器的命令端口(即tcp 21端口)。紧接着客户端开始监听端口N+1,并发送FTP命令“port N+1”到FTP服务器。最后服务器会从它自己的数据端口(20)连接到客户端指定的数据端口(N+1),这样客户端就可以和ftp服务器建立数据传输通道了。ftp port模式工作流程如下图所示:
针对FTP服务器前面的防火墙来说,必须允许以下通讯才能支持主动方式FTP:
1、客户端口>1024端口到FTP服务器的21端口 (入:客户端初始化的连接 S<-C)
2、FTP服务器的21端口到客户端>1024的端口(出:服务器响应客户端的控制端口 S->C)
3、FTP服务器的20端口到客户端>1024的端口(出:服务器端初始化数据连接到客户端的数据端口 S->C)
4、客户端>1024端口到FTP服务器的20端口(入:客户端发送ACK响应到服务器的数据端口 S<-C)
1.2 ftp pasv模式(被动模式)
在被动方式FTP中,命令连接和数据连接都由客户端。当开启一个FTP连接时,客户端打开两个任意的非特权本地端口(N > 1024和N+1)。第一个端口连接服务器的21端口,但与主动方式的FTP不同,客户端不会提交PORT命令并允许服务器来回连它的数据端口,而是提交 PASV命令。这样做的结果是服务器会开启一个任意的非特权端口(P > 1024),并发送PORT P命令给客户端。然后客户端发起从本地端口N+1到服务器的端口P的连接用来传送数据。ftp pasv模式工作流程如下图所示:
对于服务器端的防火墙来说,必须允许下面的通讯才能支持被动方式的FTP:
1、客户端>1024端口到服务器的21端口 (入:客户端初始化的连接 S<-C)
2、服务器的21端口到客户端>1024的端口 (出:服务器响应到客户端的控制端口的连接 S->C)
3、客户端>1024端口到服务器的大于1024端口 (入:客户端初始化数据连接到服务器指定的任意端口 S<-C)
4、服务器的大于1024端口到远程的大于1024的端口(出:服务器发送ACK响应和数据到客户端的数据端口 S->C)