在门户项目中Q经怼遇到如何实现单点d的问题,下面本人的l验做个ȝ。欢q大家进行补充讨论?/p>
如果目对SSO的要求比较低Q又不想对要被集成的pȝ做Q何改动,可采用下面介l的方式单实玎ͼ下面我们通过一个例子来说明。假如一个门户项目要对下面的几个pȝ做SSO?/p>
用户在这些系l中的用户名Q密码各不相同,如:员工号ؓ001的员工在q些pȝ中的用户名,密码分别如下Q?/p>
用户 | pȝ | 用户?/th> | 密码 |
---|---|---|---|
001 | Portalpȝ | A | 1234 |
001 | 邮gpȝ | B | 2345 |
001 | DOMINOpȝ | C | AAAA |
001 | 报销pȝ | D | CCCC |
001 | 工资pȝ | E | BBBB |
首先Q要建立员工在PORTALpȝ中的用户名和其他pȝ中的用户名之间的对应关系q保存。可保存在表中或LDAP中或文gpȝ中。当然要考虑q些pȝ之间的数据同步问题。比较好的方式是扑ֈ用户在这些系l中的都存在的唯一信息Q如员工PMAIL地址Q姓名等Q。通过唯一信息实时到各个系l中d认证所需要的信息。就不需要考虑数据同步问题。比较实用。可以徏立类g面的表:密码可采用加密保存。如果是采用BEA的Weblogic Portal,可采用UUP来保存这些信息?/p>
( user varchar2(20), /*用户?/ app_name varchar2(20), /*应用pȝ*/ architect varchar2(4), /*应用pȝ的架构BS或CS*/ app_company varchar2(50), /*用户所属分公司*/ app_department varchar2(50), /*用户所在的部门*/ app_user varchar2(15), /*在该pȝ中的用户?/ app_passwd varchar2(15), /*在该pȝ中的密码*/ app_cookie varchar2(30), /*COOKIE名称*/ form_user varchar2(20), /*认证面中FORM的用户名字段*/ form_passwd varchar2(20), /*认证面中FORM的密码字D?/ app_special varchar2(20) /*其他*/ );
通过IFRAME或超q接方式集成目标pȝ,q在URL中带上用户名和密码。如集成DOMINO可采用如下方式:
<IFRAME src=http://host1/names.nsf?Login&Username=admin&Password=pass&RedirectTo=/names.nsf
width="100%" frameborder="0" align="middle" height="100%" hspace="0" marginheight="0" marginwidth="0" scrolling="yes" style="background-color:#f7f7ff;">
</IFRAME>
或:
Href src=?a href="http://localhost/names.nsf?Login&Username=admin&Password=password&RedirectTo=/names.nsf" target="_parent">http:// host1/names.nsf?Login&Username=admin&Password=pass&RedirectTo=/names.nsf?
以上采用的是在HTTP中直接传递明码,为提高安全性,可采用HTTPS来传递用户名和密码。另外采用这U方式被集成的系l必L持FORM方式认证。J2EE应用QDOMINO{都支持FORM认证?/p>
q两U方式如果SSO成功Q就自动q入目标pȝ的界面,如果实现会显C目标系l的d界面。其效果囑֦下:
q种方式Q必ȝ护对应关p表Q如上面的sso_info。更好的方式是提供界面,让最l用戯q护这U对应关p,可模仿Compoze portlets for lotus的做法,在用L一ơ进入要与之做SSO的系l时Q如DOMINOpȝQ显CZ个界面,让用戯p入他在该pȝ中的用户?密码{信息。ƈ保存到表中或LDAP{其他数据源中。以后用戯q入q些pȝӞq接从表中或其他数据源中取用户的用户名/密码{信息,帮助用户做认证。徏议采用这U方式。如下图所C。如果用h变了自己在DOMINOpȝ中的用户名,密码。从门户pȝq入DOMINOpȝӞ认证会失败,重新显C类g面的界面。让用户重新输入他在DOMINOpȝ中新的用户名Q密码ƈ保存?/p>
以上q种实现方式Q一般需要浏览器支持COOKIEQ所以要注意览器的配置Q在开发阶D,为方便调试,可设|IEQ让它显CCOOKIE的名U。如下所C:
采用q种方式Q对要集成的pȝ不需要做M的改动。如果PORTALpȝ中的用户在被集成的系l中的权限都一P可采用徏立一个通用用户的做法。也是所有在PORTALpȝ中的用户都采用这个通用用户q入目标pȝ。这U方式等于是采用面集成方式做集成。比较方便用。另外,有时候需要采用调用APIQ或配置Adapter{应用集成方式来集成其他pȝQ一般也是通过定义一个连接专用的用户。在API中或在配|Adapter的时候写歅R如采用JAVA API方式集成DOMINOQ?/p>
lotus.domino.Session dominoSession = NotesFactory.createSession(dominoServer, “admin? “password?;
l常有h问CSl构的应用如何实现SSOQ本人的是对q种pȝ不要自己d现SSO。很ȝQ其实输个用户名Q密码没什么大不了的。如果要实现Q一是采用商业Y件。另外也可以采用以下方式Q在PORTAL的PORTLET上徏立超q接。ƈ通过APPLET方式启动CSl构的应用系l的d界面。然后通过如下的方式把用户?密码传递过厅R?/p>
-不能做Q何改动的客户?/b> - WIN消息Q给dH口发送用户名Q密码等d所需要的信息Q?模拟键盘Qjava有模拟键盘输入的APIQ?/p>
-可以做改动的客户?/b> - 参数传递,q让d的EXE文gd参数q行认证?/p>
因ؓ要让APPLET执行本地的EXE文gQ所以必dIE中的JRE的安全进行设|?/p>
在采用以上方式实CSSO后,要注意LOGOUTQ可采用与LOGIN相同的方式。也可以通过被集成系l的时讄来实现?/p>
刚开始玩java,对其Stringc,使用有些感触;
1?abc"与new String("abc");
l常会问到的面试题:String s = new String("abc");创徏了几个String Object?【如q里创徏了多对? 和一道小的面试??BR>
q个问题比较单,涉及的知识点包括Q?BR>
引用变量与对象的区别Q?
字符串文?abc"是一个String对象Q?
文字池[pool of literal strings]和堆[heap]中的字符串对象?BR> 一、引用变量与对象Q除了一些早期的Java书籍和现在的垃圾书籍Qh们都可以从中比较清楚地学习到两者的区别。A aa;语句声明一个类A的引用变量aa[我常常称之ؓ句柄]Q而对象一般通过new创徏。所以题目中s仅仅是一个引用变量,它不是对象。[ref 句柄、引用与对象]
二、Java中所有的字符串文字[字符串常量]都是一个String的对象。有人[特别是CE序员]在一些场合喜Ƣ把字符?当作/看成"字符数组Q这也没有办法,因ؓ字符串与字符数组存在一些内在的联系。事实上Q它与字W数l是两种完全不同的对象?BR>
System.out.println("Hello".length());
char[] cc={'H','i'};
System.out.println(cc.length);
三、字W串对象的创?׃字符串对象的大量使用[它是一个对象,一般而言对象L在heap分配内存]QJava中ؓ了节省内存空间和q行旉[如比较字W串Ӟ==比equals()快]Q在~译阶段把所有的字符串文字放C个文字池[pool of literal strings]中,而运行时文字池成为常量池的一部分。文字池的好处,是该池中所有相同的字符串常量被合ƈQ只占用一个空间。我们知道,对两个引用变量,使用==判断它们的值[引用]是否相等Q即指向同一个对象:
String s1 = "abc" ;
String s2 = "abc" ;
if( s1 == s2 )
System.out.println("s1,s2 refer to the same object");
else System.out.println("trouble");
q里的输出显C,两个字符串文字保存ؓ一个对象。就是说Q上面的代码只在pool中创Z一个String对象?BR>
现在看String s = new String("abc");语句Q这?abc"本n是pool中的一个对象,而在q行时执行new String()Ӟpool中的对象复制一份放到heap中,q且把heap中的q个对象的引用交ls持有。okQ这条语句就创徏?个String对象?BR>
String s1 = new String("abc") ;
String s2 = new String("abc") ;
if( s1 == s2 ){ //不会执行的语句}
q时?=判断可知,虽然两个对象?内容"相同[equals()判断]Q但两个引用变量所持有的引用不同,
BTWQ上面的代码创徏了几个String Object? [三个Qpool中一个,heap?个。]
[Java2 认证考试学习指南 (W??( 英文?p197-199有图解。]
2、字W串?q算和字W串转换
字符串{换和串接是很基础的内容,因此我以个问题简直就是送分题。事实上Q我自己q错了?BR>
String str = new String("jf"); // jf是接?BR>str = 1+2+str+3+4;
一共创Z多少String的对象?[我开始的{案Q?个。jf、new?jf?jf3?jf34]
首先看JLS的有兌qͼ
一、字W串转换的环境[JLS 5.4 String Conversion]
字符串{换环境仅仅指使用双元?q算W的情况Q其中一个操作数是一个String对象。在q一特定情Ş下,另一操作数{换成StringQ表辑ּ的结果是q两个String的串接?BR>
二、串接运符[JLS 15.18.1 String Concatenation Operator + ]
如果一个操作数/表达式是StringcdQ则另一个操作数在运行时转换成一个String对象Qƈ两者串接。此ӞMcd都可以{换成String。[q里Q我漏掉?3"?4"]
如果是基本数据类型,则如同首先{换成其包装类对象Q如int x视ؓ转换成Integer(x)?
现在全部统一到引用类型向String的{换了。这U{换如同[as if]调用该对象的无参数toStringҎ。[如果是null则{换成"null"]。因为toStringҎ在Object中定义,故所有的c都有该ҎQ而且Boolean, Character, Integer, Long, Float, Double, and String改写了该Ҏ?
关于+是串接还是加法,由操作数军_?+2+str+3+4 很Ҏ知道?3jf34"。[BTW :在JLS?5.18.1.3中D的一个jocular little exampleQ真的很无趣。]
下面的例子测试了改写toStringҎ的情??BR>
class A{
int i = 10;
public static void main(String []args){
String str = new String("jf");
str += new A();
System.out.print(str);
}
public String toString(){
return " a.i ="+i+"\n";
}
}
三、字W串转换的优?BR>
按照上述说法Qstr = 1+2+str+3+4;语句g应该应该生?个String对象Q?BR>
1+2 Q?Qthen 3↺nteger(3)?3" in pool? [假设如此]
"3"+str(in heap) = "3jf" (in heap)
"3jf" +3 ,first 3↺nteger(3)?3" in pool? [则不创徏] then "3jf3"
"3jf3"+4 create "4" in pool
then "3jf34"
q里我ƈ不清??转换成字W串后是否在池中Q所以上q结果仍然是猜测?BR>
Z减少创徏中间q渡性的字符串对象,提高反复q行串接q算时的性能Qa Java compiler可以使用StringBuffer或者类似的技术,或者把转换与串接合q成一步。例如:对于 a + b + c QJava~译器就可以它视ؓ[as if]
new StringBuffer().append(a).append(b).append(c).toString();
注意Q对于基本类型和引用cdQ在append(a)q程中仍然要先将参数转换Q从q个观点看,str = 1+2+str+3+4;创徏的字W串可能?3"?4"?3jf34"[以及一个StringBuffer对象]?BR>
现在我仍然不知道怎么回答str = 1+2+str+3+4;创徏了多String的对象,。或许,q个问题不需要过于研IӞ臛_SCJP不会考它?BR>
3、这又不同:str = "3"+"jf"+"3"+"4";
如果是一个完全由字符串文字组成的表达式,则在~译Ӟ已经被优化而不会在q行时创Z间字W串。测试代码如下:
String str1 ="3jf34";
String str2 ="3"+"jf"+"3"+"4";
if(str1 == str2) {
System.out.println("str1 == str2");
}else {
System.out.println("think again");
}
if(str2.equals(str1))
System.out.println("yet str2.equals(str1)");
可见Qstr1与str2指向同一个对象,q个对象在pool中。所有遵循Java Language Spec的编译器都必d~译时对constant expressions q行化。JLS规定QStrings computed by constant expressions (ý15.28) are computed at compile time and then treated as if they were literals.
对于String str2 ="3"+"jf"+"3"+"4";我们说仅仅创Z个对象。注意,“创建多对象”的讨论是说q行时创建多对象?BR>
BTWQ编译时优化
String x = "aaa " + "bbb ";
if (false) {
x = x + "ccc ";
}
x += "ddd ";
{h于:
String x = "aaa bbb ";
x = x + "ddd ";
4、不变类
String对象是不可改变的(immutable)。有人对str = 1+2+str+3+4;语句提出疑问,怎么str的内容可以改变?其实仍然是因Z清楚Q引用变量与对象的区别。str仅仅是引用变量,它的值——它持有的引用可以改变。你不停地创建新对象Q我׃断地改变指向。[参考TIJ的Read-only classes。]
不变cȝ关键是,对于对象的所有操作都不可能改变原来的对象[只要需要,p回一个改变了的新对象]。这׃证了对象不可改变。ؓ什么要一个类设计成不变类Q有一个OOD设计的原则:Law of Demeter。其q义解读是:
使用不变cR只要有可能Q类应当设计Z变类?BR>
1、tomcat下配|虚拟目?BR>
打开TOMCAT文g下的conf\server.xml文g Q查扑ֈ<ContextManager>标签Qƈ在该标签的结束标{?lt;/ContextManager>前面加上Q?BR>
<Context path="虚拟目录" docBase="盘目录" debug="0" reloadable="true" crossContext="true"/>
其中path的值是虚拟目录Qdocbase的值是你的盘的的目录的绝对\径?/STRONG>
如找不到<ContextManager>元素Q可以找
<Host name="localhost" debug="0" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
然后d<Context path="虚拟目录" docBase="盘目录" debug="0" reloadable="true" crossContext="true"/>
2、禁止tomcat目录览,listings设ؓfalse
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>
org.apache.catalina.servlets.DefaultServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
3、设|友好错误页面,配置web.xml
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
4、在IE中直接打开其他扩展名的文g
Z让能在IE览器中自动打开其他扩展文g名的文g的设|:
需要在WEB.XML中进行如下的讄Q?BR> 在WEB.XML中添?lt;mime-mapping>,其中:
<extension>: 文g的扩展名
<mime-type>: 除了该类型文件的可执行文?同WINDOW注册表中?nbsp; /HKEY_CLASSES_ROOT下该cL件的Content Type 的g?
如能在IE中自动打开DOCQXLSQPDF文g的配|如?
<?xml version="1.0" ?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 1.2//EN" "<web-app>
<mime-mapping>
<extension>doc</extension>
<mime-type>application/msword</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/msexcel</mime-type>
</mime-mapping>
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
</web-app>