I am not being able to make messageSource work in the Pojo classes,its throwing a nullpointerexception. However in all the other classes namely controller,service messageSource is working alright. Could someone please suggest what needs to be done ?
#Autowired
private MessageSource messageSource;
I have autowired the MessageSource using the above code snippet.
public class ProposalWiseSelectionForm implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Autowired
private MessageSource messageSource;
private String txtPageHierarchy="";
private String txtLineOfBusiness;
private String txtProduct;
private String btn;
private String clickedGo="N";
private List arrLineOfBusiness=new ArrayList();
private List arrProduct=new ArrayList();
#Valid
private ArrayList documentList=initiateDocumentList();
private String txtPageMode="I";
private String enableDiscardBtn="N";
private String enableInsertBtn="N";
private String isDivVisible="N";
private int numApplicationType=1;
public ProposalWiseSelectionForm() {
}
public String getTxtPageHierarchy() {
return txtPageHierarchy;
}
public void setTxtPageHierarchy(String txtPageHierarchy) {
this.txtPageHierarchy = txtPageHierarchy;
}
public String getTxtLineOfBusiness() {
return txtLineOfBusiness;
}
public void setTxtLineOfBusiness(String txtLineOfBusiness) {
this.txtLineOfBusiness = txtLineOfBusiness;
}
public String getTxtProduct() {
return txtProduct;
}
public void setTxtProduct(String txtProduct) {
this.txtProduct = txtProduct;
}
public String getBtn() {
return btn;
}
public void setBtn(String btn) {
this.btn = btn;
}
public String getClickedGo() {
return clickedGo;
}
public void setClickedGo(String clickedGo) {
this.clickedGo = clickedGo;
}
public List getArrLineOfBusiness() {
return arrLineOfBusiness;
}
public void setArrLineOfBusiness(List arrLineOfBusiness) {
this.arrLineOfBusiness = arrLineOfBusiness;
}
public List getArrProduct() {
return arrProduct;
}
public void setArrProduct(List arrProduct) {
this.arrProduct = arrProduct;
}
public void setArrProduct(ArrayList arrProduct) {
this.arrProduct = arrProduct;
}
public ArrayList getDocumentList() {
return documentList;
}
public void setDocumentList(ArrayList documentList) {
this.documentList = documentList;
}
public String getTxtPageMode() {
return txtPageMode;
}
public void setTxtPageMode(String txtPageMode) {
this.txtPageMode = txtPageMode;
}
public String getEnableDiscardBtn() {
return enableDiscardBtn;
}
public void setEnableDiscardBtn(String enableDiscardBtn) {
this.enableDiscardBtn = enableDiscardBtn;
}
public String getEnableInsertBtn() {
return enableInsertBtn;
}
public void setEnableInsertBtn(String enableInsertBtn) {
this.enableInsertBtn = enableInsertBtn;
}
public String getIsDivVisible() {
return isDivVisible;
}
public void setIsDivVisible(String isDivVisible) {
this.isDivVisible = isDivVisible;
}
public int getNumApplicationType() {
return numApplicationType;
}
public void setNumApplicationType(int numApplicationType) {
this.numApplicationType = numApplicationType;
}
}
In order to be able to use #Autowired in a class, that class has to be managed by Spring.
of
Your ProposalWiseSelectionForm class is obviously not managed by Spring and therefor messageSource is always null.
Using #Autowired MessageSource messageSource in your other classes works, because as you mention those classes are managed by Spring (as you have mentioned they are either controllers, services etc).
I am guessing that ProposalWiseSelectionForm is a DTO used to capture values from a form. The sort of class will not be a Spring bean and therefor you can't autowire stuff into it.
I suggest you either move the logic you need out of the DTO and into the controller (or some Spring managed utility) or in the extreme case that you absolutely need #Autowired in the DTO, take a look at #Configurable here and here
Try using #Component,you might be getting this issue because of the fact the Pojo class is not being recognized.
You have to make your class a Spring bean
Add #Component annotation to your class and add these 2 lines to your appContext.xml:
<context:component-scan base-package="com.<your-company-name>" />
<context:annotation-config />
Or just add the service in your beans section in the appContext.xml if you wish not to work with Spring component-scan feature.
Related
I am working within an environment that changes credentials every several minutes. In order for beans that implement clients who depend on these credentials to work, the beans need to be refreshed. I decided that a good approach for that would be implementing a custom scope for it.
After looking around a bit on the documentation I found that the main method for a scope to be implemented is the get method:
public class CyberArkScope implements Scope {
private Map<String, Pair<LocalDateTime, Object>> scopedObjects = new ConcurrentHashMap<>();
private Map<String, Runnable> destructionCallbacks = new ConcurrentHashMap<>();
private Integer scopeRefresh;
public CyberArkScope(Integer scopeRefresh) {
this.scopeRefresh = scopeRefresh;
}
#Override
public Object get(String name, ObjectFactory<?> objectFactory) {
if (!scopedObjects.containsKey(name) || scopedObjects.get(name).getKey()
.isBefore(LocalDateTime.now().minusMinutes(scopeRefresh))) {
scopedObjects.put(name, Pair.of(LocalDateTime.now(), objectFactory.getObject()));
}
return scopedObjects.get(name).getValue();
}
#Override
public Object remove(String name) {
destructionCallbacks.remove(name);
return scopedObjects.remove(name);
}
#Override
public void registerDestructionCallback(String name, Runnable runnable) {
destructionCallbacks.put(name, runnable);
}
#Override
public Object resolveContextualObject(String name) {
return null;
}
#Override
public String getConversationId() {
return "CyberArk";
}
}
#Configuration
#Import(CyberArkScopeConfig.class)
public class TestConfig {
#Bean
#Scope(scopeName = "CyberArk")
public String dateString(){
return LocalDateTime.now().toString();
}
}
#RestController
public class HelloWorld {
#Autowired
private String dateString;
#RequestMapping("/")
public String index() {
return dateString;
}
}
When I debug this implemetation with a simple String scope autowired in a controller I see that the get method is only called once in the startup and never again. So this means that the bean is never again refreshed. Is there something wrong in this behaviour or is that how the get method is supposed to work?
It seems you need to also define the proxyMode which injects an AOP proxy instead of a static reference to a string. Note that the bean class cant be final. This solved it:
#Configuration
#Import(CyberArkScopeConfig.class)
public class TestConfig {
#Bean
#Scope(scopeName = "CyberArk", proxyMode=ScopedProxyMode.TARGET_CLASS)
public NonFinalString dateString(){
return new NonFinalString(LocalDateTime.now());
}
}
I have set qualifier name from properties file as isomessage.qualifier=isoMessageMember1:
public class BankBancsConnectImpl implements BankBancsConnect{
#Autowired
#Resource(name="${isomessage.qualifier}")
private Iso8583Message iso8583Message;
public BancsConnectTransferComp getFundTransfer(IpsDcBatchDetail ipsDcBatchDetail) {
bancsxfr = iso8583Message.getFundTransfer(bancsxfr);
}
}
The value of ${isomessage.qualifier} is static as it is defined in the properties file. However i want it to be dynamic and get it's value from database based on certain condition. For instance i have multiple implementation of Iso8583Message (member wise) and has to call respective class of member id that is currently logged in. Please guide me to achieve this in the best and java spring way.
And my implementation class will look like this:
#Service("isoMessageMember1")
public class Iso8583MessageEBLImpl implements Iso8583Message{
public BancsConnectTransferComp getFundTransfer(BancsConnectTransferComp bancsxfr) throws Exception {
...
}
You can use Condition instead Qualifier if you are using Spring4+.
First, you need a ConfigDAO which read the qualifier name which you
need from database.
public class ConfigDAO {
public static String readFromDataSource() {
return " ";
}
}
Suppose there are two implemetions of Iso8583Message, you can
create two Condition objects.
IsoMessageMember1_Condition
public class IsoMessageMember1_Condition implements Condition {
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String qualifier = ConfigDAO.readFromDataSource();
if (qualifier.equals("IsoMessageMember1_Condition")) {
return true;
} else {
return false;
}
}
}
IsoMessageMember2_Condition
public class IsoMessageMember2_Condition implements Condition {
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String qualifier = ConfigDAO.readFromDataSource();
if (qualifier.equals("IsoMessageMember2_Condition")) {
return true;
} else {
return false;
}
}
}
Return different implemetion according to condition in config class.
#Configuration
public class MessageConfiguration {
#Bean(name = "iso8583Message")
#Conditional(IsoMessageMember1_Condition.class)
public Iso8583Message isoMessageMember1() {
return new Iso8583MessageEBLImpl();
}
#Bean(name = "iso8583Message")
#Conditional(IsoMessageMember2_Condition.class)
public Iso8583Message isoMessageMember2() {
return new OtherMessageEBLImpl();
}
}
Remove the #Qulifier and #Autowire annotations which you do not need anymore, you can retrieve the message from context every time you use it.
public class BankBancsConnectImpl implements BankBancsConnect{
private Iso8583Message iso8583Message;
public BancsConnectTransferComp getFundTransfer(IpsDcBatchDetail ipsDcBatchDetail) {
iso8583Message = (Iso8583Message)context.getBean("iso8583Message");
bancsxfr = iso8583Message.getFundTransfer(bancsxfr);
}
}
In spring it is possible to autowire the application context, and retrieve any bean based on its name.
For example, your interface signature similar to the below syntax
public interface Iso8583Message {
public String getFundDetails(String uniqueId);
}
and 2 different implementations follow below format
#Service("iso8583-message1")
public class Iso8583MessageImpl1 implements Iso8583Message {
#Override
public String getFundDetails(String uniqueId) {
return "Iso8583MessageImpl1 details ";
}
}
and
#Service("iso8583-message2")
public class Iso8583MessageImpl2 implements Iso8583Message {
#Override
public String getFundDetails(String uniqueId) {
return "Iso8583MessageImpl2 details ";
}
}
We can retrieve the beans as follows
public class BankBancsConnectImpl implements BankBancsConnect{
#Autowired
private ApplicationContext applicationContext;
public BancsConnectTransferComp getFundTransfer(IpsDcBatchDetail
ipsDcBatchDetail) {
//for retrieving 1st implementation
Iso8583Message iso8583Message=applicationContext.getBean("iso8583-message1", Iso8583Message.class);
//For retrieving 2nd implementation
Iso8583Message iso8583Message=applicationContext.getBean("iso8583-message2", Iso8583Message.class);
String result = iso8583Message.getFundTransfer(bancsxfr);
}
}
In this case, we can configure the bean names coming from the database instead of hard coded values("iso8583-message1","iso8583-message2").
I am trying to map two structures with JMapper but struggle with two encapsulated complex types and how to map them. I want to achive the following:
Source > Destination
Source.sourceString > Destination.destinationString
Source.SourceInternal > Destination.DestinationInternal
Source.SourceInternal.internalString2 > Destination.DestinationInternal.internalString
My classes look as follows:
public class Source {
private String sourceString;
private SourceInternal sourceInternal;
public String getSourceString() {
return sourceString;
}
public void setSourceString(final String sourceString) {
this.sourceString = sourceString;
}
public SourceInternal getSourceInternal() {
return sourceInternal;
}
public void setSourceInternal(final SourceInternal sourceInternal) {
this.sourceInternal = sourceInternal;
}
}
The internal source object
public class SourceInternal {
private String internalString1;
private String internalString2;
public String getInternalString1() {
return internalString1;
}
public void setInternalString1(final String internalString1) {
this.internalString1 = internalString1;
}
public String getInternalString2() {
return internalString2;
}
public void setInternalString2(final String internalString2) {
this.internalString2 = internalString2;
}
}
The destination the source should be mapped to
public class Destination {
private String destinationString;
private DestinationInternal destinationInternal;
public String getDestinationString() {
return destinationString;
}
public void setDestinationString(final String destinationString) {
this.destinationString = destinationString;
}
public DestinationInternal getDestinationInternal() {
return destinationInternal;
}
public void setDestinationInternal(final DestinationInternal destinationInternal) {
this.destinationInternal = destinationInternal;
}
}
The internal destination object.
public class DestinationInternal {
private String internalString;
public String getInternalString() {
return internalString;
}
public void setInternalString(final String internalString) {
this.internalString = internalString;
}
}
How would I achive the described mapping? Is it even possible with JMapper? Thanks.
I was looking into that a similar feature too. Here's how I managed it.
JMapperAPI jMapperAPI = new JMapperAPI()
.add(mappedClass(Destination.class)
.add(attribute("destinationString").value("sourceString"))
.add(attribute("destinationInternal").value("sourceInternal")))
.add(mappedClass(DestinationInternal.class).add(attribute("internalString").value("internalString1").targetClasses(SourceInternal.class)));
Basically the logic is to have a mapping for each nested class.
I'm trying to store a list in the Application class instance as a global variable in one of my Android applications. Below is my Application class code:
public class DefectsApplication extends Application{
private NormalUser normalUser;
private ArrayList<Complaint> complaintList;
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
private String testString;
public NormalUser getNormalUser() {
return normalUser;
}
public void setNormalUser(NormalUser normalUser) {
this.normalUser = normalUser;
}
public ArrayList<Complaint> getComplaintList() {
return complaintList;
}
public void setComplaintList(ArrayList<Complaint> m_complaints) {
this.complaintList = complaintList;
}
}
Below is my code which is trying to access the fields from the Application class instance:
DefectsApplication defectsApplication = ((DefectsApplication)getApplicationContext());
defectsApplication.setComplaintList(m_complaints);
defectsApplication.setTestString("urghhhhhhhhh");
ArrayList<Complaint> complaintList = defectsApplication.getComplaintList();
String s = defectsApplication.getTestString();
In the above code, m_complaints is a list of objects. When I try to store a String, it works. But for a list, it doesn't. Please, help me to resolve this issue.
Probably, a typo is taking place:
public void setComplaintList(ArrayList<Complaint> m_complaints) {
this.complaintList = complaintList;
}
You're setting this.complaintList to itself which is initially null. Try
public void setComplaintList(ArrayList<Complaint> m_complaints) {
this.complaintList = m_complaints;
}
The code below is working perfectly but I am in doubt if I am using the best approach for the requirenment: read, from a couple of places, property from a properties file in a Spring project. Basically, I created a public class with static variables. Now I am using Spring 3 plus JDK6. I might upgrade Spring to 4 soon but I will not be able to chnage JDK version.
mvc-dispatcher-servlet.xml
Properties File
url = http://localhost:8080/MHE2/
lastpage = log/display/last
firstpage = log/display/first
previouspage = log/display/previous
nextpage = log/display/next
One sample of using the property value. There will be a lot of case like these
//calling rest web service
DefaultHttpClient httpClient = new DefaultHttpClient(); //Apache HttpClient
HttpPost postRequest = new HttpPost(Ut_Properties.getUrl() + Ut_Properties.getLastpage());
Public class with static variables
package com.mastercard.mhe.utilities;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component("ut_Properties")
#Scope("singleton")
public class Ut_Properties {
private static String url;
private static String lastpage;
private static String firstpage;
private static String previouspage;
private static String nextpage;
#Autowired
public Ut_Properties(#Value("${url}") String url,
#Value("${lastpage}") String lastpage,
#Value("${url}") String previouspage,
#Value("${lastpage}") String nextpage) {
Ut_Properties.setUrl(url);
Ut_Properties.setLastpage(lastpage);
Ut_Properties.setUrl(previouspage);
Ut_Properties.setLastpage(nextpage);
}
public static String getUrl() {
return url;
}
public static void setUrl(String url) {
Ut_Properties.url = url;
}
public static String getFirstpage() {
return firstpage;
}
public static void setFirstpage(String firstpage) {
Ut_Properties.firstpage = firstpage;
}
public static String getPreviouspage() {
return previouspage;
}
public static void setPreviouspage(String previouspage) {
Ut_Properties.previouspage = previouspage;
}
public static String getNextpage() {
return nextpage;
}
public static void setNextpage(String nextpage) {
Ut_Properties.nextpage = nextpage;
}
public static String getLastpage() {
return lastpage;
}
public static void setLastpage(String lastpage) {
Ut_Properties.lastpage = lastpage;
}
}
You could use something like this:
#Service
public class MyPropertiesServ implements InitializingBean {
#Autowired
protected ApplicationContext context;
private Properties properties;
private static MyPropertiesServ singleInst;
protected MyPropertiesServ () {
properties = new Properties();
singleInst= this;
}
#Override
public void afterPropertiesSet() throws Exception {
properties.load(context.getResource("classpath:file.properties").getInputStream());
}
public static String getStringProperty(String key) {
return singleInst.properties.getProperty(key);
}
}
Another example:
http://forum.spring.io/forum/spring-projects/container/35703-initialising-static-property-of-class-through-injection-on-startup
#Value is a lovely annotation but looking at your code I'm wondering if it is important for you that those variables representing the properties are static ?
If not you could avoid alot of clutter code by not making them static.
#Component
public class Ut_Properties {
#Value("${url}")
private String url;
// ...
public getUrl() { return url; }
#Component/Service/Controller
public class ClassFromWhereYouWantToAccessTheProperties {
#Inject
Ut_Properties utProperties;
// you could ofcourse just inject the properties in the classes where you need them instead of trying to gather them in one class.
#Value("${url}")
private String url;
public void someRandomMethod() {
utProperties.getUrl();
// vs
this.url;