In native JSF 2.0 environment user is able to refer to request parameters with something like
#ManagedProperty("#{param.id}")
private Long id;
However I'm using Spring to manage JSF beans, so #ManagedProperty annotation is ignored in my case. It's still possible to use #{param.id} statement in faces-config.xml, but annotation-based configuration is obviously much more preferable.
Is there any way to resolve such statements with Spring annotations?
You can try to use #Value with Spring Expression Language. There should be request variable available:
#Value("#{request.getParameter('id')}")
private Long id
Related
So, I have an application running on WildFly10, which uses JSF, Spring (DI), JPA, Spring Data;
Right now we're trying to move it to CDI and remove Spring(DI). For now we'll keep Spring Data.
So, I set up CDI and made an EntityManager producer.
#Produces
#Dependent
#PersistenceContext
public EntityManager entityManager;
So, I'm able to inject repositories with CDI and all.
However on my original environment we had a custom repository factory,that was defined in my SpringConfiguration like this:
#EnableJpaRepositories(basePackages = {"com.foo.repository" }, repositoryFactoryBeanClass=CustomJpaRepositoryFactoryBean.class)
So, the question is, how can I define this repositoryFactoryBeanClass=CustomJpaRepositoryFactoryBean.class on a CDI environment?
The current implementation doesn't allow the configuration of the JpaRepositoryFactoryBean as one can see from the code where it gets instantiated.
So I guess you have the following options:
reimplement the instantiation process.
open a feature request.
do 2. and 1. in a reusable way and submit the result as a PR for the issue.
When trying to solve this problem I found that the custom impl was not being picked up. The solution suggested in this question helped me however: https://stackoverflow.com/a/38541669/188624
Basically is uses Java8 default interface method to provide the additional functionality. I had to use the "CDI.current().select" method to get hold of the entity manager though as property injection of course won't work.
I tested with Spring Data JPA 2.0.0
I'm trying to set an attribute in an annotation, using Spring #Value, but I get Type mismatch: cannot convert from Value to String. Here is what I tried:
#Table(name = "myTable", catalog = #Value("${database.myCatalog}") )
Is it possible? And if yes, how to do it?
I think you are a little bit confused with how Spring uses that annotation.
As far as I know, the only way that annotation can only be set at field or method/constructor parameters.
Also, for Spring to resolve it, the POJO must be a Spring managed bean. That means that it must be defined in the Spring (Web)ApplicationContext implementation to be resolved.
Your question seems like you are annotating a JPA Entity which is not a Spring bean but a Class to be used by the JPA implementation that you are using (e.g. Hibernate).
How to enable the #Required annotation in Java (Spring 3.1) ? Not in a xml, but in through Java. Also under which annotation I put this enabling? Under #Feature (in #FutureConfiguration or #Bean (in #Configuration) ?
Edit:
#Feature
public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
return new MvcAnnotationDriven().conversionService(conversionService)
.argumentResolvers(new CustomArgumentResolver());
}
Does this enables all annotations?
#anubhava's answer works, but he's referenced the Spring 2.0 manual, which is 5 years old.
In XML config, Spring 3.x has a more elegant approach: <context:annotation-config/>. This also enabled a whole other bunch of features that you'll probably want, whereas RequiredAnnotationBeanPostProcessor only enables a few.
See Spring 3.x manual.
If you're using #Bean-style config, then annotations like #Required should already be enabled, since that's how #Bean works. However, it's possible that this is a bug - Spring 3.1 is still in early beta, and big chunks of it are likely to be broken.
Unless you really know what you're doing, I strongly recommend sticking to 3.0.x.
From the Spring manual:
There is one last little (small, tiny)
piece of Spring configuration that is
required to actually 'switch on' this
behavior. Simply annotating the
'setter' properties of your classes is
not enough to get this behavior. You
need to enable a component that is
aware of the #Required annotation and
that can process it appropriately.
This component is the
RequiredAnnotationBeanPostProcessor
class. This is a special
BeanPostProcessor implementation that
is #Required-aware and actually
provides the 'blow up if this required
property has not been set' logic. It
is very easy to configure; simply drop
the following bean definition into
your Spring XML configuration.
<bean class=
"org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
Please check: http://static.springsource.org/spring/docs/2.0.x/reference/metadata.html
Use AnnotationConfigApplicationContext if you don't want to use XML:
Standalone application context,
accepting annotated classes as input -
in particular #Configuration-annotated
classes, but also plain #Components
and JSR-330 compliant classes using
javax.inject annotations. Allows for
registering classes one by one
(register(java.lang.Class...)) as well
as for classpath scanning
(scan(java.lang.String...)).
In case of multiple Configuration
classes, Bean methods defined in later
classes will override those defined in
earlier classes. This can be leveraged
to deliberately override certain bean
definitions via an extra Configuration
class.
Sample Code:
ConfigurableApplicationContext applicationContext =
new AnnotationConfigApplicationContext(
"com.mycompany.package1",
"com.mycompany.package2",
"com.mycompany.package3"
// etc.
);
applicationContext.refresh();
I've been looking a around for a while now with no luck. I'n not using Spring MVC but still want to use #javax.validation.Valid to enable validation of method arguments. To give an example
public class EventServiceImpl implements IEventService {
#Override
public void invite(#Valid Event event, #Valid User user) { ... }
}
Using MVC, this is enabled for #Controller annotated beans with a simple <mvc:annotation-driven/> (see 5.7.4.3 Configuring a JSR-303 Validator for use by Spring MVC).
Using AOP should be quite trivial. Nevertheless, I suspect there's some standard way to do this. Hence the question: Is there a similar thing for non-MVC applications and non-controller beans to enable input validation for annotated beans?
Method level validation is not part of the Bean Validation specification (JSR 303). Method level validation is a suggestion in the spec added in appendix C.
Hibernate Validator 4.2 (a beta is out already) is implementing this suggestion and allows to place JSR 303 annotations on method parameters and return values. Of course you will still need some Spring glue code, but that should not be too hard.
Also Bean Validation 1.1 will add method level validation officially to the spec (not just as appendix/recommendation). See also http://beanvalidation.org/
Using MVC, this is enabled for #Controller annotated beans
#Valid is just a marker in Controller beans that hides the code that does the validation and puts all constraint violations in Errors in a nice way. Spring designers could have invented their own annotation to do the same thing.
The real use of #Valid annotation is in the class (bean) that you are validating with JSR 303 validator and its primary use is to validate the object graph. Meaning one bean can have other
bean references with #Valid annotation to trigger validation recursively.
Outside the MVC, you can use configured validator to validate any bean that uses JSR 303 annotations but, unlike the nicely populated Errors in controller, you will have to decide yourself what you are going to do with constraint violations.
So, to answer your question, there is no standard way. To have the same appearance as in a controller, you could use #Valid annotation (or create a new one) to run AOP advice to validate a bean and populate a 'ViolationCollector' (something like Errors in MVC) that must be passed to a method.
The answers seem to be quite old. As of now, you can utilize #Validated and MethodValidationPostProcessor for method inline validation of any Spring beans. They are basically responsible for creating pointcut-like behavior for Spring managed beans of any tier, not Controllers specifically.
Also see my other answer.
#SpringBean
PDLocalizerLogic loc;
When using above I receive java.io.NotSerializableException. This is because loc is not serializable, but this shouldn't be problem because spring beans are a serializable proxies.
I'm using wicket-spring library, and as injector SpringComponentInjector, where wrapInProxies is by default set to true, so I think that proxies should be created, but they aren't.
On the page https://cwiki.apache.org/WICKET/spring.html#Spring-AnnotationbasedApproach is written:
Using annotation-based approach, you
should not worry about
serialization/deserialization of the
injected dependencies as this is
handled automatically, the
dependencies are represented by
serializable proxies
What am I doing wrong?
Do you know how the bean is being injected?
Through component initialization (i.e. a Component and being filled in by the SpringComponentInjector)
Some other object using InjectorHolder.getInjector().inject(this)?
Injected directly by spring (i.e. this is a spring bean where the property is being set by Spring configuration)
Cases 1 and 2 would use wicket-spring integration and would wrap the bean with a wicket proxy which is serializable.
Case 3 would only provide you whatever spring passes to you without wrapping.
First, make sure your bean is really proxied. By default spring does not create proxies.
Second, check your proxying strategy - whether it is proxy-target-class="true" or not. If it is false, (afaik) a reference to your object is stored in the invocation handler of the JDK proxy, and is attempted to be serialized.
So you'll need to make your class Serializable as well, if you need it to be.
Can you double check that the instantiation listener is added in your application class:
addComponentInstantiationListener(new SpringComponentInjector(this));
Also, this only works for fields in Wicket components, not arbitrary classes.
See also wicket #SpringBean can not create bean