Multiple c:imports with Stripes is causing problems - jstl

I'm having a problem when I call the same Stripes action with multiple c:import tags in the same jsp. When I use the first c:import, I use a few c:params with it. These get bound to the corresponding fields in the action. But then when I use the next c:import, the fields are already set from the first c:import, which is not what I want. I want to be able to import an action several times, and each time it should only use the values I pass in with the c:param tags.
The only solution I could think of is to call a method before binding and validation takes place, that sets all the fields to null. Is that a bad idea? What's the best way to handle this?
<c:import url="/widget/House.action">
<c:param name="dogNam" value="Muffin" />
<c:param name="catName" value="Junior" />
</c:import>
<c:import url="/widget/House.action">
<c:param name="dogNam" value="Rocky" />
</c:import>
In this example catName is getting set to "Junior" both the first and second time I use the c:import.

The c:import fires an http request to your Java application server and from what you describe the second c:import still seems to add the catName parameters to the request, you might want to try this:
<c:import url="/widget/House.action">
<c:param name="dogNam" value="Rocky" />
<c:param name="catNam" value="" />
</c:import>

Related

Distinguish between conversion failure and validation failure in o:viewParamValidationFailed

I am using the OmniFaces <o:viewParam> taghandler in my current project. I like it, it's great. And even greater is the <o:viewParamValidationFailed>. Now, we are able to send an error if validation or conversion fails. But I wonder, whether it is possible to distinguish between conversion failure and validation failure.
Let's say we want to send a Bad Request if the given view param in malformed and can not be converted; for that matter send a Not Found if conversion succeeded, but the object could not be found in the database; and send a Forbidden if the successfully fetched object should not be accessed by the user.
Does anybody know a way to achieve this?
It's unfortunately not possible to distinguish between a ConverterException and ValidatorException when you've only UIInput#isValid() at hands. Theoretically, you could check and test the faces message to see if it represents a conversion or validation error, but this is not a robust approach, certainly not when it's localized.
On the other hand, it's possible to declare multiple view parameters on the same parameter name. You do not necessarily need to specify a value to set it as model value.
Here's an example based on your description, note that the model value is only set on the last one:
<o:viewParam name="foo">
<f:converter converterId="yourFooConverter" />
<o:viewParamValidationFailed sendError="400" />
</o:viewParam>
<o:viewParam name="foo">
<f:converter converterId="yourFooConverter" />
<f:validateRequired />
<o:viewParamValidationFailed sendError="404" />
</o:viewParam>
<o:viewParam name="foo" value="#{bean.foo}">
<f:converter converterId="yourFooConverter" />
<f:validateRequired />
<f:validator validatorId="yourRestrictedAccessValidator" />
<o:viewParamValidationFailed sendError="403" />
</o:viewParam>
To avoid the expensive job of calling the DB on every conversion, let the YourFooConverter implementation store the converted value as a custom attribute of the FacesContext and then check it on every pass.

OmniFaces validateOrder disabling

I'm trying to use validateOrder component to validate two java.util.Date objects. It is similar to showcase example on this link (PrimeFaces example). Everything works perfect, but i have one question:
What if 2nd date field is not required?
In that case i'm getting nullpointer exception, and since validateOrder has "disabled" attribute, i was wondering is it worth/possible enabling/disabling it via ajax every time the 2nd date is inserted/removed. If not, i guess i'll stick to Balus' approach for JSF2.0 cross-field validation that you can read about on this link.
Let the disabled attribute check if the 2nd field is filled in. If it's not filled in, the request parameter value associated with field's client ID will be empty. Use exaclty that to let disabled attribute evaluate to true.
<p:calendar ... binding="#{endDate}" />
...
<o:validateOrder ... disabled="#{empty param[endDate.clientId]}" />
Code is as-is. No additional backing bean property necessary for binding.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?

Apache-Shiro: User authenticates within AJAX, how to restore GET-Variables after login?

in my JavaEE-Application, I am using Apache Shiro[1] for user-authentication.
My users are navigating via GET-URLs, as for example "/company/index.xhtml?companyId=327".
I have enabled programmatic login, following a guide[2] from BalusC:
SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(Faces.getRequest());
My problem is, that savedRequest.getRequestUrl() does not contain the previous mentioned GET-parameteres, when my case is asynchronous POST with or without RememberMe; just "/company/index.xhtml" is returned, for example. It seems as if "FacesAjaxAwareUserFilter" (see [2]) is not GET-params aware. Everything works fine on synchronous GET-calls.
How do I get the GET-parameters after an shiro-redirect because of authentication-needed in case of using "FacesAjaxAwareUserFilter"?
[1] https://shiro.apache.org/
[2] Followed this great article about JavaEE and Shiro: http://balusc.blogspot.de/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html
JSF ajax requests are sent to the URL as generated by <h:form>. This is however by default not exactly the current URL including the query string, it's by default the current URI without the query string.
There are several ways to fix this. The simplest but ugliest way is to use JS:
<h:form id="foo">
...
</h:form>
<script>document.getElementById("foo").action += "?" + location.search;</script>
The cleanest way would be to create a custom ViewHandler whose getActionURL() (as used by <h:form>) will return the desired URL with the query string.
JSF utility library OmniFaces has already such a component which does that based on view parameters: the <o:form> which basically extends the <h:form> with support for includeViewParams="true" (exactly the same way as <h:link> does).
<f:metadata>
<f:viewParam name="companyId" value="#{bean.company}" />
</f:metadata>
...
<o:form includeViewParams="true">
...
</o:form>

<ui:param> facelet tag performance

I have a file with large content to display. For example in displaying user profile, every EL expression in <h:outputText/> needs an userId as an argument to bean which is taken from the session context. I declared this userId in xhtml file as
<ui:param name="userId" value="#{currentUser.id}"/>
I am passing this userId to bean methods as
<h:outputText value="#{profile.getAddress(userId)}"/>
<h:outputText value="#{profile.getContact(userId)}"/>
<s:link>
<f:param name="userId" value="#{userId}"/>
</s:link>
I am expectiong the session variable is invoked once for a page. But each time when the userId is processed the sessiion variable is called. Is this the correct behaviour? How to optimize this?
Yes this is the correct behavior. It would be interesting to see which is faster. I would guess it is faster to inject the currentUser in your profile component, and then to retrieve the correct object from there, instead of getting the address and contact by the userId each time. (Depends if you cache it in the component or not).
However, I would try to optimize it by injecting the currentUser in the profile component. That is the standard way of doing it.

how to avoid <spring:url />ing multiple times

I'm working with <spring:url /> because our project is located at domain/ProjectName/mappings/here. I posted about some confusion here: How to use <spring:url /> with an <a> tag? . Now the issue I'm having is because I'm saving the URLS to a database. So I get URLs like domain/ProjectName/ProjectName/mappings/here. How can I avoid this? If spring needs to add ProjectName, shouldn't it be able to check for it's existence first?
From your last comment, yes the spring:url tag does have an option to exclude the contextPath portion of the URL. Just set the context attribute to an empty string:
<spring:url var="mappingLink" context="" value="/mappings/here" />
I'm not sure this will fix your problem though, as it seems unlikely that the spring:url tag is adding the contextPath twice. That seems more likely to be happening somewhere else in your code. Either way this should help you find out.

Resources