Back in the day (well, more like several months ago) I developed an admittedly bad Seam
app to replace a part of a website originally written in struts/jsp. Due to the somewhat
limited nature of struts, I found myself heavily relying on @RequestParameter to allow me
to pass values to the Seam part of the application from the traditional JSP portion.
Fast forward to now, lots of great improvements to Seam. In many ways, it makes my code
from before seem so bad it's scary. One problem in particular (handling requests made
directly to a view that required the user to be logged in) has been greatly simplified
with the addition of Seam security. However, I'm running into a problem.
I have a page that's a simple JSP that represents some search results. The search
results are enclosed in an HTML form to allow mass updates on the search results (in this
particular case, the user is allowed to bookmark items from the search results... kinda
like adding items to a shopping cart or wish list). So what I've done is have the page
submit to a JSF view that has a page action associated with it that will capture the users
bookmarks. I'm also using features from Seam security to redirect the user to the
login page if they're not logged in, and then return them to this bookmark view so
that the page action will continue to save their bookmarks.
However, this results in a problem as in order to have Seam remember the request
parameters from the form submission, I have to have the parameters defined as part of the
page using the tag in pages.xml. Unfortunantly for me, the Param class in Seam that
handles these parameters doesn't accept multi-valued request parameters (it throws an
IllegalArgumentException).
I'm not allowed to convert this page to Seam or Faces/Facelets. That being the case,
I've decided to take a look at the Param class from Seam and see how difficult it
would be to change it to allow for multi-valued request parameters. I've since made
some slight modifications that seem to work, but I'd like the community to review it
and give me some suggestions for improvement. The code I've changed is as follows...
from org.jboss.seam.pages.Param
| /**
| * Get the current value of a page parameter from the request parameters
| */
| public Object getValueFromRequest(FacesContext facesContext, Map<String,
String[]> requestParameters)
| {
| String[] parameterValues = requestParameters.get( getName() );
| if (parameterValues==null || parameterValues.length==0)
| {
| return null;
| }
| Converter converter = null;
| try
| {
| converter = getConverter();
| }
| catch (RuntimeException re)
| {
| // YUCK! due to bad JSF/MyFaces error handling
| return null;
| }
|
| Class<?> methodType = valueBinding.getType();
| if (methodType.isAssignableFrom(Collection.class))
| {
| List retVal = new ArrayList();
| if(converter != null)
| {
| for(String parameterValue: parameterValues)
| {
| Object convertedValue = converter.getAsObject(facesContext,
facesContext.getViewRoot(), parameterValue);
| retVal.add(convertedValue);
| }
| }
| else
| {
| throw new RuntimeException("You must specify a converter for bean
properties that are a collection.");
| }
|
| try
| {
| return methodType.cast(retVal);
| }
| catch (Exception e)
| {
| throw new RuntimeException(e);
| }
| }
|
| if(parameterValues.length > 1 &&
!(methodType.isAssignableFrom(Collection.class)))
| {
| throw new RuntimeException("Request parameter was multi-valued and bean
property doesn't support collection interface.");
| }
|
| String stringValue = parameterValues[0];
| return converter==null ?
| stringValue :
| converter.getAsObject( facesContext, facesContext.getViewRoot(),
stringValue );
| }
|
Basically, I've changed the method to see if the value binding associated with this
parameter is expecting a list or other form of collection. There doesn't seem to be a
way to find the generic type of a particular collection (i.e if you have a List there
doesn't seem to be a way to find out that this list only accepts String values), so
I'm forcing the specification of a converter for value bindings that are expecting a
collection. I then iterate through the array of request parameter values and convert each
one and place it into a collection. Then I convert the collection to the type expected by
the value binding.
This method certainly has it's flaws, which is why I'm posting it out here.
I'm hoping I can refine this code into something worthy of a patch.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4042468#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...