Spring Validator does not support command class - java

I think the issue is pretty common, but for some reason I cannot manage to fix this.
This is the error I am getting:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reverseController' defined in ServletContext resource [/WEB-INF/app-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Validator [FormValidator#6b3ded0d] does not support command class [ReverseString]
This is the supports method in my FormValidator class:
public boolean supports(Class clazz) {
return ReverseController.class.isAssignableFrom(clazz);
}
This is the bean definition on my app-servlet.xml:
<bean id="reverseController" class="ReverseController">
<property name="commandName"><value>reverseString</value></property>
<property name="commandClass"><value>ReverseString</value></property>
<property name="formView"><value>reverse</value></property>
<property name="successView"><value>reverseResult</value></property>
<property name="validator"><bean class="FormValidator" /></property>
And finally, this is the main part of my ReverseController:
#Service
public class ReverseController extends SimpleFormController {
public ReverseController() {
//setCommandClass(ReverseString.class);
//setCommandName("reverseString");
}
private ReverseString reverseStringMaster;
#Autowired
public void setWriter(ReverseString reverseStringMaster) {
this.reverseStringMaster = reverseStringMaster;
}
protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors) {
ReverseString revString = (ReverseString) command;
return new ModelAndView(getSuccessView(),"reversedString", revString);
}
public void init() {
System.out.println("Done");
}
}
Any idea what might be causing that issue?

It's an instance of the command class that gets validated on each request - as this gets populated with form data. The controller itself is not validated.
So the supports() method in your FormValidator should actually read:
public boolean supports(Class clazz) {
return ReverseString.class.isAssignableFrom(clazz);
}

Did you add getters and setters for this commandClass variable as well as well? If so, you probably need to remove the #spring.validator type="required" from the setter method method.

Try this code for your app-servlet.xml
1.Define your controller like this.
2.then use reverseController to call ReverseController class method.
<managed-bean>
<managed-bean-name>reverseController</managed-bean-name>
<managed-bean-class>com.action.ReverseController</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

Related

is it needed to add init-method in Sprint configuration file if there is nothing to initialize

I am new to Java. I have below java class:-
#WebService
#SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public class ABC extends AbstractWebService {
protected ClassNameForService classNameForService;
public void init() {
}
#WebMethod
#Path("/test")
#Produces("text/plain")
#GET
/**
*
* #return String
*/
public String test(
#WebParam(partName = "sessionID")
#QueryParam("sessionID") String sessionID
) throws UserNotDefinedException
{
// does something here
}
}
and below is my spring configuration file
<bean id=”org.testproject.webservices.ABC class=”org.testproject.webservices.ABC init-method=”init” parent=”org.testproject.webservices.AbstractWebService”>
<property name=classNameForService ref=”org.testproject.service.gb.ClassNameForService/>
</bean>
So do we need init-method=”init” here? Can I remove init-method=”init” from configuration as well as init method from class, Is it a standard practice?
You do NOT have to specify an init method (or destroy method for that matter). I think it's worth noting that you ask if it's standard practice, I believe the standard practice has moved away from the XML configuration to an annotation-driven approach but for the purpose of your question, it is standard practice to not include an init method when it is not needed.
The init-method is akin to adding a #PostContstruct annotated method on annotation declared beans.

How to pass a value from a #ApplicationScoped to a #ViewScoped?

When trying to pass the value I receive this error:
javax.servlet.ServletException: javax.servlet.ServletException: Unable to >create managed bean createController. The following problems were found:
Property configMB for managed bean createController does not exist. Check that appropriate getter and/or setter methods exist.
The scope of the object referenced by expression #{configMB}, request, is shorter than the referring managed beans (createController) scope of view at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:138)
Is it possible to pass a value from #ApplicationScoped to #ViewScoped?
You can inject long-life beans into short-life beans. (Not vice versa)
#ApplicationScoped
public class AppBean {
private Object someValue;
//getters
}
#ViewScoped
public class ViewBean {
#Inject
private AppBean appBean;
public void sendForm() {
Object value = appBean.getSomeValue();
// do things...
}
}

pass parameter to reference with autowired

i want pass parameter to #autowired ref like
public CoreDao {
private String taskId;
private final String sql = "select ....."+getTaskId()+".....";
public CoreDao(String taskId){
if(taskId.length != 0){
this.taskId = taskId;
}else{
this.taskId = "0";
}
public getTaskId(){
return this.taskId;
}
}
xml is:
<bean id="coreDao" class="Coredao" scope="prototype">
<constructor-arg type="java.lang.String" value=""/>
</bean>
and the CoreService is
#service
CoreService implement ICoreService{
#Autowired
pirvate CoreDao;
}
and xml is
<bean id="coreService" class="CoreService" scope="prototype">
<property name="coreDao" ref="coreDao"/>
</bean>
and i want use getBean("coreService","123") to get the bean with dynamic reference of coreDao.
However,when i use getBean("coreService","123"),the exception is:
error creating bean with name "coreService" defined in file ....xml,could not resolve matching constructor (hint:specify index/type/name arguments for simple parameter to avoid ambiguities.
how could do that?thanks your help.
getBean(String, Object ...) is applicable to bean's constructors or factory methods.
Your CoreService should have CoreService(String s) constructor in order to use this method.
If you want to create many CoreService instances with different parameters, you can create a factory bean which creates all instances for you and puts them together, like
#Component
public class CoreServiceFactoryBean {
#Autowired ApplicationContext ctx;
public CoreService getBean(String param) {
CoreService coreService = ctx.getBean("coreService");
CoreDao coreDao = ctx.getBean("coreDao", parameter);
coreService.setCoreDao(coreDao);
return coreService;
}
}
This way, the logic of creating bean and using it remains separate. Using factories is pretty common to configure prototype scoped beans.

Spring bean scope based on dynamic constructor value

I have to create a bean where it needs to be cached based on the dynamic constructor value. Example: I need an OrganizationResource bean where "x" (constructor value) organization will have its own specific instance values and "y" (constructor value) will have different values.
But I don't want to create a new object for every x value, I want it to be cached.
I know there are 2 scopes, singleton and prototype, for dynamic constructor value. I am planning to use prototype, but it seems it will create a new object every time, how can I implement cache based on constructor value in spring?
FactoryBean is a way to go. It is very simple, give it a try. All you have to do is create a class implementing FactoryBean and reference it in bean definition file:
package some.package;
import org.springframework.beans.factory.FactoryBean;
public class ExampleFactory implements FactoryBean {
private String type;
public Object getObject() throws Exception {
//Logic to return beans based on 'type'
}
public Class getObjectType() {
return YourBaseType.class;
}
public boolean isSingleton() {
//set false to make sure Spring will not cache instances for you.
return false;
}
public void setType(final String type) {
this.type = type;
}}
Now, in your bean definition file, put:
<bean id="cached1" class="some.package.ExampleFactory">
<property name="type" value="X" />
</bean>
<bean id="cached2" class="some.package.ExampleFactory">
<property name="type" value="Y" />
</bean>
It will make objects based on strategy you implemented in ExampleFactory.getObject().

spring bean with dynamic constructor value

I need to create an Object which is in-complete without the constructor argument. Something like this
Class A {
private final int timeOut
public A(int timeout)
{
this.timeOut = timeout;
}
//...
}
I would like this Bean to be spring managed, so that I can use Spring AOP later.
<bean id="myBean" class="A" singleton="false">
</bean>
However my bean needs timeout to be passed as a dynamic value - is there a way to create a spring managed bean with dynamic value being injedcted in the constructor?
BeanFactory has a getBean(String name, Object... args) method which, according to the javadoc, allows you to specify constructor arguments which are used to override the bean definition's own arguments. So you could put a default value in the beans file, and then specify the "real" runtime values when required, e.g.
<bean id="myBean" class="A" scope="prototype">
<constructor-arg value="0"/> <!-- dummy value -->
</bean>
and then:
getBean("myBean", myTimeoutValue);
I haven't tried this myself, but it should work.
P.S. scope="prototype" is now preferable to singleton="false", which is deprecated syntax - it's more explicit, but does the same thing.
Two options spring (no pun intended) to mind:
1. create a timeout factory, and use that as the constructor parameter.
You can create a bean which implements FactoryBean, and it's job is to create other beans. So if you had something that generates salt's for encryption, you could have it return from getObject() a EncryptionSalt object. In your case you're wanting to generate Integers.
Here is an example: http://www.java2s.com/Code/Java/Spring/SpringFactoryBeanDemo.htm
2. create a timeout bean that wraps an int that's dynamically set, and leave that in the "prototype" state so it's created each time
Instead of going to the hassle of creating a factory, the EncryptionSalt object could just be declared as a prototype bean, so when it's injected a new object is created each time. Place the logic into the constructor or somewhere else.
It somewhat depends what value you want the timeout to actually be.
Do it explicitly:
interface Bean {
void setTimeout(int timeout);
}
class BeanImpl implements Bean {
private int timeout;
#Override
public void setTimeout(int timeout) {
this.timeout = timeout;
}
...
}
<bean id="bean" class="BeanImpl" scope="prototype">
...
<!-- Nothing about timeout here -->
...
</bean>
class Client {
private Bean bean;
public void setBean(Bean bean) {
this.bean = bean;
}
...
public void methodThatUsesBean() {
int timeout = calculateTimeout();
bean.setTimeout(timeout);
...
}
}

Categories