Struts2: Get id from request prior to getModel() call - struts2

I encountered the problem after upgrading Struts2 to 2.3.15 from 2.3.1
In my action I use ModelDriven Interface to populate a bean. In request I also pass parameter id that identifies object in the session. Id parameter is not part of the bean. To populate id field in action prior to getModel() I used "params" interceptor in front of other interceptors.
In Struts 2.3.15 I get lots of errors from ParametersInterceptor - no setter could be found. It throws errors for all fields that supposed to set my bean fields.
What is the right way to handle such situation?

Related

Why JSP doesn't throw error for non-mapped fields in Struts 2

I've my Struts 2 actions as ModelDriven. I've some fields defined on the actions themselves as well. However, if in the JSP I use wrong field names that are neither in ModelDriven model nor directly used as action member fields then I don't get any errors and it simply ignores those fields.
<s:if test="(method == 'list')">
If method is neither a ModelDriven model field nor an action member field then it simply ignores this s:if statement and doesn't execute instructions inside this s:if statement.
Any idea on how to throw errors on JSP for fields that are non-mapped in the ModelDriven models fields or in the actions of ModelDriven models?
OGNL expressions can throw exceptions but they are caught internally.
The OGNL expression is evaluated in this attribute, like in many other
attributes of Struts tags, and if can't resolve the value it returns
null. This value is unacceptable for the if tag.
However, if you know which expression returns null then create a boolean expression.
Any idea on how to throw errors on jsp...
The java code is encapsulated in the tags implementation. If tags cannot execute they throw 500 internal server error. You can write your custom tags to throw that errors.

What is the role of the action mapper in Struts 2?

Can somebody explain the role of the Action Mapper in Struts 2?
The role of ActionMapper interface in Struts2 framework is to extract mapping from the request's URL.
When given an HttpServletRequest, the ActionMapper may return null if no action invocation request matches, or it may return an ActionMapping class that describes an action invocation for the framework to try.
You can read more about this feature here.
Th first method returns a mapping to try, it doesn't guarantee that this action will be executed.
The ActionMapping returned by the action mapper contains all necessary information to invoke an action if there's an action config corresponding to this mapping is available in runtime configuration.
Different implementation of this interface can be used to override the default behavior for mapping URLs to actions in Struts2.

CDI bean List in datatable is null on submit from JSF

Please note: This question is about CDI scopes as we are using CDI scopes in the app and not JSF scopes.
1) Controller Bean (TestController.java) which is in RequestScoped (enterprise context) is called index_cut.xhtml, when we come for first time on this page.
2) On button “Load”, we load the following method to populate the sapFinancialPeriodList which works fine and displays the data
3) After changing the content on the page and submitting, the sapFinancialPeriodList appears as NULL in the following method –
Any suggestions?
Your bean is request scoped and you're loading the data model on action only instead of on (post)construction. When the HTTP response after the action which loaded the data is finished, then the bean is garbaged. The subsequent request would get a brand new instance of the bean with all properties set to default. However, as the same data model isn't been preserved during (post)construct, it remains empty.
In JSF2 you'd solve this with using #ViewScoped. This way the bean will live as long as you're interacting with the same view by postbacks (which return null or void).
In CDI you'd need to solve this using #ConversationScoped, which in turn requires some additional #Inject Conversation boilerplate, complete with begin() and end() calls at the right moments. For a concrete example, see also What scope to use in JSF 2.0 for Wizard pattern?.
An alternative is to pass the parameters responsible for creating the data model to the subsequent request via <f:param> in the command link/button as follows
<h:commandButton value="save" ...>
<f:param name="period" value="#{bean.period}" />
</h:commandButton>
and then recreate exactly the same data model in (post)constructor of the request scoped bean as follows
String period = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("period");
List<SapFinancialPeriod> sapFinancialPeriodList = someservice.list(period);
(the above is by the way nicer to solve with #ManagedProperty if you were using standard JSF; as far as I know CDI doesn't have an annotation which enables you to set a HTTP request parameter as a bean property)
See also:
How to choose the right bean scope?
Unrelated to the concrete problem, the upcoming JSF 2.2 solves this functional requirement in a nicer way using the new "Faces Flow" feature with the new #FlowScoped annotation and the new xmlns:j="http://java.sun.com/jsf/flow" tags.

Maintaining values of action variables in between different requests

I am struts2 for developing my application.
Sample code of action class would be
class sampleAction extends Action {
private List<Employee> employee;
public validate(){
--logic for validation
}
public String prepopulate(){
--logic for populating value of employee list
}
--getters and setters
}
Now my problem is on page load i call prepopulate function and populate the value of employee list. After page submit validate method is called and during that if some error happens control redirects to jsp. but this time the value of employee list is empty. I am using this list for autocompleter tag in struts2.
I have never used Struts 2 built-in validation mechanism, as I prefer client-side validation to avoid an extra round trip. This is purely a personal choice and not a standard.
First I will suggest you not to use Action and use ActionSupport: ActionSupport provides a lot of functionality out of the box and you need not to do everything yourself.
I am assuming that you are using defaultStack and if this is the case than it provides out of the box Prepare Interceptor which takes care of preparing any values before the action itself is called.
In your case, validate is called before the execute method, so you never will get a chance to re-fill the values you need in your JSP.
All you need to make sure that you have prepare() method in your action class. Here are more details for this interceptor:
Prepare Interceptor
FAQ: How do we repopulate controls when validation fails

Pass request parameters through FacesContext

I moved from JSF 1.2 to JSF 2.0 and it seems I missed something during the switch. I have following scenario:
There is a button on one page with actionListener set to one managed bean's method which adds an object to request by calling FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("foo", fooObject);
Navigation is properly handled to other page where other managed bean is initialized.
The constructor of other managed bean tries to retrieve passed object from request by calling FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("foo"); and to initialize itself with received values.
Both managed beans are request scoped. I notice that constructor can't retrieve proper value from request because request map doesn't contain "foo" key.
What am I doing wrong? Is there a better way to do this?
Thanks in advance.
In step 2, if there is a redirect the initial request scope is lost as the redirect would result in another request.

Resources