1) i have added an element in request object given below, i need to get/read this in my webpage, how can i do it?
<input type="hidden"> wicket:id="submitted" value="false" />
eg: in servlet, use request.getParameter("submitted") from hidden session.
2) in my controller class i want to set the value in session or hidden field, so that i can identify the user if he already processed the request or enetered my block of code.
1) use HiddenField
2) use a custom WebSession object:
public class MySession extends WebSession{
public Mysession(Request request){super(request);}
private boolean completedRegistration;
public boolean hasCompletedRegistration() {
return completedRegistration;
}
public void setCompletedRegistration(boolean completedRegistration) {
this.completedRegistration = completedRegistration;
}
}
I am not sure I have fully understood your questions.
But to make it short, if you want to get the value stored in your request object, you'll need to make the model of your input map to this value (by using HiddenField wicket internal class).
If you want to track your user, the best thing to do is looking around for a cookie set on the client side that'll allow you to manage its visits.
Please refine your question if you want a more precise answer...
Related
Here's the basic requirement:
An http request is received by page A that may have parameters defined.
If parameters are defined, page A processes the request and automatically forwards to page B. If parameters are not defined, display page A with a form for the user to fill in and submit. On submit, process the request and forward to page B.
Basically, I want to bypass the need for the user to enter data via onSubmit() if the data has already been provided as input parameters to page A. How can I do this?
Page A and B are implemented by extending the (deprecated) SimpleFormController. One way I've done this before is to place a "hidden" page (A′) that accepts the request and, if parameters are defined, processes the data and redirects to B. If the parameters are not provided, then I redirect to A where the processing is done.
This doesn't seem efficient to me, as it duplicates a lot of the processing code.
I'm not providing any code, since it doesn't easily explicate the question.
I hope I understand but you want a method in controller that will direct based on information provided.
Here is something i knocked up quickly that i hope will help solve the problem:
#RequestMapping("/pageA/{parameter}")
public String displayPageA(Model model, #PathVariable String parameter) {
if(parameter == null)
{
model.addAttribute("your_form", new YourForm());
return "pageA";
}
else {
return "redirect:/pageB/"+parameter; // this is if you want the parameter passed on
}
}
Lets say I have a Java function something like
public int getNumber(){
}
which returns some value based on it's logic. And I have a JS file something like
Tapestry.Validator.amountValidator = function(field, message) {
field.addValidator(function(value) {
if (value != null) {
// code here
}
}
});
};
Now I am asking myself is it possible in JS or JQuery to pass value from Java function to it's function(value) in JS and if so, how can it be achieved?
UPDATE: As suggested by abalos answer, Tap for myself has already done 3 out of 4 stages for it. I am providing a function that deals with server side and logic behind it.
#InjectComponent
private TextField amount;
#Inject
private FieldValidatorSource fieldValidatorSource;
public FieldValidator<?> getAmountValidator()
{
return fieldValidatorSource.createValidators(amount, "required,max=" + getBroj());
}
Now here validator is taken from a logic inside a function getBroj(), which is maximum number of what it takes. And this works like a charm on server side. Now I was thinking that what I don't have( using my logic ) is only Client side, and I can achieve it by updating current Validation class from Tapestry that will handle with this kind of request yet known to that class. And to do it I would need to call a js file with a function calling something like above in the example, but I am not quite sure how to pass value from getNumber() function to the JS function above.
You don't need Jersey or DWR or any other framework at all for invoking a method in Tapestry. You just need to ask your questions properly.
final private static String EVENT_NAME = "whateverEventNameYouWant";
#Inject
private ComponentResources resources;
#Inject
private JavaScriptSupport javaScriptSupport;
/** Method that will provide the value you want to pass to JS. */
#OnEvent(EVENT_NAME)
public JSONObject provideValue() {
JSONObject object = new JSONObject();
object.put("value", /* the value you want to pass to JS */);
// other values you may want to pass
return object;
}
void afterRender() {
// This creates an URL for the event you created. Requesting it will
// invoke any event handler methods for that event name.
Link link = resources.createEventLink(EVENT_NAME);
javaScriptSupport.addScript("var eventUrl = '%s';", link.); // the JavaScript variable name doesn't matter. You can choose any you want
}
Then, in your JavaScript, do an AJAX request using the URL in the eventUrl variable. I'll leave this part for you to figure out from the jQuery documentation. The received data is exactly the JSONObject or JSONArray you'll return in your event handler method.
I think you have some very heavy misconceptions into what types of languages Java and jQuery/Javascript are. First off, with the exception of node.js, jQuery/Javascript are used for client-side operations. Java is used for server-side operations. This means that you will need to pass a value from the server to the client.
Now, what you are asking for looks initially like it is trying to perform validation. This should not be completed only on the client-side. There are ways to get around client validation and it is best to leave information from the client in an "untrusted" state until it is validated on the server.
With all that said, to do what you are trying to do will require the use of some method for the client to communicate with the server. My favorite way to do this for simple operations is through a web service.
Here are steps to do what you require, but note that this is not the only way.
Create a web service with Jersey.
Pass the value to the web service via AJAX with either JSON or XML with a request that contains the value.
Perform your validation on the server-side with the information from the service.
Pass a response from the rest service back to the client-side AJAX call and use it for your JS/jQuery code.
Let me know if you have any questions.
I am creating a wizard-like interface consisting of 3 jsp pages and 3 Struts actions using Struts 1.3. The flow is like below:
page1>action1 ->page2>action2 -> page3>action3
I use a session form bean (an action form with session scope) to share data between requests. The problem I am having is that the data I submitted in page2 is available in action 2, but not in action 3. I am in doubt it might be I don't have a form on page3 to hold those data, or because I call action3 via jQuery post method instead of a regular form submit, but I am really not sure.
I have been digging all the internet for almost a day and still no luck. Could anyone offer some help. Thanks a lot.
The reset() method on the form is being called with each request and thus you are losing state. You can programmatically control this.
public class MyForm extends ActionForm {
boolean reset = true;
private String[] checkboxes = {};
#Override
public void reset(ActionMapping mapping, HttpServletRequest request) {
if (reset) {
this.checkboxes = new String[];
// etc
}
reset = true;
}
public void doNotReset() {
reset = false;
}
}
Have action2 call doNotReset() on the form.
I suppose that you might have assigned a same form to both the action in StrutsConfig.xml and hence it is not giving the ClassCastException. By the way, if you want to access the same form bean which was filled on action 2 stuff, do the following
Look at the strutsConfig file for actionMapping of both the actions (2 and 3). keep the name of form different for separate action (e.g. form2 for action2 and form3 for action3).
In Action3, instead of casting the form, use this form2 = (FormBean2) session.getAttribute("form2");
The reason for above is since both the actions are using the same form, struts might have overwriting it. Hopefully above will solve your problem.
Thank you for all your inputs. Here is how I solved my problem. I don't really like this solution, but it possibly the neatest one I can find.
In page 3 I added hidden fields for what ever property I want to be available in action 3. Struts will store the values in those hidden field and when the form is submitted again, the data will then re-populated to the action form.
It seems to me that Struts works like this: when it loads page 3, it try to populate the form in page 3 with values of myForm. When the form is submitted, the process is reversed, it populate myForm with values from the user's form. The problem is that, before populating myForm with values submitted by user, it resets myForm's properties. And because after reseting, it doesn't find the value for those fields, it leaves it empty.
I don't think it makes sense for Struts to work that way, but... so be it.
How are you accessing the form bean of page2 in action2 as well as in action3.
I suppose you are accessing the wrong way. Are you getting an exception regarding invalidCast or something.
I'm working on converting a legacy project to Spring (trying to adjust little as possible for now) and I'm running into a small issue with mapping/translating legacy parameters to a model attribute object. I may be completely wrong in thinking about this problem but it appears to me that to translate a parameter to a specific model attribute setter is to pass in the request parameter through a method for creating a model attribute and manually call the correct setter:
#ModelAttribute("form")
public MyForm createMyForm(#RequestParameter("legacy-param") legacy) {
MyForm myForm = new MyForm();
myForm.setNewParam(legacy);
return myForm;
}
I don't necessarily want to change the request parameter name yet since some javascript and JSPs are depending on it being named that way but is there any way to do something like this? Or is there a different way to map/translate request parameters to model attributes?
public class MyForm {
#ParameterName("legacy-param")
private String newParam;
public void setNewParam(String value) { ... }
public String getNewParam() { ... }
}
#Controller
public class MyController {
#RequestMapping("/a/url")
public String myMethod(#ModelAttribute("form") MyForm myForm, BindingResult result) { ... }
}
The way you've written that model attribute method is indeed odd. I'm not entirely clear what you're actually trying to do.Assuming there are many parameters, you're going to end up with an awful lot of instances of MyForm in your ModelMap. A more 'normal' way to create model attribute would be like this:
#ModelAttribute("legacyParamNotCamel")
public MyForm createMyForm(#RequestParameter("legacy-param-not-camel") String legacy) {
return legacy;
}
Then in the JSP you can refer to it directly in expression language. e.g.,
<c:out value="${legacyParamNotCamel}"/>
If you want to put them onto a form backing object, you need to do it all in a single method that creates the object, not make new copies of it in each method. (assuming your form has more than a single parameter associated with it.)
--
It seems like what you're really trying to do though is translate the parameter names in the request before the web data binder gets ahold of it, so that you can bind oddly named parameters onto a java bean? For that you'll need to use an interceptor that translates the names before the binding process begins, or make your own subclass of the databinder than can take a property name translation map.
You placed the #ModelAttribute at the Method Level but the intention seems to be more of a formBackingObject hence we should be dealing at the Method Parameter Level
There's a difference.
I put up an explanation here on my blog along examples at Spring 3 MVC: Using #ModelAttribute in Your JSPs at http://krams915.blogspot.com/2010/12/spring-3-mvc-using-modelattribute-in.html
I have to warn you: the question may be rather silly, but I can't seem to wrap my head around it right now.
I have two managed beans, let's say A and B:
class A
{
private Date d8; // ...getters & setters
public String search()
{
// search by d8
}
}
class B
{
private Date d9; //...getters & setters
public String insert()
{
// insert a new item for date d9
}
}
and then I have two JSP pages, pageA.jsp (the search page) and pageB.jsp (the input page).
What I would like to do is placing a commandbutton in pageB so to open the search page pageA passing the parameter d9 somehow, or navigating to pageA directly after b.insert(). What I would like to do is showing the search result after the insertion.
Maybe it's just that I can't see the clear, simple solution, but I'd like to know what the best practice might be here, also...
I though of these possible solutions:
including **A** in **B** and linking the command button with **b.a.search**
passing **d9** as a **hiddenInput** and adding a new method **searchFromB** in **A** (ugly!)
collapsing the two beans into one
JSF 1.1/1.2 raw doesn't provide an easy way to do this. Seam/Spring both have ways around this and there are a couple of things you can do. JSF 2 should also have solutions to this once it is released.
Probably the easiest and most expedient would be to collapse the two beans into one and make it session scoped. The worry, of course, is that this bean will not get removed and stay in session until the session times out. Yay Memory leaks!
The other solution would be to pass the date on as a GET parameter. For instance, you action method could call the
FacesContext.getCurrentInstance().getExternalContext().redirect("pageB?d9=" + convertDateToLong(d9));
and then get the parameter on the other side.
You should configure the navigation flow in faces-config.xml. In ideal scenario you would return a "status" message which would decide the flow. Read more at following link:
http://www.horstmann.com/corejsf/faces-config.html
http://publib.boulder.ibm.com/infocenter/rtnlhelp/v6r0m0/index.jsp?topic=/com.businessobjects.integration.eclipse.doc.devtools/developer/JSF_Walkthrough8.html
As far as passing the values from one page to another is concerned you can use backing beans. More about backing beans here:
http://www.netbeans.org/kb/articles/jAstrologer-intro.html
http://www.coderanch.com/t/214065/JSF/java/backing-beans-vs-managed-beans
Hope i have understood and answered correctly to your question
Way to share values between beans
FacesContext facesContext = FacesContext.getCurrentInstance();
Application app = facesContext.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesContext.getELContext();
ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
return valueExp.getValue(elContext);
In above code "expression" would be something like #{xyzBean.beanProperty}
Since JSF uses singleton instances, you should be able to access the values from other beans. If you find more details on this technique, I am sure you'll get what you are looking for.
Add commandButton action attribute referencing to B'insert method
<h:commandLink action="#{b.insert}" value="insert"/>
In B'insert method,add d9 parameter as request parameter. Then return an arbitrary string from insert method.
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getRequestMap().put("d9", d9);
Then go to faces context and add navigation from B to A with "from-outcome" as the arbitrary String you returned from insert method. But don't add redirect tag to navigation tags as it will destroy the request coming from B and the parameter you added (d9) will be cleared.
<from-outcome>return string of insert method</from-outcome>
<to-view-id>address of A</to-view-id>
Then you might get the "d9" in A class by fetching it from request map at its constructor or in a place where its more appropriate (getters). You might add it into a session scope or place it to a hidden variable if you want to keep track of it later.
in class A, when page is navigated, A should be initialized as it will be referenced.
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getRequestMap().get("d9", d9);
Sorry i cant give full code, as i have no ide at here, its internet machine at work. I could not give details therefore.
In my opinion, the simplest way is 3-rd option - have both query and insert methods in same class. And you can do something like that:
public String query () {
//...
}
public String Insert() {
//insert
return Query(); }
If your classes are managed Beans you can load class A from class B and call A.query() in your insert method at the end. Also class A can have
<managed-bean-scope>session</managed-bean-scope>
parameter in faces-config.xml and it wouldn't be instantiated again when loaded.