I am using spring 3.0 in my webapplication. I've got recently a problem in my application. I am using <mvc:annotation-drive/> tag in my spring-servlet.xml file but due to a requirement I've to remove this and place XML configuration instead.
But now my problem is it generates json output with quoted field names like if I return Boolean.TRUE I got "true" in the output. I want just true without quotes.
here is my XML configuration
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<bean id="pathMatcher" class="net.hrms.web.filters.CaseInsensitivePathMatcher" />
<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService"></property>
</bean>
</property>
<property name="messageConverters">
<list>
<ref bean="byteArrayConverter"/>
<ref bean="jaxbConverter"/>
<ref bean="jsonHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
</list>
</property>
</bean>
<bean name="byteArrayConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
<bean name="jaxbConverter" class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="pathMatcher" ref="pathMatcher"></property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsps/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="jsonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="prefixJson" value="false"/>
<property name="supportedMediaTypes" value="application/json"/>
</bean>
any help would be much appreciable.
If you are using the FlexJSON plugin, you can create custom output for JSON. I am sure you can do that in Jackson too, but I have never done it. There is loads of examples on the FlexJSON site.
What happens if you return just the primitive value of true (or Boolean.TRUE.booleanValue() rather than the wrapped object version of Boolean.TRUE?
I believe that true and false values are hardcoded in Jackson library (writeBoolean is called even for the boxed booleans):
private final static byte[] TRUE_BYTES = { 't', 'r', 'u', 'e' };
#Override
public void writeBoolean(boolean state)
throws IOException, JsonGenerationException
{
_verifyValueWrite("write boolean value");
if ((_outputTail + 5) >= _outputEnd) {
_flushBuffer();
}
byte[] keyword = state ? TRUE_BYTES : FALSE_BYTES;
int len = keyword.length;
System.arraycopy(keyword, 0, _outputBuffer, _outputTail, len);
_outputTail += len;
}
so Jackson will never return double-quoted "true" in field values(if its behavior is not heavily overriden, for example with codecs).
So please check that MappingJacksonHttpMessageConverter methods are being invoked, and conversion is not performed somewhere else.
That is the default behavior, if you want your boolean values unquoted use a JAXB ContextResolver
Something like this
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import com.sun.jersey.api.json.JSONJAXBContext;
#Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
private JAXBContext context;
private Class[] types = {SomeClass.class}; //Add the classes processed by JAXB and exposing boolean properties
public JAXBContextResolver() throws Exception {
Map props = new HashMap<String, Object>();
props.put(JSONJAXBContext.JSON_NOTATION, JSONJAXBContext.JSONNotation.MAPPED);
props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE);
java.util.HashSet<String> eprops = new HashSet<String>();
eprops.add("someBooleanProperty"); //add properties you want unquoted
props.put(JSONJAXBContext.JSON_NON_STRINGS, eprops);
this.context = new JSONJAXBContext(types, props);
}
public JAXBContext getContext(Class<?> objectType) {
return (types[0].equals(objectType)) ? context : null;
}
}
Related
I have bean class as below -
public class Account {
private String strAccNumber = "";
private List<Account> accountList = new ArrayList<Account>();
// getter setter
....
...
#Override
public String toString() {
// code for PassThroughLineAggregator
String data="";
for (int j=0; j<accountList.size(); j++) {
Account bean = accountList.get(j);
data = data + bean.getStrAccNumber();
if (j<(accountList.size()-1)) {
data = data + "\n";
}
}
return data;
}
}
to write data I want to set accountList in my config file.
I'm using below code to set bean property.
<bean id="flatFileReader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
<property name="resource" value="classpath:springBatch.csv" />
<property name="strict" value="false"></property>
<property name="linesToSkip" value="1" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="ACC#" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="com.abc.reader.AccountDetailsFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="flatFileProcessor"
class="com.abc.processor.AccountItemProcessor"
scope="step"></bean>
<bean id="flatFileWriter"
class="com.abc.FlatFileItemWriterListener"
scope="step">
<property name="resource" value="classpath:springBatch1.csv" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="strAccNumber" />
</bean>
</property>
</bean>
</property>
</bean>
AccountItemProcessor -
public class AccountItemProcessor implements ItemProcessor<Account, List<Account>>{
#Override
public List<Account> process(Account accObj) throws Exception {
// logic..
}
After processing single record in the process step I want to write multiple items(list of item) , how can I write multiple item at a time using arraylist. In my case I want to write data from accountlist.
You'll want to implement your own LineAggregator. That is what provides the String to be written to the file. In your case, you'll write one that returns a String that is really multiple lines.
You can read more about the LineAggregator interface in the documentation here: http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/file/transform/LineAggregator.html
I'm new to Spring and trying to get a example to work. But my application loads twice each time it starts. I think it could be a context problem because of my internet research and I have just one context.xml.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
<bean name="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
<bean name="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="requestFactory" ref="requestFactory" />
</bean>
<bean name="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="10000" />
<property name="readTimeout" value="10000" />
</bean>
<bean name="httpClient" class="org.apache.http.client.HttpClient" factory-bean="requestFactory" factory-method="getHttpClient"/>
<bean name="TraderApplication" class="net.mrmoor.TraderApplication"/>
<bean name="API" class="com.iggroup.api.API"/>
<bean name="LightStreamerComponent" class="com.iggroup.api.streaming.LightStreamerComponent"/>
</beans>
My code of the TraderApplication Class is:
... skipped imports ....
#SpringBootApplication
public class TraderApplication implements CommandLineRunner{
private static final Logger log = LoggerFactory.getLogger(TraderApplication.class);
#Autowired
protected ObjectMapper objectMapper;
#Autowired
private API api;
#Autowired
private LightStreamerComponent lightStreamerComponent = new LightStreamerComponent();
private AuthenticationResponseAndConversationContext authenticationContext = null;
private ArrayList<HandyTableListenerAdapter> listeners = new ArrayList<HandyTableListenerAdapter>();
public static void main(String args[]) {
SpringApplication.run(TraderApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
try {
if (args.length < 2) {
log.error("Usage:- Application identifier password apikey");
System.exit(-1);
}
String identifier = args[0];
String password = args[1];
String apiKey = args[2];
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/public-api-client-spring-context.xml");
TraderApplication app = (TraderApplication) applicationContext.getBean("TraderApplication");
app.run(identifier, password, apiKey);
} catch (Exception e) {
log.error("Unexpected error:", e);
}
}
You mention in your comments above you got this working by removing SpringApplication.run(TraderApplication.class, args); but this would be removing spring-boot from your application so I'm going to assume since your question has a tag of [spring-boot] that this is not what you wanted. So here is an alternative way that you can configure beans using your xml.
#ImportResource({"classpath*:public-api-client-spring-context.xml"}) //Proper way to import xml in Spring Boot
#SpringBootApplication
public class TraderApplication implements CommandLineRunner {
...code you had before goes here
#Autowired
TraderApplication app;
#Override
public void run(String... args) throws Exception {
.. your parsing logic here
app.run(identifier, password, apiKey); //Now uses the autowired instance
}
}
You didn't list your pom.xml or build.gradle but it's important to remember that components you have registered in your context xml may be automatically configured in Spring Boot and you may not need to register them yourself in your xml.(Depending on which items you have starters for in your build file)
I have a problem the InOnly exchange pattern what I use with aciveMq.
I wrote a module what run in ServiceMix. It works correctly except that it send every message to dead letter queue (ActiveMQ.DLQ). If I check the message then dlqDeliveryFailureCause contains this message: java.lang.Throwable: Message Expired.
I checked the JMSExpiration = 0.
The route:
from("direct:" + reqOutQueue).id("reqInEnritch")
.log("Start dispatch")
.setExchangePattern(ExchangePattern.InOnly)
.recipientList().method(EsbDynamicRouter.class, "systemRoute").parallelProcessing();
The function, what gives back the endpoint list:
#RecipientList
public String[] systemRoute(#Body Object body) throws Exception
{
String[] result = null;
List<DispConfView> targetList;
int cikl = 0;
SystemQueueHelper systemInfo;
MessageHeaderHelper msgHeadHelp = new MessageHeaderHelper(body);
// The object contains the affected elements
targetList = dispHelp.getDispConfByMsgType(msgHeadHelp.getMsgType());
result = new String[targetList.size()];
for (DispConfView element : targetList)
{
// It builds the target andpoints
systemInfo = new SystemQueueHelper(element.getSystemCode(), null, msgHeadHelp.getDirection());
result[cikl] = systemInfo.getQueuName();
cikl++;
}
return result;
}
The list contains these values:
activemq:queue:ERP.req.in?exchangePattern=InOnly
activemq:queue:WF.req.in?exchangePattern=InOnly
As you see, I try to set the correct pattern, but every messages go to dead letter queue.
Please help, what I have to set up!
Thank you!
The solution:
It is settable in context file:
<!-- JMS configuration -->
<bean id="pooledJmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="1" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:(tcp://localhost:61616)" />
<property name="redeliveryPolicy">
<bean class="org.apache.activemq.RedeliveryPolicy">
<property name="maximumRedeliveries" value="5"/>
</bean>
</property>
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledJmsConnectionFactory"/>
<property name="cacheLevelName" value="CACHE_CONSUMER" />
<property name="disableReplyTo" value="true" />
</bean>
The "jmsConfig bean ""diasbleReplayTo" property solve the problem.
In spring context file, I use org.springframework.beans.factory.config.PropertyPlaceholderConfigurer to load several configuration files:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>a.properties</value>
<value>b.properties</value>
<value>c.properties</value>
</list>
</property>
</bean>
The a.properties, b.properties, c.propertes may have some hibernate configurations which have prefix of abc.:
abc.hibernate.show_sql=true
abc.hibernate.default_schema=myschema
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
Now I want to define a hibernate session factory:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<util:properties>
<prop key="hibernate.show_sql">${abc.hibernate.show_sql}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
</util:properties>
</property>
</bean>
You can see I have to write the property in bean declaration again and again:
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
Is there any way to just tell spring to get all properties which have prefix abc.?
So I can write:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<something prefix="abc" /> <!-- TODO -->
</property>
</bean>
Is it possible or is there any other simple solutions for it?
You can use something like the following class to extend java.util.Properties:
import java.util.Enumeration;
import java.util.Properties;
public class PrefixedProperties extends Properties {
public PrefixedProperties(Properties props, String prefix){
if(props == null){
return;
}
Enumeration<String> en = (Enumeration<String>) props.propertyNames();
while(en.hasMoreElements()){
String propName = en.nextElement();
String propValue = props.getProperty(propName);
if(propName.startsWith(prefix)){
String key = propName.substring(prefix.length());
setProperty(key, propValue);
}
}
}
}
Then you can define sessionFactory as following:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<bean id="sessionFactoryProperties" class="PrefixedProperties">
<constructor-arg ref="props"/> <!-- reference to all properties -->
<constructor-arg value="abc.hibernate."/> <!-- prefix -->
</bean>
</property>
</bean>
I don't see any other possibility to filter properties.
As Sean said, PropertyPlaceHolderConfigurer don't expose his properties, but you could use reflection to filter them.
public static Properties filterProperties(String prefix, PropertyPlaceholderConfigurer ppc) {
Properties props = new Properties();
Method method = ReflectionUtils.findMethod(PropertiesLoaderSupport.class, "mergeProperties");
ReflectionUtils.makeAccessible(method);
Properties all = (Properties) ReflectionUtils.invokeMethod(method, ppc);
for (String key : all.stringPropertyNames()) {
if (key.startsWith(prefix))
props.setProperty(key, all.getProperty(key));
}
return props;
}
And inject with spel
<bean id="ppc" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
...
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties" value="#{T(SomeClass).filterProperties('abc.', #ppc)}" />
</bean>
The PropertyPlaceHolderConfigurer is a special construct that is meant for bean creation only. It does not expose the underlying properties in a way that you can access.
A possible workaround is to subclass PropertyPlaceHolderConfigurer, as I have outlined in a previous answer of mine.
Another way is to have a custom PropertiesFactoryBean, like this one:
public class PrefixedPropertyFactoryBean extends AbstractFactoryBean<Properties> {
private List<Resource> locations;
public void setLocations(List<Resource> locations) { this.locations = locations; }
private String prefix;
public void setPrefix(String prefix) { this.prefix = prefix; }
#Override public Class<?> getObjectType() { return Properties.class; }
#Override
protected Properties createInstance() throws Exception {
Properties properties = new Properties();
for (Resource resource : locations) {
properties.load( resource.getInputStream());
}
final Iterator<Object> keyIterator = properties.keySet().iterator();
while(keyIterator.hasNext()) {
if(!keyIterator.next().toString().startsWith(prefix))
keyIterator.remove();
}
return properties;
}
}
You can use this in your XML as follows:
<bean id="hibernateProps" class="some.path.PrefixedPropertyFactoryBean">
<property name="locations">
<list>
<value>a.properties</value>
<value>b.properties</value>
<value>c.properties</value>
</list>
</property>
<property name="prefix" value="abc.hibernate" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties" ref="hibernateProps" />
</bean>
This is of course redundant, as you'd probably still have to wire the PropertyPlaceHolderConfigurer to set up your other beans.
All - In the Spring 3.0, in the applicationContext.xml .... are we supposed to have the bean property name and the reference value to be the same ? If I give a different value, it returns null object. But on giving the same value, it works. For my project, i am supposed to give different values for them. Kindly help. bye, HS
This works: (same values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
This doesn't work: (different values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
bye, HS
My Full Code here:
WIRAdminBaseAction.java ---> my base action
AuthenticateAction.java ---> my java file that calls the bean here
applicationContext.xml --> system's applicationcontext file
applicationContext_MNC.xml ---> my applicationContext for a specific company ... this is getting loaded by my java file, which gets invoked by the web.xml file.
CacheDelegate.java
StatusDBDAO.java
PreXMLWebApplicationContext.java ----> loads my applicationContext file for the specific company.
****** applicationContext.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean name="exceptionHandler" class="com.megasoft.wir.eStatement.web.interceptor.WIRExceptionHandlerInterceptor"/>
<bean name="security" class="com.megasoft.wir.eStatement.web.interceptor.SecurityInterceptor"/>
<bean name="permission" class="com.megasoft.wir.eStatement.web.interceptor.PermissionInterceptor"/>
<!-- AutoProxies -->
<bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>base</value>
<value>exceptionHandler</value>
<value>security</value>
<value>permission</value>
</list>
</property>
</bean>
</beans>
****** applicationContext_MNC.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
<bean id="MNCCacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
<bean id="MNCStatusDBDAO" class="com.megasoft.wiradmin.dao.StatusDBDAO">
<property name="dataSource">
<ref bean="MNCAdminDataSource" />
</property>
</bean>
<!-- database configuration from property file -->
<bean id="MNCAdminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClass" value="${jdbc.driver}" ></property>
<property name="jdbcUrl" value="${admin.jdbc.url}" ></property>
<property name="user" value="${admin.jdbc.user}" ></property>
<property name="password" value="${admin.jdbc.password}" ></property>
<property name="initialPoolSize" value="3" ></property>
<property name="minPoolSize" value="3" ></property>
<property name="maxPoolSize" value="25" ></property>
<property name="acquireIncrement" value="1" ></property>
<property name="acquireRetryDelay" value="1000" ></property>
<property name="debugUnreturnedConnectionStackTraces" value="true" ></property>
<property name="maxIdleTime" value="300" ></property>
<property name="unreturnedConnectionTimeout" value="300000" ></property>
<property name="preferredTestQuery" value="SELECT COUNT(*) FROM LOCALE_CODE" ></property>
<property name="checkoutTimeout" value="300000" ></property>
<property name="idleConnectionTestPeriod" value="600000" ></property>
</bean>
<!-- this bean is set to map the constants which needs to be configured as per
the environment to the java constants file -->
<bean id="envConstantsConfigbean" class="com.megasoft.wiradmin.util.constants.Environm entConstantsSetter">
<property name="loginUrl" value="${login.url}"/>
<property name="logoutIR" value="${logout.from.image.retrieval}"/>
<property name="adminModuleUrl" value="${admin.url}"/>
<property name="adminUrlSym" value="${admin.url.sym}"/>
<property name="envProperty" value="${env.property}"/>
</bean>
</beans>
****** AuthenticateAction.java ******
package com.megasoft.wiradmin.web.action;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.bouncycastle.crypto.CryptoException;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.web.context.support.WebApplica tionContextUtils;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class AuthenticateAction extends WIRAdminBaseAction {
private static final long serialVersionUID = 1L;
public String authenticate() throws UnknownHostException, CryptoException,
DataAccessException, SQLException{
/** This way of calling works...... This is not encouraged, as we should not use applicationContext always **/
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContex t(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate) applicationContext.getBean("MNCCacheDelegate");
/** The below way of calling does NOT work .... returns null value.... Please help...
* I assume that, since I have extended the WIRAdminBaseAction, i should be able to call the getCacheDelegate directly
* and it should return my cacheDelegate object ...
* Again, Please note.....if I change my applicationContext_MNC.xml as below, the below way of calling works fine...
* but, i don't want to change my applicationContext_MNC.xml as below, due to some necessity.
*
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
*
<bean id="cacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
*
... is it that the name and bean should have the same value.... ??? No Need to be.....Am i right ? Please advise.
*
* **/
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
return "success";
}
}
****** WIRAdminBaseAction.java ******
package com.megasoft.wiradmin.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.config.entities.Parameteri zable;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class WIRAdminBaseAction extends ActionSupport implements Preparable, ParameterAware, Parameterizable, SessionAware,RequestAware {
private HttpServletRequest request;
private static final long serialVersionUID = 1L;
private HttpServletResponse response;
private ICacheDelegate cacheDelegate;
private Map session;
private Map<String, String> params;
private Map parameters;
public void prepare() throws Exception {
}
public String execute() throws Exception {
return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public HttpServletResponse getServletResponse() {
return this.response;
}
public ICacheDelegate getCacheDelegate() {
return cacheDelegate;
}
public void setCacheDelegate(ICacheDelegate cacheDelegate) {
this.cacheDelegate = cacheDelegate;
}
public void addParam(final String key, final String value) {
this.params.put(key, value);
}
public Map getParams() {
return params;
}
public void setParams(final Map<String, String> params) {
this.params = params;
}
public Map getSession() {
return this.session;
}
public void setSession(final Map session) {
this.session = session;
}
public void setParameters(final Map param) {
this.parameters = param;
}
}
PreXMLWebApplicationContext.java **
package com.megasoft.wiradmin.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class PreXMLWebApplicationContext extends XmlWebApplicationContext {
/**
* This initializes the Logger.
*/
private static Log logger = LogFactory.getLog(PreXMLWebApplicationContext.class);
protected String[] getDefaultConfigLocations() {
String environment = System.getProperty("envProperty");
String webirConfig = System.getProperty("webirConfig");
String fi = System.getProperty("FI");
String preHostConfiguration =null;
logger.info("The environment is "+environment);
logger.info("The webirConfig is "+webirConfig);
logger.info("The fi is "+fi);
if(environment != null && webirConfig != null && fi != null) {
preHostConfiguration = DEFAULT_CONFIG_LOCATION_PREFIX +
"classes/applicationContext" + "_" + fi.toUpperCase() +
DEFAULT_CONFIG_LOCATION_SUFFIX;
}
return new String[]{DEFAULT_CONFIG_LOCATION, preHostConfiguration};
}
/**
* This is close API.
*
* #see org.springframework.context.support.AbstractApplicationContext
* #close()
*/
public void close() {
this.doClose();
logger.info("Login-->into the closed");
}
}
<property name="userDelegate" ref="userDelegate" />
name is the field name in your class. When name is userDelegate, it means that WIRAdminBaseAction has a field named userDelegate (and probably a setter setUserDelegate())
ref is the bean name you want to set this field to. In your example, you should have another bean, named userDelegate or bmoUserDelegate which should be set as userDelegate in WIRAdminBaseAction.
So if you want to use the second configuration:
You just need to create a bean with id bmoUserDelegate:
<bean id="bmoUserDelegate" class="mypackage.BmoUserDelegateClass"/>