I am downloading a json file and contents are available as arrays of arrays.
There are various validation(notNull, isNumber etc) which I want to do for the elements of child array.
One was is when I am using Spring batch and enable ValidatingItemProcessor and Bean Validation works for me.
However, I want to write a standalone solution using already existing Validator frameworks like from Apache but do not want to validate as bean but directly on array.
What should be my approach to this problem.
I am using Spring framework, so anything around that would be helpful.
We used JSR validations for our spring batch application. We annotated our classes with validations such as #NotNull,#DecimalMin. We then created a CommonValidator such as
import javax.validation.Validator;
...
public class CommonValidator<T> implements ItemProcessor<T, T>{
#Autowired
private Validator validator;
public T process(T t) throws Exception{
Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
return constraintViolations.isEmpty()? t : null;
}
We then, added it in a CompositeItemProcessor as follows.
<bean id="validateProcessor" class="mypackage.CommonValidator" />
class="org.springframework..CompositeItemProcessor">
<property name="delegates">
<list>
<ref bean="validateProcessor"/>
<ref bean="otherProcessor"/>
And it worked. On the similar lines, you can write your own validator to validate your array. So, if the array values are valid, then the array is returned. null is returned for an invalid array.
Related
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.
What is the easiest way to bind a UUID in Spring MVC, such that this works:
#RequestMapping("/MyController.myAction.mvc")
#ResponseBody
public String myAction(UUID id, String myParam)...
Using the above I currentely get the following exception:
org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [java.util.UUID]:
No default constructor found;
nested exception is java.lang.NoSuchMethodException: java.util.UUID.<init>()
There are other questions on SO that skirt around this, but none seem to answer it. I'm using Spring 3.latest (4 EA actually). I'm after the latest, simplest way to achieve this.
UUID is a class that cannot simply be instantiated. Assuming that it comes as a request parameter you should first annotate the argument with #RequestParam.
#RequestMapping("/MyController.myAction.mvc")
#ResponseBody
public String myAction(#RequestParam UUID id, String myParam)...
Now this expects a request parameter with the name id to be available in the request. The parameter will be converted to a UUID by the StringToUUIDConverter which is automatically registered by Spring.
Prior to the Spring 3.2
there was no StringToUUIDConverter so additionally you have to write and register converter by your own.
public class StringToUUIDConverter implements Converter<String, UUID> {
public UUID convert(String source) {
return UUID.fromString(source);
}
}
Hook this class up to the ConversionService and you should have UUID conversion for request parameters. (This would also work if it was a request header, basically for everything that taps into the ConversionService). You also might want to have a Converter for the other-way (UUID -> String).
Hooking it up to Spring MVC is nicely explained in the reference guide (assuming you use xml config). But in short:
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.company.converter.StringToUUIDConverter"/>
</set>
</property>
</bean>
The converter below is available in Spring Framework (core) since version 3.2.
org.springframework.core.convert.support.StringToUUIDConverter<String, java.util.UUID>
If its coming as a Header parameter use
#RequestHeader(value="UUID") String id
If its coming in a model
#ModelAttribute(value="ModelName") Entity modelName
I'm trying to do some spring validation with the error messages in properties files.
But the examples I find all seem to have the values hardcoded, or gotten from a properties file but using a validator class and retrieving it there.
My setup is a bit different.
I'm using the #Valid annotation in my requestmapping, and my #Valid class uses #NotNull etc.
I've seen some examples where people do #NotNull(message = "blablabla");
But that's also hardcoded, and I'd like to put the messages in a properties file so I can easily edit it on the fly and so I can easily implement i18n in the future.
Any input on how to achieve this would be appreciated.
It works exactly the same way as with explicit Validator - you declare a MessageSource and write error messages in .properties files. Messages codes are formed as constraintName.modelAttributeName.propertyName:
publib class Foo {
#NotNull private String name;
...
}
.
#RequestMapping
public String submitFoo(#Valid Foo foo, ...) { ... }
messages.properties:
NotNull.foo.name=...
MessageSource declaration:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value = "messages" />
</bean>
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?
I have DAO's for each table, that all implement an interface.
Now I want to be able to (potentially) swap database layer implementations.
So my strategy is to create a DaoFactory, and this DaoFactory will be specific to a particular implemenation of my DAO's.
So I will have DAO's for hibernate.
Then a DaoHibernateFactory that will look like:
public class DaoHibernateFactory implements DaoFactory
{
public UserDao GetUserDao() {
return new UserHibernateDao();
}
}
Then in all my manager/service classes, I will use whichever Dao___Factory is currently wired via spring ioc.
Does this make sense? Suggestions?
I would have separate configuration files for each implementation, rather than using factories. That way spring can inject your DAOs for you, and you don't have to call or maintain an extra factory class.
For example:
hibernate-data.xml:
<bean id="userDAO" class="com.foo.dao.hibernate.HibernateUserDao">
...
</bean>
ibatis-data.xml:
<bean id="userDAO" class="com.foo.dao.ibatis.IBatisUserDao">
...
</bean>
etc.
Then you can swap out the implementation by changing which -data file is included in your web.xml.
Since you are using dependency injection, you should try to use the wiring that is provided out of the box from the DI framework in question rather than writing your own factories.
The current problem can be solved using SpringPropertyPlaceHolder and a simple convention around the naming of the DAOs in the spring configuration file.
Steps:
1. First use some naming convention to name the Ids of your individual DAOs and configure them in the spring file.
Ex:
<bean id='hibernateUserDao' class='UserHibernateDao'/>
<bean id='ibatisUserDao' class='UserIbatisDao'/>
Here we are saying that all Hibernate Daos begin with hibernate and all ibatis Daos begin with ibatis etc.
2.Next configure the consumer of the Daos. Make sure that the wiring is dynamic depending on properties.
<bean id='daoconsumer' class='some.consumer.class'>
<property name='dao' ref='${daoImpl}UserDao'/>
</bean>
3.After that configure Spring Property place holder in your spring file.
<bean id="propertyConfigurator" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:/path/to/app.properties</value>
</property>
</bean>
4.Finally you write the app.properties with the single line.
daoImpl=hibernate # choose hibernate implementations.
Now, the daoImpl would get replaced by "hibernate". The other advantage of this technique is that SpringPropertyPlaceHolder can also obtain properties from the environment which it can use in preference to the app.properties (depends on a configuration parameter look up the javadocs for details)
Hence you can configure your app behavior using environment properties as well which can be pretty powerful.
Alternative 2:
You can also use Maven Profiles to achieve similar behavior. Maven has the ability to "filter" your resources - in this case it would replace placeholders with some strings depending on the maven profile that it is executing under. You can leverage this feature to generate app packages (jars, ears etc.) that work with a given implementation (like hibernate,ibatis etc). Obviously, this is less flexible than the PropertyPlaceHolder approach but can be preferable under certain conditions.
I would say you're missing the point badly if you think you need to write a factory. The Spring application context is the factory in this case: a declarative, dynamic object factory. The classes that use your factory lose the advantage of Spring.
You could write a generic DAO so you don't have to maintain all that code.
package hibernate.policy.persistence;
import java.io.Serializable;
import java.util.List;
public interface GenericDao<T, K extends Serializable>
{
T find(K id);
List<T> find();
List<T> find(T example);
List<T> find(String queryName, String [] paramNames, Object [] bindValues);
K save(T instance);
void update(T instance);
void delete(T instance);
}