I have a struts action flow(struts-1.x framework), which, when executes, the action class ActionFlowActionUnit1.java sets a String variable varName to request using the code
request.setAttribute("varNameFromRequest", varName);
and the flow finally leads to the loading of a jsp Page1.jsp.
Now, Page1.jsp contains a button, which, when clicked, initiates a new struts action flow, which has the action class ActionFlowActionUnit2.java. In this class, I want to use the varName which I had set in request using request.getAttribute().
How can I do it WITHOUT USING SESSION?
Technically, I'm not sure if achieving this using requestis possible, because, triggering a new struts-action will lose all other information in the request that was previously set (if I'm correct).
I couldn't get anything from Google.
As you say, it is not feasible technically as you want it (every http request from the browser creates a new HttpServletRequest object)
You have 2 options:
Using the Session, which you want to avoid as far as I understand
Bring back and forth some parameter into every successive request with the value you would like to keep.
The second option would mean to store some parameter inside your Page1.jsp <form> with the variable you need your second action to receive, and then rinse and repeat. This is a pure html form solution.
If you are implementing a complex flow, this looks a fair case to have a look at Spring Webflow. There you can manage flow-level variables, which are stored at a "different" scope than request or session, and looks exactly what you want.
http://projects.spring.io/spring-webflow/
Related
I have RESTful app which reacts on GET request and I need to store the state.
For example
localhost/subs?search=John
Then I need to add other parameter division by clicking button.
localhost/subs?search=John&division=develop
Meanwhile the data output will be distributed on pages. And appear new 2 parameters size and page.
localhost/subs?search=John&division=develop&size=5&page=0
In this situation when I click on next page button my url is resetting.
I’m really confused. How to save state and if parameter is already has in url then it should be changed for new value, if parameter doesn’t exist then append it.
If there good options?
At least I can use JavaScript by taking it and parsing url.
But I think it’s not good at all.
As I know, the RestAPI doesn't save any request parameters (Maybe you can do by adding them into a session attribute, but it's just made the logic code become more complex).
At least I can use JavaScript by taking it and parsing URL
Yes, I think you should.
Happy coding!
I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
It seems like JSF has been around for long enough that there must be a clean, solid way to deal with this. If so, would you mind sharing?
I have found various workarounds, but sadly nothing that seems like a real solid solution.
Simply accept that the URL is misleading.
Append "?faces-redirect=true" to the return value of every bean's action and then
figure out how to replace #RequestScoped with something else (Flash Scopes, CDI conversation, #SessionScoped, ...).
accept to have two HTTP round trips for every user action.
Use some method (e.g. 3rd party library or custom code) to hide the page name in the URL, always using the same generic URL for every page.
If "?faces-redirect=true" is as good as it gets, is there a way do configure an entire application to treat all requests this way?
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the <h:form> is been requested form. You can confirm it by looking at the <form action> URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use <a>, <form>, <h:link> or <h:button> instead of <h:form> and <h:commandXxx>).
For example, page-to-page navigation, Google-like search form, etc.
If the request is non-idempotent, just show results conditionally in the same view (i.e. return null or void from action method and make use of e.g. <h:message(s)> and/or rendered).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.
If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with ?faces-redirect=true from action method, or manually invoke ExternalContext#redirect(), or put <redirect/> in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
See also:
What is the difference between redirect and navigation/forward and when to use what?
JSF implicit vs. explicit navigation
What URL to use to link / navigate to other JSF pages
Bookmarkability via View Parameters feature
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
When should I use h:outputLink instead of h:commandLink?
Creating master-detail pages for entities, how to link them and which bean scope to choose
Retaining GET request query string parameters on JSF form submit
Pass an object between #ViewScoped beans without using GET params
I have a JSP page which passes the HttpServletRequest and HttpServletResponse to a Java class which dispatches the request and response to an action class based upon a parameter named "action". The action class performs some action and sometimes forwards to another JSP where the same procedure is repeated. If your thinking I should use a servlet, your right, but that is a long story and basically I don't have the authority too.
In one of my action classes, I validate the data and if valid, forward the request to another JSP, using the RequestDispatcher. I also tried to set the "action" attribute so that I could tell the other JSP what action to perform, however I learned that attributes are not forwarded with the request. In fact, my code started infinitely looping because I was performing the same action due to the action parameter not changing, which resulted in the request looping between action and jsp.
I found out I could override the action parameter by passing the parameter in the url of the new page. Like so:
RequestDispatcher dispatcher = request.getRequestDispatcher("someUrl.jsp?action=SOME_OTHER_ACTION");
dispatcher.forward(request, response");
This solution smells fishy to me. Can anyone provide any insight into whether this is a good idea?
Yes, that is the only way to send request parameters while forwarding.
As you found out, request attributes are just a convenient place for filters or other request handlers to add objects to the request object. They are quite distinct from parameters which come from the HTTP request itself. Attributes are not passed to the HTTP client, and are gone once the response has been sent.
There's nothing fishy about your approach. An alternative (probably worse) approach would be to maintain the state using a session.
I think it is one of the valid way to pass the parameters.
Other way may be, you have access to request object, you can set it as request attributes. forward is on server and you should be able to access the same request attribute on other end.
Let's say I have five or more input computers that can affect whether a single drop down menu is displayed. The issue I am running into is that if the drop down menu is displayed once (thus setting the value in the backing bean through ajax) and the user then changes one of the affecting input components, then the backing bean value of the drop down menu is not getting reset when the drop down goes into hiding using the rendered property. For example:
<h:selectOneMenu id="sampleDropDown" required="false" immediate="true"
onchange="jsUpdateSampleDropDownValue()" value="#{backingBean.value}"
rendered="#{backingBean.shouldShowSampleDropDown}"
actionListener="#{backingBean.listener}" />
I understand that I have options here. I've debated whether I should add a generic ValueChangeListener (apply request values phase) or an EventHandler (render response phase) that would listen in on the values of the other inputs and make a decision on whether to clear the drop down menu value but this certainly is more work then just letting the rendered property make that decision.
We've seen dozens of the same type of issue on the project I'm currently on and I'd really like to hear from the experts on the best practice for handling this type of situation. In case it matters we are using custom ajax (not ajax4jsf) and jsf 1.1. Any help is appreciated.
The solution I came up with is to not try and reset the input component in the backing bean value of the renderered property.
I have a phase listener attached to the single page interface and am essentially passing request parameters in the javascript method (i.e. jsUpdateSampleDropDownValue()) so that business logic data can be loaded in the rendered response phase using the chain of responsibility pattern.
When a request parameter is passed (i.e. RESET_SAMPLE_DROP_DOWN) onchange that matches a corresponding event handler (i.e. ResetSampleDropDownEventHandler), I check a separate "constraint" class (see Hardcore Java book) that validates whether enough data is accumulated before either clearing the binding value or continuing with the request.
This allows the logic to be centralized yet be attached to multiple components. You may be asking why a single JSF ValueChangeListener was not attached to each component which would allow the same re-use. The reason for this is because our business logic takes place in the render response phase after the update model phase so it makes sence that any "reset" type methods occur after any "defaulting" of values.
I am using a MVC framework which is a bit like struts.
So, say I have a "Edit Store" link in my application this is how the url would look like:
http://localhost:9080/test?action=editStore&storeNum=10
Now, action determines my Action (analogous to Struts Action) to be run. The corresponding action here is: EditStoreAction. Clicking this would open a pop up with different attributes of a store for edit.
My question here is:
How do I write my actions? Do I write two actions in this context?
EditStoreAction which will render
edit.jsp
StoreSaveAction which
will invoked when user presses
accept on the rendered response of
edit.jsp.
OR Do I just write one action? EditStoreAction and submit form to the same action, I would know that the user has pressed the accept button for changes on submission. So, I would execute a different flow in the Action, which would save updates to database and redirect to a diff page.
What is the best pratice here? Create as many actions as possible coz it keeps the code modular? OR just write one action to handle everthing in a jsp?
I know this question sounds a bit trivial, however, sometimes you just want to get everything right. Hence, the question. Appreciate your help.
The idea is, similar to Spring MVC, to map your actions to the methods of a specific class, say it controller.
So, in your case, these two actions will be mapped on two different methods of the same class. You can call the class StoreFormController and two methods, editStore() and saveStore().
Better still if you make two controllers for each entity. May be one for all GET requests and another is for POST requests. So, in your case there would be two controllers StoreController for all other requests and StoreFormController for all form submissions, namely post requests. Now, your first action being GET will go to editStore() method of StoreController, whereas the second being POST request will go to saveStore() method of StoreFormController. You can define as many methods as needed in any of these two classes based on the request type.
You can easily see, where I am coming from, if you know Spring MVC API.
I like to use struts DispatchAction class because I could define more than one method in the action class (the "execute") method. Behind the hood, all it does is to find the method that it has to execute (submitted in the form or passed in the URL), find the method using reflection, invoke it with the right set of arguments (the method must have the same signature of the "execute" method), gets it result and pass it along. The DispatchAction simply overrides the "execute" method of the Action class to implement that behavior.
That being said, in your case, I would define only one class - let's say "DispatchStoreAction", and I would define two methods, probably "prepare" and "save". I like doing it that way because I still have a good class abstraction (and you don't put the "action" you're executing in the class name), because your methods can clearly identify what they are supposed to do, and also because, by definition, action classes tend to be small. You will probably have a "StoreLogic" or "StoreBusiness" defined somewhere, and this class will handle the business logic related to the entity that you're working on. I personally think that it's nice if you have one "StoreAction" and then one "StoreLogic", one "UserAction" and one "UserLogic" and so on - the relationship doesn't need to be 1 to 1 but I think it helps maintaining the code.
Check the source code of the DispatchAction class for ideas on how to do this, but the implementation should be trivial.