Pass parameter value from struts2.xml result to jsp - struts2

I have a program in which business logic return some data. that data needs to show on the jsp. i am able to forward to the jsp based on the result but how can i send the return value.
e.g.
public String createuser(String strUser,String strPassword)
{
String strReturnValue="S0000";
try
{
// My code;
}
catch(Exception ex)
{
}
return strReturnValue+"Token";
}
Struts.xml
<action name="RegUser" class="....">
<result name="success">/UIShow.jsp</result>
<result name="error>/UIError.jsp</result>
</action>
in jsp i want to show this token value on success; How can I do this?

You may want to check out the Hello World Struts 2 application because it provides a good example of how to do this.
In your Action class, you can create a String field and appropriate getter method for the token value so that your JSP can retrieve it. In your RegUser action method you will want to assign the field to the result from the business logic, like tokenValue = createUser(user, password);
In your UIShow.jsp you can use a struts 2 tag s:property to display the token value, like <s:property value="tokenValue"/>
Or, since this is just a String, it may be simpler for you to use the addActionMessage method from ActionSupport in your Action class (pass in the String result of the business logic into addActionMessage) and then use the s:actionmessage tag in your JSP to display the token value.

Related

define a message key in <exception-mapping>?

I'm trying to find a way to configure in struts.xml an error message for each type of exception that can be thrown by an Action class. In an action class I could accomplish something similar by catching an exception, calling addActionError(String), and rethrowing the exception (provided an <exception-mapping> exists). Is there a way to do this through configuration?
As a reference point, this functionality exists in Struts1 with the key attribute on an exception handler - I'm hoping to be able to do something similar.
<exception key="some.key"
type="java.io.IOException"
handler="com.yourcorp.ExceptionHandler"/>
In strut2 also you can define exception mappings. Refer http://struts.apache.org/release/2.1.x/docs/exception-configuration.html. You can have a common error.jsp which displays a message that is looked up based on the class name of the exception.
In Struts2 you can use the following mapping to pass on the key/message to result (result can be a jsp or another action class).
<global-exception-mappings>
<exception-mapping exception="com.test.exception.MyCustomException" result="error">
<param name="param">display.custom.error</param>
</exception-mapping>
</global-exception-mappings>
<global-results>
<result name="error" type="chain">handleAction</result>
</global-results>
<action name="handleAction" class="HandleExceptionAction">
<result name="result">/WEB-INF/jsp/error.jsp</result>
</action>
If it an action class, in case of chaining (if the user wants to process the exception) then you need to have a corresponding attribute in Action class with getters and setters.
public class HandleExceptionAction extends ActionSupport implements
ServletRequestAware, SessionAware {
private **String param**;
private HttpServletRequest httpRequest;
private static final Log LOG = LogFactory.getLog(InputAction.class);
public String execute(){
LOG.debug("inside excute().....");
LOG.debug("Parameter passed:" + param);
System.out.println("Parameter passed:" + param);
return "result";
}
I am using spring injection, hope it will hep you.

jsf2.0 - How to get the values in other jsf page's bean in request scope

I have two pages myaccount.xhtml and selectbank.xhtml
In my account page there is one option for recharge account in which user will enter the amount when user will press submit button then it will goto the select bank page using following bean method.
public String gotoPayMethod() {
FacesMessage doneMessage=new FacesMessage("Redirecting to Payment Type Page");
FacesContext.getCurrentInstance().addMessage(null, doneMessage);
return "SelectBank";
}
When user will goto to selectbank there user will have to submit payment method but in this page it shows the amount as null which was entered in the previous page.
Both the pages are using the same bean and the scope of the bean is request scope.
So how can I access that value without passing this values through URL GET method.
Just for my satisfaction I used session scope then it was working but I know thats not the proper way because I start using session scope for each pages then it will not be efficient.
Thanks
Well, if your beans are RequestScoped than you don't have same bean for both pages. These beans are recreated for every request, so you should pass parameters. Change return statement of your gotoPayMethod() to:
return "SelectBank?faces-redirect=true&includeViewParams=true";
and on selectbank.xhtml add:
<f:metadata>
<f:viewParam name="amount" value="#{bean.amount}" />
</f:metadata>
Adapt this to your property and bean name.
If using parameters is not a solution you can add this parameter in the session, and remove it from session in second bean when you retrieve it:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("amount", amount);
((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().removeAttribute("amount");
Second construction for removing the attribute is necessary as Map returned from getSessionMap() is immutable.
You can use the #{flash} object that will keep your data until the next view. This way you won't need to deal with view parameters.
Details from myaccount.xhtml:
<h:form>
<h:outputText value="Enter amount: " />
<h:inputText value="#{flash.amount}" />
<br/>
<h:commandButton value="Go to payment method" action="#{bean.gotoPayMethod}" />
<h:form>
Bean of both views:
#ManagedBean
#RequestScoped
public class Bean {
#ManagedProperty("#{flash}")
private Flash flash;
private int amount = -1;
public Bean () { }
public String getAmount() {
if(amount == -1) {
int val = Integer.parseInt((String)flash.get("amount"));
flash.keep("amount");
amount = val;
}
return amount;
}
public Flash getFlash() {
return flash;
}
public void setFlash(Flash flash) {
this.flash = flash;
}
public String gotoPayMethod() {
//do business job
return "SelectBank?faces-redirect=true";
}
}
Details from selectbank.xhtml:
<h:outputText value="Amount entered by user is #{bean.amount}" />
Your use case is not of simple request/response cycle, the life span is more than one request response which makes it candidate for session scope.
Using hidden variable or GET parameters in URL is not good practice especially for a banking application. Where security is so important dont compromise on small memory foot print.
If flash scope map simplifies the case you can use it, but I would not go for such a thing.
Update: Forgot to mention you can check Conversation scope too.

Can be load and update data in one page using struts 2?

I wonder whether i can use 1 action to load data and update it?
It mean i have a page call about.jsp, manager will click a link to access this page. after redirect into this page, this page load content of about and update content if user edited data but two tasks can be use 1 action.
my i dea is, user use a action call AboutAction to load data to about.jsp page, after end user edited data on about.jsp and click submit, it will send data to AboutAction and update it?
Can i do that? and how?
First thing What you asked is one of the beauty of Struts2
xml :
<action name="AboutAction" class="AboutAction" method="load">
<result>showMe.jsp</result>
<result name="input">about.jsp</result>
</action>
<action name="AboutAction" class="AboutAction" method="update">
<result>showMe.jsp</result>
<result name="input">editsuccess.jsp</result>
</action>
Action :
public String load(){
//logic to load
return SUCCESS;
}
public String update(){
//logic to update
return SUCCESS;
}

Struts 2 : How many times an Interceptor would be called if its configured for one Action class

I have a question with respect to interceptors in Struts2
Struts2 provides very powerful mechanism of controlling a request using Interceptors. Interceptors are responsible for most of the request processing. They are invoked by the controller before and after invoking action, thus they sits between the controller and action. Interceptors performs tasks such as Logging, Validation, File Upload, Double-submit guard etc.
I have taken this above lines from:
http://viralpatel.net/blogs/2009/12/struts2-interceptors-tutorial-with-example.html
In this example you will see how the interceptors are invoked both before and after the execution of the action and how the results are rendered back to the user.
I have taken this above lines from
http://www.vaannila.com/struts-2/struts-2-example/struts-2-interceptors-example-1.html
I have written a basic interceptor and plugged it to my Action class:
public class InterceptorAction implements Interceptor {
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("Action class has been called : ");
return success;
}
}
struts.xml
<action name="login" class="com.DBAction">
<interceptor-ref name="mine"></interceptor-ref>
<result name="success">Welcome.jsp</result>
<result name="error">Login.jsp</result>
</action>
As per the above statements from their sites , i assumed that this line Action class has been called would be two times on the console (That is before the Action and after the Action class ) , but it has been printed only once?
PLease let me know , if my understanding is wrong , or the authors were wrong in that site ??
Not taking the time to read the page lets clear a few things up...
You are missing an important step in your interceptor.
Struts2, uses an object called ActionInvocation to manage calling the interceptors.
Lets give ActionInvocation a name (invocation) and show how the framework starts the ball rolling:
ActionInvocation invocation;
invocation.invoke(); //this is what the framework does... this method then calls the first interceptor in the chain.
Now we know interceptors can do pre-processing and post-processing... but the interface only defines one method to do the work of the interceptor (init and delete are just life cycle)! If the interface defined a doBefore and doAfter it would be easy so there must be some magic, happening...
As it turns out you are responsible for giving control back to action invocation at some point in your interceptor. This is a requirement. If you don't give control back to the ActionInvocation you will break the chain.
So when creating an interceptor you do the following steps
Create a class which implements com.opensymphony.xwork2.interceptor.Interceptor
[optional] do pre-processing work
call ActionInvocations invoke method to carry on processing down the stack and capture the return value.
[optional] do post processing as the above call unwinds.
return the string from step 3 (the result string) unless you have reason to do otherwise.
And here is a complete but pretty useless example:
package com.quaternion.interceptors;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor{
#Override
public void destroy() {
//nothing to do
}
#Override
public void init() {
//nothing to do
}
#Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("Something to do before the action!");
String resultString = invocation.invoke();
System.out.println("Something to do after the action!");
return resultString;
//if you are not doing post processing it is easiest to write
//return invocation.invoke();
}
}

Managed bean property not maintained in the next page by #ManagedProperty

I am new for JSF. In my project am using #ManagedBean, #RequestScoped. Am using 4 pages in my project. My problem was bean values not maintain in the second, third and fourth pages. Am using getter and setter properly. If i not use #ManagedProperty the bean value maintained properly. But i need to use the
#ManagedProperty. Could you please advise me how to solve this issue. I have copied some sample code for reference.
#ManagedBean
#RequestScoped
public class ArticlePrepToolManagedBean implements Runnable, Serializable {
#ManagedProperty (value="#{param.jidName}")
private String jidName;
#ManagedProperty (value="#{param.aidName}")
private String aidName;
private List<com.elsevier.ArticlePrepTool.db.ItemZipContains> usabilityDetailList = null;
public String getAidName() {
return aidName;
}
public void setAidName(String aidName) {
this.aidName = aidName;
}
public String getJidName() {
return jidName;
}
public void setJidName(String jidName) {
this.jidName = jidName;
}
public List<ItemZipContains> getUsabilityDetailList() {
return usabilityDetailList;
}
public void setUsabilityDetailList(List<ItemZipContains> usabilityDetailList) {
ArticlePrepToolManagedBean.usabilityDetailList = usabilityDetailList;
}
}
My project url is (http://localhost:8080/articlepreptool/) but input for my project is jidName=AEA aidName=10663. that input given by some other webpage that is if user trigger using the following href "PrepTool". Depends on the input i fetched some data in my project DB (using JPA) and list out the data in the first page. But if i goes to next page all previous data stored in that list which i got from DB was cleared that is all list values and variables which set in the bean becomes null. So could you please advise me how to solve this issue.That problem occured only if i used the #ManagedProperty. I used #ManagedProperty to fetch the input values comes through url, because the input values of my project comes through other web page.
A #ManagedProperty("#{param.foo}") basically sets the HTTP request parameter with name "foo" as a bean property directly after bean's construction. If you're retrieving null values for them, then it simply means that those parameters are not present in the HTTP request.
Assuming that you're navigating by a plain link, then you need to fix your links to include the request parameters:
<h:link value="Go to page2" outcome="page2">
<f:param name="jidName" value="#{bean.jidName}" />
<f:param name="aidName" value="#{bean.aidName}" />
</h:link>
This will result in something like:
<a href="page2.xhtml?jidName=foo&aidname=bar">
This way those parameters can be set as bean properties.
Alternatively, instead of #ManagedProperty you could also use <f:viewParam> on all pages and add includeViewParams=true to the outcome. See also ViewParam vs #ManagedProperty(value = "#{param.id}")
If you're navigating by a form submit, then there's really no reason to use them. Or you must be abusing forms instead of links for plain vanilla page-to-page navigation.

Resources