Tuesday, January 25, 2011
java.lang.ClassNotFoundException: weblogic.logging.commons.LogFactoryImpl
Check the class folder under APP-INF to see if there is a file commons-logging.properties and in the file there is an entry org.apache.commons.logging.LogFactory = weblogic.logging.commons.LogFactoryImpl
Remove the file and it will be done.
Wednesday, July 28, 2010
web service over https
Home My How-To's Recently Read
RSS subscribe by rss
Calling a secure Axis web service via SSL, through a proxy
February 5th, 2008 by lukas
In a recent project one of the requirements was to implement an Axis client for a web service with the following additional configuration:
1. Web service traffic must go through a proxy
2. Basic authentication turned on – login & password required
3. Communication is over HTTPS with a self-signed SSL certificate
Although not overly difficult for somebody experienced in creating Apache Axis clients the implementation for the above is not trivial. This is mainly due to SSL’s complexity but also because the configurations to get the above working are required in slightly different places of the Axis client framework.
I hope the below may help someone through some of the steps required.
1. Routing web service calls through a proxy
We need to take care of this one first. If there is a proxy between the client and the server and the client doesn’t know to route the traffic through it the requests won’t even reach the server and will just time out. (If your web browser uses a proxy then your local web service will as well since we are using SOAP over HTTP. You can most likely use the same proxy for the settings for the web service).
Without a proxy configured the connection just times out:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.net.ConnectException: Connection timed out: connect
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
...
Telling Axis to use a proxy is easy. We use Axis properties to set both the proxy host and the port:
private void configureProxy()
{
//this setting (from a config file) controls whether the proxy is to be used or not
if (ApplicationProperties.useProxy())
{
AxisProperties.setProperty("https.proxyHost", "192.168.15.1");
AxisProperties.setProperty("https.proxyPort", "8080");
}
}
2. Basic Authentication
Once Axis knows to use a proxy we can actually reach the server. But calling a web service that requires HTTP basic-auth without the proper credentials will fail. Basic authentication includes a base64 encoded login and password set in the http header of the message. Without these details in the header we will get an error similar to this:
AxisFault
faultCode: {http://xml.apache.org/axis/}HTTP
faultSubcode:
faultString: (401)Authorization Required
faultActor:
faultNode:
faultDetail:
{}:return code: 401
Authorization Required
This server could not verify that you
are authorized to access the document
requested. Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.
{http://xml.apache.org/axis/}HttpErrorCode:401
(401)Authorization Required
at org.apache.axis.transport.http.HTTPSender.readFromSocket(HTTPSender.java:744)
at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:144)
...
Taking care of this is also quite easy as the generated Axis client stub (if you’re using a standard JAX-RPC web service) provides methods to set the user login and password for basic authentication. (Naturally, you need to know what these are to be able to connect)
private void configureBasicAuth() throws ServiceException
{
//the port is the interface for the web service
this.configuredPort = ((MyWebServiceLocator)getService()).getMyWebServicePort();
MyWebServiceBindingStub myStub = (MyWebServiceBindingStub)configuredPort;
myStub.setUsername("userName");
myStub.setPassword("password");
}
3. Communicating over HTTPS with a self-signed SSL certificate
Now that we’re authenticated our web service request makes it through but the SSL connection cannot be established since we’re not providing the correct certificate. In my instance the server requires an unsigned (or self-signed) SSL certificate.
If we don’t provide one the request will bounce with the following error:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
...
Implementing SSL using certificates is a bit more tricky. It requires creating a custom SSLSocketFactory which uses the correct SSL certificate and setting this factory as the one to be used by Axis. The certificate is packaged into a custom keystore which is packaged and released with the client application. The steps required to implement this are:
1. obtain the certificate to be used on the client-side
2. create a custom keystore to store the above certificate
3. create code for the custom ssl socket factory by extending org.apache.axis.components.net.JSSESocketFactory (reads the custom keystore)
4. configure the new custom factory to be used by Axis
To create the custom factory we first need to create a custom keystore which will hold our self-signed certificate. The “Using Self-Signed Certificates for Web Service Security” article explains nicely how this is done.
(The certificate you receive could be a .crt. The keytool utility may throw a tantrum at this as it expects a .cer file. To convert to this Base-64 encoded X.509 certificate, double-click your original .crt file -> Details -> Copy to File and follow the prompts. Save the resulting certificate as a file with a .cer extension and keytool should now be happy)
I used the following command to create my CustomKeystore.jks:
keytool -import -noprompt -trustcacerts -alias CustomKeystoreAlias -file CERTIFICATE.cer -keystore CustomKeystore.jks -storepass customKeystorePassword
(NOTE: for some reason I could not copy the command into the CommandPrompt window and had to type it out)
Once the keystore is created, we include it in the client application – somewhere on the classpath. The next step is to code the custom SSLSocketFactory:
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Hashtable;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.axis.components.net.JSSESocketFactory;
import org.apache.axis.components.net.SecureSocketFactory;
import org.apache.commons.lang.StringUtils;
/**
* Custom SSL socket factory to use our integrated keystore.
*
* Based loosely on org.apache.axis.components.net.SunJSSESocketFactory
*/
public class MyCustomSSLSocketFactory extends JSSESocketFactory implements SecureSocketFactory {
/* local keystore password */
private static String MY_KEYSTORE_PASSWORD = "customKeystorePassword";
/* local keystore file (contains the self-signed certificate from the server */
private static String RESOURCE_PATH_TO_KEYSTORE = "CustomKeystore.jks";
/**
* Constructor MyCustomSSLSocketFactory
*
* @param attributes
*/
public MyCustomSSLSocketFactory(Hashtable attributes) {
super(attributes);
}
/**
* Read the keystore, init the SSL socket factory
*
* This overrides the parent class to provide our SocketFactory implementation.
* @throws IOException
*/
protected void initFactory() throws IOException {
try {
SSLContext context = getContext();
sslFactory = context.getSocketFactory();
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
}
throw new IOException(e.getMessage());
}
}
/**
* Gets a custom SSL Context.
* This is the main working of this class. The following are the steps that make up our
* custom configuration:
*
* 1. Open our keystore file using the password provided
* 2. Create a KeyManagerFactory and TrustManagerFactory using this file
* 3. Initialise a SSLContext using these factories
*
* @return SSLContext
* @throws WebServiceClientConfigException
* @throws Exception
*/
protected SSLContext getContext() throws WebServiceClientConfigException {
char[] keystorepass = MY_KEYSTORE_PASSWORD.toCharArray();
if (StringUtils.isBlank(new String(keystorepass)))
throw new WebServiceClientConfigException("Could not read password for configured keystore!");
InputStream keystoreFile = this.getClass().getResourceAsStream(RESOURCE_PATH_TO_KEYSTORE);
if (keystoreFile == null)
throw new WebServiceClientConfigException("Could not read the configured keystore file at "+RESOURCE_PATH_TO_KEYSTORE);
try
{
// create required keystores and their corresponding manager objects
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(keystoreFile, keystorepass);
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keystorepass);
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// congifure a local SSLContext to use created keystores
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}
catch (Exception e)
{
throw new WebServiceClientConfigException("Error creating context for SSLSocket!", e);
}
}
}
The last step required is to tell Axis to use the above MyCustomSSLSocketFactory as the default ssl socket factory. This is again achieved by setting AxisProperties:
private void configureSSL()
{
//this is configurable so that it can be switched off in development mode
if (Configuration.useSSL())
{
//use our custom SSLSocketFactory
AxisProperties.setProperty("axis.socketSecureFactory","com.company.application.util.MyCustomSSLSocketFactory");
}
else
{
// The fake factory must not be used in production environment because it ignores any certificates but
// it is convenient to have for testing purposes.
AxisProperties.setProperty("axis.socketSecureFactory","org.apache.axis.components.net.SunFakeTrustSocketFactory");
log.debug("WARNING: SSL CERTIFICATE CONFIGURATION IS TURNED OFF!");
}
}
In the code above we have the option of either using our new fully configured MyCustomSSLSocketFactory or the provided SunFakeTrustSocketFactory. The latter is very useful for testing and will accept any ssl certificate. It is mentioned on the Axis wiki here.
This should be it. Communication should now flow freely between client and server in a reasonably secure manner.
Feel free to post comments.
Posted in programming | 26 Comments »
26 Responses
1. Abhay Singh Says:
February 9th, 2008 at 4:43 am
Hi there,
The article by you was excellent.
I was struggling to configure my axis client for https, but with your article i could successfully do that.
Thanks a ton.
Cheers
Abhay
2. dheer Says:
February 19th, 2008 at 7:31 pm
Thank you it helped me a lot to get an idea. Now I still get this exception
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
Could you please tell what else config i am missing Thank You
3. lukas Says:
February 20th, 2008 at 6:18 am
dheer:
Make sure that you are actually contacting the web service via https. Your web service url must start with “https://” and if you’re using a proxy then make sure that you’re setting the https.proxyHost and https.proxyPort. Also, double check that the server you’re trying to connect to has actually https setup.
4. marcel Says:
April 9th, 2008 at 8:59 pm
thanks a lot for this brilliant article. you helped me a great deal to finish my stuff. a lot of black magic is going on with all this SSL stuff :-)
great
marcel
5. vin Says:
May 13th, 2008 at 5:41 am
Great article. wonderful to find all the three niggling issues covered in the same article!
6. Julie Says:
July 31st, 2008 at 10:17 am
At what point do you call configureSSL()? Is there a workflow to this? Do I have to set the AxisProperties prior to obtaining a connection to the web service?
7. lukas Says:
August 1st, 2008 at 5:19 am
Julie: The above methods are all static methods that can be called once you have a client proxy. Each of the config steps must be executed BEFORE you establish the connection as once you do that you cannot easily dynamically change connection properties.
8. Julie Says:
August 1st, 2008 at 6:19 am
I don’t think this works with Axis2. Just setting the AxisProperties did nothint – i.e. at no point was my custom SSLSocketFactory getting instantiated. Axis2 uses apache.commons.HttpClient at its http transport layer, so this way is looking more promising… http://hc.apache.org/httpclient-3.x/sslguide.html
(although, I haven’t gotten it to work yet, either).
9. SivaKannan Says:
October 14th, 2008 at 11:29 am
This actual is a great post!! I was able to talk to a WS expecting Client Auth.
I have a question. I want to pass the cert/password location to the MyCustomSSLSocketFactory(in your case). How can I do that?
10. Vince Says:
March 6th, 2009 at 3:55 am
Hi,
i have a Web Application that calls two Web Services.
The two Web Services can be reach via two different proxies. Meaning WS #1 can be reached via proxy #1 (and only this one) and WS #2 can be reached via proxy #2 (and only this one).
The two calls are not synchronised and can be done at the same time. So in my case, i would like a thread safe solution.
my question is : do you have any idea how can I specify two different proxies for calling WS with axis 1.1 ?
Thanks.
11. lukas Says:
March 17th, 2009 at 9:38 am
Vince: this is an interesting problem that may not be easily solved with Axis 1.1. Without knowing the details I can suggest maybe to create 2 separate client projects (separately deployed jar files) each with its own Axis client implementation. You’d dispatch messages to either one or the other depending on service call required. This is more in the realm of enterprise messaging now and would potentially benefit from a lightweight JMS or even ESB implementation.
12. Sam Says:
March 17th, 2009 at 10:38 pm
Hello.
Your article is very interesting, still i have a few question to set.
My webservices are in PHP, and the client is in Java(using Axis).
I configured Apache(server) to use SSL using a self generated certificate, then imported the certificate to create the CustomKeystore just like you adviced.
When i tested the client i got:
“javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target”.
So, after a bit of reading, i imported the certificate into the cacerts file used by the JRE in use.
Now the client can connect and it responds, even if i provide a bad MY_KEYSTORE_PASSWORD or PATH to the keystore in the MyCustomSSLSocketFactory.
Does the client still look to the MyCustomSSLSocketFactory anymore ?
Is there anyway to overpass the problems caused by the self generated certificate ?
Thank you.
13. Juanqui Says:
March 18th, 2009 at 12:38 am
Hi Lukas, a great article !
I have to connect an axis client web service with SSL but with mutual authentication, I have the the certificate from a URL in a cacerts and everything works fine, but when I need to send my credentials I don’t know how to do it.
I need to send my certificate that is in the cacerts too but I don´t find how to choose my alias and how to connect, and then call a method. Any ideas ?
14. Suresh Says:
March 19th, 2009 at 7:30 am
Thanks a lot Lukas for your article.
Great work dude!!
15. Juanqui Says:
March 27th, 2009 at 6:23 am
I could do the mutual authentication, but now I have the following problem. I have some axis clients that use one way authentication and others use two ways authentication.
For work with two ways authentication I need to set the axis properties:
AxisProperties.setProperty(“axis.socketSecureFactory”,”com.mycompany.MySSLSocketFactory”);
Setting this property produce that the two way authentication works fine but the one way authentication don’t work.
Any ideas ? Thanks, Juan.
16. Juanqui Says:
March 31st, 2009 at 8:32 am
If you want to work with “3. Communicating over HTTPS with a self-signed SSL certificate”, one way or two ways, don’t create the class that inherit from JSSESocketCustomFactory, I repeat you don`t need to do “3. create code for the custom ssl socket factory by extending org.apache.axis.components.net.JSSESocketFactory (reads the custom keystore)” and “4 configure the new custom factory to be used by Axis”, you only need to set this six properties:
javax.net.ssl.trustStore="your path to cacerts"
javax.net.ssl.trustStorePassword=yourpassword
javax.net.ssl.trustStoreType=JKS or the type you use in your certs
javax.net.ssl.keyStore="your path to cacerts"
javax.net.ssl.keyStorePassword=yourpassword
javax.net.ssl.keyStoreType=JKS or the type you use in your certs
Another things is that all your certs in cacerts should have the same password for work with axis 1.4
17. Juanqui Says:
March 31st, 2009 at 8:36 am
And you don’t should set the axis properties:
AxisProperties.setProperty(“axis.socketSecureFactory”,”com.mycompany.MySSLSocketFactory”);
and everything works fine.
The solution for Lucas work great if you want to work with one or two ways but not both at the same time.
18. Anatoliy Says:
April 29th, 2009 at 7:02 am
Using multiple configuration at the same time should be possible. You can define a property file that maps the destination host and port to your specific SSL attributes and initialise those up front. Here is a detailed example:
package com.my.pack;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.Hashtable;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.servlet.ServletContextEvent;
import org.apache.axis.AxisProperties;
import org.apache.axis.components.net.JSSESocketFactory;
import org.apache.axis.components.net.SecureSocketFactory;
import org.apache.axis.components.net.BooleanHolder;
/**
* This class provides a workaround for Axis 1.x limitation of using custom socket factories dynamically.
* It caches a custom created Map of SSLSocketFactory objects on startup and later uses this cache rather
* then the default Axis factory.
*/
public class MyCustomSSLSocketFactory extends JSSESocketFactory implements SecureSocketFactory, javax.servlet.ServletContextListener
{
public static final String DEFAULT_SSL_CONTEXT_TYPE = "SSLv3";
private static HashMap factories = null;
/**
* Initialize your custom factory here. Make sure that is defined in right web.xml,
* so it picked up by the right classloader.
*/
public void contextInitialized(ServletContextEvent sce)
{
AxisProperties.setProperty("axis.socketSecureFactory", "com.my.pack.MyCustomSSLSocketFactory");
loadFactories();
}
public void contextDestroyed(ServletContextEvent sce) {}
public MyCustomSSLSocketFactory(Hashtable attributes)
{
super(attributes);
}
/**
* A dummy init to mask the JSSESocketFactory.initFactory();
*/
protected void initFactory() throws IOException
{
}
/**
* This method loads the Map of custom SSL Socket Factories.
*/
public synchronized void loadFactories()
{
if(factories==null)
{
while(//reading thru your property file that maps "host:port"
//to SSL attributes like trust/key store, etc.
)
{
factories.put(host+port, getSocketFactory(trust_store,
trust_store_type,
trust_store_password,
ident_store,
ident_store_type,
ident_store_password,
ident_private_key_password)
)
);
}
}
}
/**
* This method uses a custom SSLSocketFactory, before letting the super.create(...) to continue.
* The "sslFactory" is an instance variablee of the JSSESocketFactory, and is initialized in its create(...) method
* unless already beed existent. Here it will always be overriden every time new socket is created.
*/
public Socket create(String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL) throws Exception
{
if(port 0)
{
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(identStoreType);
ks.load(getFileStream(identStore), identStorePassword.toCharArray());
kmf.init(ks, identPrivateKeyPassword.toCharArray());
kmArr = kmf.getKeyManagers();
}
ctx.init(kmArr, tmArr, new SecureRandom());
factory = ctx.getSocketFactory();
return factory;
}
/**
* Read resource file
*/
private static InputStream getFileStream(String file)
{
InputStream fis = null;
try
{
try{fis = new FileInputStream(file);}catch(Exception e){;}
if(fis==null)
{
System.out.println("File ["+file+"] not found. Will attempt load from classpath...");
URL url = ClassLoader.getSystemClassLoader().getResource(file);
if (url == null)
url = MyCustomSSLSocketFactory.class.getResource("/" + file);
fis = url.openStream();
}
}
catch(IOException e)
{
System.out.println("Unable to load file ["+file+"]");
e.printStackTrace();
}
return fis;
}
}
19. Anatoliy Says:
April 29th, 2009 at 7:13 am
That didn’t post very well. I need to find some other place to put the code.
20. Peter Says:
June 15th, 2009 at 12:00 pm
I find HTTP4E very useful for making AXIS Service calls. It is an awesome Eclipse plugin. It has tabs, syntax coloring, auto suggest, code generation, REST HTTP call replay, etc.. It does a great job of HTTP debugging, HTTP tampering, hacking.
http://http4e.roussev.org/
21. buddha Says:
July 16th, 2009 at 4:23 am
Can you please change the webpage color style . Its hard to read the code , with these colors.
22. venky Says:
September 25th, 2009 at 4:24 pm
i have 3 services runs on the same instance. two runs in the same LAN and one is external. so how can i control switching ? i am getting issues if one works other fails. i am setting as System.setproperty for proxy one.can u help me regarding this ?
SoapBindingStub stub = new SoapBindingStub(new URL(service.getSoapAddress()), service);
System.setProperty(“http.proxyHost”, “hostname”);
System.setProperty(“http.proxyPort”, “3128″);
23. wolf Says:
December 10th, 2009 at 3:28 am
I really like this solution. As I understand it, it allows to provide special key stores for many axis clients in one installation.
Unfortunately it is build on axis1.4. I use axis2 1.5.x and the complete package org.apache.axis.components.net does not exist.
Has anyone ported this to axis2?
Thanks a lot
Wolf
24. Guest Says:
May 10th, 2010 at 3:16 pm
I am getting ” faultString: (401)Authorization Required” exception when i am making the JAR.
If i run application without making the JAR, then this exception is not thrown …
25. Guest Says:
May 10th, 2010 at 5:32 pm
I am getting ” faultString: (401)Authorization Required” exception when i am making the JAR.
If i run application without making the JAR, then this exception is not thrown
26. BrendaHerring21 Says:
July 25th, 2010 at 4:10 am
Wednesday, April 21, 2010
浅谈Spring入门
Spring入门—反射技术
无参数的
Java代码
- Class.forName(className).newInstance;
- //有参数的
- Class.forName(className).getDeclaredConstructor(String.class).newInstance(“黎明”);
- //通过反射获取属性
- Introspector.getBeanInfo(Person.class).getPropertyDescriptors()
- //通过反射机制修改bean属性的值
- Person person=(Person)Class.forName(className).getDeclaredConstructor(String.class).newInstance("黎明");
- PropertyDescriptor[] ps = Introspector.getBeanInfo(Person.class).getPropertyDescriptors();
- for(PropertyDescriptor p :ps){
- System.out.println(p.getName());
- if(p.getName().equals("name")){
- Method setter=p.getWriteMethod();
- if(setter!=null){
- setter.setAccessible(true);//允许访问private属性
- setter.invoke(person, "小燕子");
- //通过反射机制修改bean字段的值
- Field field=Person.class.getDeclaredField("name");
- field.setAccessible(true);//允许访问private字段
- field.set( person , "sss");
Spring提供了声明式的事务管理
软件的解耦合,不是硬编码
Spring 需要的jar
Dist\spring.jar
lib\jakarta-commons\commons-logging.jar
如果使用了切面编程(AOP),还需要下列jar文件
- lib/aspectj/aspectjweaver.jar和aspectjrt.jar
- lib/cglib/cglib-nodep-2.1_3.jar
如果使用了JSR-250中的注解,如@Resource/@PostConstruct/@PreDestroy,还需要下列jar文件
lib\j2ee\common-annotations.jar
配置文件beans.xml
Java代码
- xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
- <bean id="xx" class="junit.test.Person" lazy-init="true">
- bean>
- beans>
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person s = (Person)context.getBean("xx");
默认bean是容器启动时实例化,只在容器中创建一次,spring中的对象一直存在容器中,是单例模式
表 3.4. Bean作用域
作用域 描述
singleton 在每个Spring IoC容器中一个bean定义对应一个对象实例。
prototype 一个bean定义对应多个对象实例。
request 在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。
session 在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global session 在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。
Spring入门—利用工厂方法创建bean
Java代码- public class PersonFactory {
- public static Person createPerson(){
- return new Person();
- }
- public Person createPerson2(){
- return new Person();
- }
- }
- //使用静态工厂方法实例化
- <bean id="person" class="bean.PersonFactory" factory-method="createPerson">bean>
- 使用实例工厂方法实例化
- <bean id="personFactory" class="bean.PersonFactory">bean>
- <bean id="person2" factory-bean="personFactory" factory-method="createPerson2">bean>
Spring入门—依赖注入
Java代码
- public class Person {
- private Integer id;
- private String name="aa";
- private IDCard idcard;
- public IDCard getIdcard() {
- return idcard;
- }
- public void setIdcard(IDCard idcard) {
- this.idcard = idcard;
- }
- public Person(String name) {
- this.name = name;
- }
- public Person() {
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- public class IDCard {
- private String no;
- public String getNo() {
- return no;
- }
- public void setNo(String no) {
- this.no = no;
- }
- }
Java代码
- <bean id="xx" class="junit.test.Person" lazy-init="true">
- <property name="idcard">
- <bean class="junit.test.IDCard">
- <property name="no" value="9999">property>
- bean>
- property>
- bean>
第二种方法
Java代码- <bean id="aa" class="junit.test.IDCard">
- <property name="no" value="88888888">property>
- bean>
- <bean id="xx" class="junit.test.Person" lazy-init="true">
- <property name="idcard" ref="aa">
- property>
- bean>
为属性配置null值
Java代码- <property name="name"><null/>property>
- public class Person {
- private String name="ss";
- public Person(){}
- public Person(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public void say(){
- System.out.println("我说了");
- }
- }
- <bean id="xxx" class="bean.Person" scope="singleton" lazy-init="false" init-method="say">
集合依赖注入
Java代码
- <property name="lists">
- <list>
- <value>1111value>
- <value>2222value>
- <value>3333value>
- <value>4444value>
- list>
- property>
- for(String s : p.getLists){
- System.out.println(s);
- }
- <property name="sets">
- <set>
- <value>TTTvalue>
- <value>YYYvalue>
- set>
- property>
- for(String s : p.getSets){
- System.out.println(s);
- }
- <property name="maps">
- <map>
- <entry key="key1" value="value1">entry>
- <entry key="key2" value="value2">entry>
- map>
- property>
- for(String key : p.getMaps().keySet()){
- System.out.println(key+"="+ p. getMaps ().get(key));
- }
- Properties 是注入
- <property name="propers">
- <props>
- <prop key="proper1">value1prop>
- <prop key="proper2">value2prop>
- props>
- property>
- for(Object key : p.getPropers().keySet()){
- System.out.println(key+"="+ p.getPropers().get(key));
- }
Thursday, February 11, 2010
保护继承与私有继承
#include "iostream"
using namespace std;
class Animal
{
public:
Animal(){}
void eat(){cout<<"eat\n";}
};
class Giraffe:protected Animal
{
public:
Giraffe(){}
void StretchNeck(double){
cout<<"stretch neck \n";
}
};
class Cat:public Animal
{
public:
Cat(){}
void Meaw(){
cout<<"meaw\n";
}
};
void Func(Animal& an)
{
an.eat();
}
int main()
{
Cat dao;
Giraffe gir;
Func(dao);
//Func(gir); //error
}
函数Func()要用一个Animal类型的对象, 但调用Func(dao)实际上传递的是Cat类的对象。因为Cat是公共继承Animal类, 所以Cat类对象拥有Animal的所有成员的使用。Animal 对象可以做的事,Cat对象也可以做。 但是,对于gir对象就不一样。Giraffe类私有继承了Animal类,意味着对象gir不能直接访问Animal类的成员。其实,在gir对象空间中,包含有Animal类的对象,只是无法让其公开访问。 公有继承就像是三口之家的小孩,饱受父母的温暖,享有父母的一切(public和protected的成员)。 其中保护的成员不能被外界所享有,但可以为小孩所拥有。 只是父母还是有其一点点隐私(private成员)不能为小孩所知道。 私有继承就像是离家出走的小孩,一个人在外面飘泊。他(她)不能拥有父母的住房和财产(如:gir.eat()是非法的), 在外面自然也就不能代表其父母,甚至他(她)不算是其父母的小孩。但是在他(她)的身体中,流淌着父母的血液,所以,在小孩自己的行为中又有其与父母相似 的成分。 例如,下面的代码中,Giraffe继承了Animal类,Giraffe的成员函数可以访问像Animal对象那样访问其Animal成员:
#include "iostream"
using namespace std;
class Animal2
{
public:
Animal2(){}
void eat(){ cout <<"eat.\n"; }
};
class Giraffe :private Animal2
{
public:
Giraffe(){}
void StretchNeck(){ cout <<"stretch neck.\n"; }
void take(){ eat(); } //ok
};
void Func(Giraffe & an)
{
an.take();
}
int main()
{
Giraffe gir;
gir.StretchNeck();
Func(gir); //ok
}
运行结果为:
stretch neck.
eat.
上例中,gir对象就好比是小孩。eat()成员函数是其父母的行为,take()成员函数是小孩的行为,在该行为中,渗透着父母的行为。但是小孩无法直接使用eat()成员函数,因为,离家出走的他(她)无法拥有其父母的权力。
保护继承与私有继承类似,继承之后的类相对于基类来说是独立的;保护继承的类对象,在公开场合同样不能使用基类的成员:
#include "iostream"
using namespace std;
class Animal3
{
public:
Animal3(){}
void eat(){cout<<"eat\n";}
};
class Giraffe:protected Animal3
{
public:
Giraffe(){}
void StretchNeck(){cout<<"stretchneck\n";}
void take()
{
eat(); //ok
}
};
int main()
{
Giraffe gir;
//gir.eat(); //error
gir.take(); //ok
gir.StretchNeck();
}
派生类的三种继承方式小结:
公有继承(public)、 私有继承(private)和保护继承(protected)是常用的三种继承方式。
1.对于公有继承方式:
·基类成员对其对象的可见性: 与一般类及其对象的可见性相同,公有成员可见,其他成员不可见。这里保护成员与私有成员相同。
·基类成员对派生类的可见性: 对派生类来说,基类的公有成员和保护成员可见:基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态;基类的私有成员不可见:基类的私有成员仍然是私有的,派生类不可访问基类中的私有成员。
·基类成员对派生类对象的可见性: 对派生类对象来说,基类的公有成员是可见的,其他成员是不可见。
所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。
2.对于私有继承方式:
·基类成员对其对象的可见性:与一般类及其对象的可见性相同,公有成员可见,其他成员不可见。
·基类成员对派生类的可见性:对派生类来说,基类的公有成员和保护成员是可见的:基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问;基类的私有成员是不可见的:派生类不可访问基类中的私有成员。
·基类成员对派生类对象的可见性:对派生类对象来说,基类的所有成员都是不可见的。
所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。
3.对于保护继承方式:
这种继承方式与私有继承方式的情况相同。两者的区别仅在于对派生类的成员而言,
·基类成员对其对象的可见性: 与一般类及其对象的可见性相同,公有成员可见,其他成员不可见。
·基类成员对派生类的可见性: 对派生类来说,基类的公有成员和保护成员是可见的; 基类的公有成员和保护成员都作为派生类的保护成员,并且可以被这个派生类的子类所继承和访问;基类的私有成员是不可见的:派生类不可访问基类中的私有成员。
·基类成员对派生类对象的可见性: 对派生类对象来说,基类的所有成员都是不可见的。
所以,在保护继承时,基类的成员可以由直接派生类访问,也可以再往下继承。
Thursday, January 28, 2010
Eclipse: JVM Terminated. Exit Code=-1 SOLUTION
add a new line if you don't have one
-launcher.XXMaxPermSize
Done.
Notes: someone says add a line
-XX:MaxPermSize=256M
I tried but it didn't work. Maybe it is for the different version.