I consume a web service in spring and get values. To do that I use GenericHandler Class to set headers for web service XML, to fill up credentials and other links in the XML I use property file and load them. However, I am not able to load values into the variables. Here are my code,
#Component
Class WSAuthentication extends GenericHandler
{
#Value("${webservice.consumerId}")
private String consumerIdString;
#Override
public QName[] getHeaders()
{
return null;
}
public boolean handleRequest(MessageContext context)
{
.... // SOAP Message context codes
System.out.println(consumerIdString);
// the above line Prints null
}
}
Web Service Handler class as follows:
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.HandlerRegistry;
import javax.xml.rpc.ServiceException;
public class WSHandler
{
public StubClass addHandlerToGetInfo()
{
....// Web Service stub codes
HandlerRegistry handlerRegistryObject = locatorStubObject.getHandlerRegistry();
List chain = handlerRegistryObject.getHandlerChain((QName)locatorStubObject.getPorts().next());
HandlerInfo handlerInfoObject = new HandlerInfo();
handlerInfoObject.setHandlerClass(WSAuthentication.class);
chain.add(handlerInfoObject);
return stubObject;
}
}
In another class I use this web service to get the code, I invoke this code in a method annotated as #PostProcess of another bean,
....// Consuming code goes here
WSHandler wsHandlerObj = new WSHandler();
StubClass stubObj = wsHandlerObj.addHandlerToGetInfo();
// Invoking WS Stub methods to get values
WSResponseClass responseObj = stubObj.getProfile(id);
Here I am not able to get consumerIdString object from properties, on the other hand I am able to hard code the value in the WSAuthentication class and it goes good when I try executing that way. Loading from property file gives a null object when I tried to access that member variable.
My questions:
Will an instance of class WSAuthentication be created by
HandlerInfo? Or How does it access the WSAuthentication class?
Does the HandlerInfo gets the web service header
through Class instance of WSAuthentication?
Is there any other way
to do this?
Or shall I use reflection to initialize the member variables of the class?
Please help me out, Thank you!
According to Spring Reference Manual, appendix E on XML Schema-based configuration,
<util:properties id="env" location="classpath:application.properties">
is a shortcut for :
<!-- creates a java.util.Properties instance with values loaded from supplied location -->
<bean id="env" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:application.properties"/>
</bean>
That means that those properties should be accessed via their containing bean.
I think that what you want to achieve is using a PropertyPlaceholderConfigurer, which should be declared as :
<context:property-placeholder location="classpath:/application.properties"/>
shortcut for :
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:/application.properties"/>
</bean>
Because here properties are directly available to configure other beans.
You are setting WSAuthentication as Handler as follows:
handlerInfoObject.setHandlerClass(WSAuthentication.class);
I think it is taking it as a plain bean instead of getting from Spring ApplicationContext, and hence no value is set for #Value annotated property.
Just to confirm inject any other Spring bean and see its value. If it is null means the instance for WSAuthentication is being created using Reflection instead of using Spring.
Related
I have a properties file under /src/main/resources/ and I want to load data from it using Spring.
In my Spring-context.xml I have this :
<context:property-placeholder location="classpath:UserUtil.properties" />
and also have <context:component-scan base-package="com.myApp" />
and in my class I load it like :
#Value("${injectMeThis}")
private String injectMeThis;
but the value is always null
EDIT:
to check if the value, I use this :
System.out.println(new myClass().getInjectMeThis());
System.out.println(new myClass().getInjectMeThis());
Spring will only parse #Value annotations on beans it knows. The code you use creates an instance of the class outside the scope of Spring and as such Spring will do nothing with it.
Assuming you have setup your application context correctly a #Value cannot be null as that will stop the correct startup of your application.
Your XML file contains a <context:component-scan /> assuming myClass is part of that package the easiest solution is to add #Component to myClass and then retrieve the instance from the context instead of creating a new instance.
In your class, add class level annotation #PropertySource("UserUtil.properties"). This should solve the problem.
There is CXF's PolicyBasedWSS4JInInterceptor that creates a singleton instance:
public static final PolicyBasedWSS4JInInterceptor INSTANCE
= new PolicyBasedWSS4JInInterceptor();
Having no Spring skills I'm struggling with how to set its acestor's (AbstractWSS4JInterceptor) properties map via Spring's bean definitions in a cxf.xml file. Basically I want to configure WSS-related properties like "signaturePropFile" in cxf.xml.
Can someone show how to set the property map of PolicyBasedWSS4JInInterceptor.INSTANCE? Thanks!
I would declare a singleton bean:
<bean id="interceptor" class="whatever.your.package.PolicyBasedWSS4JInInterceptor" scope="singleton"/>
And then inject it wherever I need it
<bean id="anotherBean" ...>
<property name="interceptor" ref="interceptor"/>
</bean>
This other bean would have a normal PolicyBasedWSS4JInInterceptor property like this:
private PolicyBasedWSS4JInInterceptor interceptor;
public PolicyBasedWSS4JInInterceptor getInterceptor() {
return interceptor;
}
public void setPolicyBasedWSS4JInInterceptor(PolicyBasedWSS4JInInterceptor interceptor) {
this.interceptor = interceptor;
}
And you would get the same as declaring it static, expressed in Spring terms. It's up to you which way you prefer, just remember that doing this the Spring way you have your interceptor inside your IoC container, and thus you can instrument it if necessary, etc.
The "action"-based WS-Security properties such as "signaturePropFile" do not work with the WS-SecurityPolicy based interceptors in CXF. CXF has separate configuration tags that you can just pass as JAX-WS properties when using WS-SecurityPolicy, and so you don't need to access any properties of the INSTANCE class. See here for more information:
http://cxf.apache.org/docs/ws-securitypolicy.html
Colm.
In my XML configuration I have this:
<bean id="soap" class="org.grocery.item.Soap" scope="prototype">
<property name="price" value="20.00" />
</bean>
And in my service class I have the "soap" autowired like this:
#Autowired
private Soap soap;
//Accessor methods
And I created a test class like this:
Item soap = service.getItem(ITEM.SOAP);
Item soap2 = service.getItem(ITEM.SOAP);
if(soap2 == soap ){
System.out.println("SAME REFERENCE");
}
And this is my getItem method in my service class:
public Item item(Item enumSelector) {
switch (enumSelector) {
case SOAP:
return this.getSoap();
}
return null;
}
#Autowired
private Soap soap;
//Accessor methods
Now what I am expecting is that the when I call the this.getSoap(); it will return a new Soap object. However, it did not, even though the soap is declared scoped as prototype. Why is that?
When you create the service object, spring will inject an instance of soap object to your service object.So all the calls to getSoap() of service will be retrieving the same soap object which was injected when service was created.
Renjith explained the why in his answer. As for the how, I know of 2 ways to achieve this:
lookup method:
Don't declare the soap dependency as a field, but rather as an abstract getter method:
protected abstract Soap getSoap();
Whenever you need the soap in your service (like in the getItem method), call the getter.
In the xml config, instruct Spring to implement that method for you:
<bean id="service" class="foo.YourService">
<lookup-method name="getSoap" bean="soapBeanId"/>
</bean>
The Spring supplied implementation would fetch a fresh instance of Soap whenever called.
Scoped proxies
This instructs Spring to inject a proxy instead of the real Soap instance. The injected proxy methods would lookup the correct soap instance (a fresh one since it's a prototype bean) and delegate to them:
<bean id="soap" class="foo.Soap">
<aop:scoped-proxy/>
</bean>
I have a system where I have an enum of Shops for example. These shows each have their own ShopCommand property (some of which share the same type of command class). from a method in the command class I then want to call send on a Spring Integration gateway. Where I'm confused is how to actually insantiate this gateway in spring. Ideally what I want is to construct the enum via XML configuration with command property being created also in spring, which has the property outGateway set via Spring. I'm not sure if I've made myself very clear with this descrition, if clarification is needed then just ask!
I think this is what you are asking for:
Say I have an enum for ShopType
public enum ShopType {
GROCERY, DEPARTMENT, MALL;
}
Then I have some Store bean that I want to setup via spring configuration. You can instantiate and use the enum like this:
<bean id="DEPTARTMENT_STORE" class="my.package.ShopType" factory-method="valueOf">
<constructor-arg value="DEPARTMENT"/>
</bean>
<bean id="searsStore" class="my.package.Store">
<property name="shopType" ref="DEPTARTMENT_STORE"/>
</bean>
The factory-method points to a static method that is used to create the object. So you can use the enum's method "valueOf" as a factory method.
I Am very new to Spring. I have an Interface (MessageHandler ) which has a get method, this method returns a list of Implementations of another interface (messageChecker).
public interface MessageHandler {
public void process(BufferedReader br);
public void setMessageCheckerList(List mcList);
[B]public List getMessageCheckerList();[/B]
}
In my Spring XML configuration , i have something like this ,along with other beans
<bean id="messageHandler" class="com.XXX.messagereceiver.MessageHandlerImpl">
<property name="messageCheckerList" ref="checkerList"/>
</bean>
<bean id="checkerList" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="HL7Checker"/>
</list>
</constructor-arg>
</bean>
<bean id="HL7Checker" class="com.XXX.messagereceiver.HL7CheckerImpl">
<property name="messageExecutor" ref="kahootzExecutor"/>
</bean>
Here i am passing a checkerlist - which is a list of Implementations ( For now i have only 1) of the Interface (messageChecker)
Checkerlist is containing references to Bean Id's which are actual implementaions.
HL7Checker is an implementation of an Interface messageChecker.
But when i run the main program, When i inject the bean "messageHandler" and call the getMessageCheckerList, It returns a null value. These getter and setter methods are working fine without using spring.
I am not sure what seems to be the problem.
I don't know the answer for you troubles, but I would check:
is the setter setMessageCheckerList(List) in messageHandler bean called? (either using some debugger or some trace output like System.out...). If it's not, there's probably something wrong with your Spring XML configuration setup. The bean definition you posted requires the property to be set and Spring wouldn't create the messageHandler bean without setting the property.
who calls the setMessageCheckerList(List) setter? Or even more precise, what code writes to the field which stores the value of the property? Maybe the field is initialized properly by Spring but gets overwritten to null later on?
are you sure you call the getMessageCheckerList on the very same object Spring has configured for you (that is, the messageHandler bean). The definition you have posted clearly states an instance of MessageHandlerImpl is created by Spring, but it doesn't prevent other instances to be created in other ways. So maybe the instance created by Spring holds the proper value, but you run the get... on a wrong instance?