Is it possible in spring-ws 2, to get unmarshalled payload for validation with jsr303.
The idea is to have this done for every endpoint that I create without explicitly creating validation code in every endpoint. (for example with an interceptor or some kind of listener)
I tried extending the EndpointInterceptor but, there is no unmarshalled object here.
I also tried implementing Unmarshaller.Listener for the jaxb unmarshaller. Registered this through spring context but there are 2 issues here:
1. It only sets unmarshaller listener while initializing jaxb-marshaller bean.
2. Jaxb Unmarshaller is created on every request and listener is not set during the creation of unmarshaller for that specific request. I dont see a way to inject this on every request.
So is there any other way of achieving this?
Thanks in advance.
As Spring WS endpoints are normal Spring Beans, you can just make use of Spring's AOP functionality and create an aspect for validating the passed objects.
If you're using Spring 3.1 and Hibernate Validator 4.2 as Bean Validation provider you can make also use of Hibernate Validator's method validation feature. Spring provides an interceptor which performs method validation for all beans annotated with #Validated.
if you don't want to use AOP this is the way to go:
You will need to extend the DefaultMethodEndpointAdapter and implment Ordered in an subclass (for example:
DefaultMethodEndpointAdapterWithJSRValidation extends DefaultMethodEndpointAdapter implements Ordered {...)
Make sure that you override following in your subclass:
1.1 In this method you will add your jsr validation stuff:
#Override
public Object[] getMethodArguments ...
1.2 This method makes sure that your bean is used in stead of the default bean.
#Override
public int getOrder() {
return Integer.MIN_VALUE;
}
You can than register you bean in the spring context like this:
<bean id="defaultMethodEndpointAdapter" class="your.package.DefaultMethodEndpointAdapterWithJSRValidation" primary="true"/>"
Have fun.
Related
I'm working on a JSF webapp which purpose is to wrap a command-line program.
One of its main functionality is the ability to share a session between users (eg. for courses purpose), so that when an input is sent to an instance of the application, the output sent to every subscriber for this session.
As a result of this design, the webapp is mainly composed of a view-scoped bean which will request a controller of the command-line application.
It has also been chosen to identify a session with the URL fragment (eg. mydomain/myapp/#SESSIONID), so that anyone using the URL with the same fragment will share inputs and outputs, using its own instance of the view-scoped bean but sharing the same controller
In order to push results to all subscribers, I'm using Primefaces Push. Results are primarily text that has to be appened to the webapp's terminal, but some commands lead to the programmatic creation of a JSF component.
In order to handle this, I just render these components to a string that I send to all subscribers.
Then, I realized that in order to handle ajax requests from components (and from every subscriber), the associated UIComponent needs to be added to the UIViewRoot in the context of (don't know how to express this) each view-scope bean.
As a matter of fact, I first tried to bind a "common container" (a UIForm) to a property of the view scoped bean, in which I would put the programmatically created components, but I obviously had to face the chicken/egg issue #BalusC talks about in his blog, because the component was added again on each ajax request. Setting javax.faces.PARTIAL_STATE_SAVING to false didn't help either (I'm using MyFaces 2.2.5)
So, as somewhat of a workaround, when the controller needs to create a new component, it basically adds the id of the component to the data pushed (in a HashMap converted to Json), and all subscribers will trigger (back) a remoteCommand to its own instance of the view-scoped bean, in order to update the "common container" from its own UIViewRoot.
This does work, but I don't like this way of doing it!
So:
would it be possible to handle this kind of sharing between view-scope beans (with the same name) which are stored in different HTTP sessions? I'm refering to this answer from #BalusC... maybe playing with javax.faces.ViewState - would it even be possible?
Is there a "magical" scope for my currently-view-scoped bean I could use?
Shall I rather use a completely different design?
Thanks!
If you want share data between all your application users you can use application scope.
If you still want to use view scope, you can connect your view scope with another application scope like this:
ApplicationView appView = BeanUtil.findBean("applicationView", FacesContext.getCurrentInstance());
import javax.faces.context.FacesContext;
public class BeanUtil {
#SuppressWarnings("unchecked")
public static <T> T findBean(String beanName, FacesContext context) {
return (T) context.getApplication().evaluateExpressionGet(context,
"#{" + beanName + "}", Object.class);
}
}
I am developing webapp where my MVC controller is JSF 2.1. I have several methods that are based on
FacesContext.getCurrentInstance()
I use this to
put/retrieve values from Flash scope
add messages on view
get request params map
examples:
public void addInfoMessage(String title, String description){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,title, description));
}
and
public void putFlashMessage(String code, String value){
FacesContext.getCurrentInstance().getExternalContext().getFlash().put(code, value);
}
etc.
I'm just wondering where is proper place to put this methods if I use this on every single managed bean? I consider two options:
a) create class "JSFUtils", where all method are public and static
b) create super class "ManagedBean" with no declared scope and no declared #ManagedBean annotation, but with these public methods. Every managed bean should be child of these class so it will have inherited these methods.
An utility class is the recommended approach. Instead of reinventing your own, you can use an existing JSF utility library, such as OmniFaces which has Faces and Messages utility classes for the purpose.
String foo = Faces.getRequestParameter("foo");
Messages.create(summary).detail(detail).add();
Messages.addGlobalInfo(summary); // Without detail.
Faces.setFlashAttribute(key, value);
You can indeed also abstract it away as a "super bean", but this is not reusable and you would keep repeating yourself in every JSF project. Also, a class can extend from only one class. So if your bean happen to need to extend from another super class, then you're lost.
I would recommend a utility class for the purpose simply because you allow the flexibility to extend other useful classes, such as those that have some common logic that you'd like to share across other beans.
Having said that, a JSFUtils class can grow quite cluttered with time with many many methods and can become very unmanageable. It would be better to categorize the util methods and put them in separate static utility classes.
I hesitate to ask yet another question on the same topic, but at least now I'm reading, I think, the right docs.
So, this class:
class FacesContextProducer {
#Produces #RequestScoped FacesContext getFacesContext() {
return FacesContext.getCurrentInstance();
}
}
From the weld docs this method does, in fact, apply to Glassfish through: GlassFish is using WELD as the reference implementation for JSR-299: Java Contexts and Dependency Injection for the Java EE platform (CDI).
For the above class, where would it be used? Why do you need a separate class which #Produces a FacesContext?
For the above class, where would it be used? Why is he trying to inject FacesContext?
I think it is done either for
consistency; or
testing.
ad 1. If one tries to do pure CDI, it looks nice when you're not using other dependency lookup mechanisms (as getCurrentInstace() static method). Note that it is really not needed to define a producer and use injection. It is just convenient and consistent with usage of CDI.
ad 2. is explained by blog McDowell links to, just imagine the injection is done with CDI.
Why do you need a separate class which #Produces a FacesContext?
This does not need to be a separate class, you can have single class producing multiple beans. It just helps the clarity of the code to have it separate.
You might want to inject the FacesContext to avoid direct reliance on the static getCurrentInstance() method to make mocking and unit testing simpler.
I've written a bit about that for JSF's own dependency injection mechanisms here.
I've first seen annotating Seam entity classes here
http://www.developer.com/java/ejb/article.php/10931_3715171_5/Introducing-JBossreg-Seam.htm
and for whatever reason I've been doing so ever since:
#Entity
#Table (name= "GADGET")
#Name("gadget")
public class GadgetBean implements Serializable {
private String mDescription = "";
private String mType = "";
...
}
However, I do not use "entity components" like this anywhere in my views. Can anyone explain the use of this and what this gains? Is it a non-practice?
If you are not using any of these entity components in your views, you should remove the #Name annotation.
Seam is great, but seam components come with overhead in the way of interceptors firing every time you access a method in that class. Since you are not accessing these attributes in your view, there is no need to make them into seam components. You are incurring the interceptor overhead every time you use a getter or setter from your entity beans.
Seam-gen, the tool used to create seam projects, can also generate entities that are reverse-engineered from your database tables. By default, the seam-gen entity generator does NOT add the #Name annotation to these classes. That should tell you something!
Hope this helps.
Hi I have a question about best practices vs safe programming in building a JSF Web Applicaiton.
I have employee.xhtml page having backing Bean - EmployeeBean. All the variables that I declare in the backing bean are non static and have getter and setter methods. For example:
ArrayList <Employee> alEmployees = new ArrayList<Employee>();
int userId;
The constructor of the BackingBean loads the employees. I acheive this by calling a static method in delegate.
userId = //some value.
alEmployees = EmployeeDelegate.loadEmployees(userId);
The Delegate method calls a static method in DAO Class.
Will the static methods cause any data concurrency issues when n users are using the application at same time? I mean userId 56 seeing userId 75 list when both are using the application same time?
Is it really advisable to have static methods in Delegate and DAO layer?
Please let me know if I was not clear.
Thanks
If the EmployeeDelegate does not hold any class variables which is sensitive to changes caused by method calls and/or has influence on how methods behave, then it's safe to do so.
You however have another major problem with this approach. The delegate should be an interface so that you can easily substitute it with a different implementation. This approach suggests that the delegate is not an interface at all (since it can impossibly have static methods).