The form is being submitted twice:
1. On Page Load
2. When user clicks on Checkout's button
I want to avoid the first submission, it is throwing an error because the token returned is null:
com.stripe.exception.InvalidRequestException: Invalid source object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'; request-id: req_DjRbT4rGULYGnB
Following the documentation I added the following code to my XHTML:
<div>
<form submit="#{studentBean.chargeStudent()}" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_test_xxxxxx"
data-amount="111"
data-name="myApp"
data-description="Example charge"
data-zip-code="true"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto">
</script>
</form>
</div>
Here is my Managed Bean's function:
#Named
#ViewScoped
public class StudentBean implements Serializable {
#EJB
StripeChargeLogic stripeChargeLogic;
public void chargeStudent(){
Map<String,String> requestParams = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
logger.info("charge:" + requestParams.get("stripeToken"));
stripeChargeLogic.chargeStudent(requestParams.get("stripeToken"));
}
}
Can someone please guide me why the form is being submitted twice and how I can prevent the submission during page load Thank you!
You are not doing jsf here, you have plain html, most likely (but mot clear from you post) in an xhtml/facelets file but not JSF.
In your form action you have an EL that, since it all is in no way related to jsf, is called on page load, sort of like what hapens here
The rest of the behaviour is even more 'undefined' because of this. Take a step back and learn the basics of web technology and jsf and then look at your problem again
Related
I am using Spring/SpringMVC 5.x version, with Thymeleaf and Bootstrap on Tomcat server.
I need to ask something that maybe it might look to you very "st#pid" question.
In my html view I have the following button or a link:
<input type="button" .../>
<a .../>
I don't need to submit something, so I just use a simple button, so I think I don't need any form for it (except if I need for this).
In this html view (because of the thymeleaf library I added in the html tag), I need to add somehow,
(but I don't know how), to this button or in the link, an expression of Spring EL or Thymeleaf EL, so I can invoke a method from a
Spring bean, that I passed in the view, via a model which I added in my controller, e.g.:
${myBean.doSomething()
// or
${myBean.doSomething(parameters)
If this is not understandable I can update my question with some code (I believe that Spring developers
understand what I am talking about).
I don't know how to pass this expression. What attribute of button or link tag to use?
I used "action" attribute for the button:
<input type="button" th:action="${myBean.doSomething()".../>
or "href" attribute in the link tag:
<a th:href= "${myBean.getStringUrlAndDoSomething()"/>
Very significant info
When I started my tomcat running the page, the actions in the EL are run successfuly on the load of the page. When I pressed the button or the link nothing happened.
I know that I cannot use "onclick" attribute because there we write JS code.
But I need to run Java Spring code.
Any ideas about solving my problem?
Thanks in advance
I followed the advice of the #M.Deinum, #Wim Deblauwe, and I did not use
a button for this job. Button needs a form to work.
That is why I used a link, where the method from the bean is called like a charm, like
the following snippet:
<div class="blabla">
<div class="blablabla" th:text="|#{change_lang} EN/GR:|"></div>
<a class="bla" th:href="${localeService.switchLocale()}">
<div th:class="|${localeService.loadCss()}_blabla|"></div>
</a>
<span th:text="${#locale.getLanguage()}"></span>
</div>
And next is a snippet from the bean:
public String switchLocale() {
locale = LocaleContextHolder.getLocale();
if (locale.getLanguage().equals("en")) {
LocaleContextHolder.setLocale(EN_LOCALE);
return "?lang=el";
} else if (locale.getLanguage().equals("el")) {
LocaleContextHolder.setLocale(GR_LOCALE);
return "?lang=en";
} else {
return "";
}
}
So, the code from the bean IS invoked successfuly. I guess this is the solution to my issue.
Thanks a lot from the 2 people #M.Deinum, #Wim Deblauwe, who advised me.
i'm currently woking on a spring mvc project. I have a page with a form, which represents a configurator.
The user can choose some data in a bunch of select fields and proceeds to the next step, where he gets the same jsp-page but with some more fields, depending on his inputs he made. This will be repeated a few times until he gets his result on another page. Each time a POST will be performed.
Now if the user uses the back function of the Browser he doesn't get to the previous page, but to a browser default "broken page", where Chrome for example says something like "Please confirm resubmission of the form data...". To actually resubmit the data he has to press reload and confirm a popup.
The resubmission itself isn't really a problem, because the data does not get inconsistent, it just performs another call to the backend and receives the data it provides.
The real no-go is the fact that the user has to manually refresh the page and by chance gets confused by the default browser page.
I did some research and found out, that the PRG (Post-Redirect-Get) Pattern might solve this problem.
In fact i can now navigate through the browser or reload the page and does not get the popup or broken page - because it's now a GET request of course.
The problem now is, that if i navigate back, the last page does not contain the data it contained before, but is now empty because no data at all is existing.
I understand that it is now a GET request and no data gets posted, but i thought the previous page would be "reused", like shown here.
Now with the PRG-Pattern the handling of the application is even worse, because if the user reloads or navigates back, he basically has to start from scratch.
Did i misunderstood the meaning of this Pattern?
A quick look into some code, how i implemented this:
#PostMapping("/config")
public String handlePostRequestConfig(RedirectAttributes redirectAttributes, ProductForm productForm){
//Handle productForm and add additional content to it
if(noMoreStepsLeft){
return "redirect:/result";
}
redirectAttributes.addFlashAttribute("form", productForm);
return "redirect:/config";
}
#GetMapping("/config")
public String handleGetRequestConfig(Model model, #ModelAttribute("form") ProductForm productForm{
model.addAttribute("form", productForm);
return getJsp("product");
}
Inside JSP:
<form method="post" action="/config">
<c:foreach items="${form.selectFields}" var="selectField">
<input...>
</c:foreach>
<button type="submit">Submit</button>
</form>
In PRG, P is not the first step of user action flow. PRG is a part of the full flow.
The following shows a flow and how PRG fits in it:
User will hit a URL. For example: http://localhost:8080/myContextPath/config.
This will be handled using a GET handler:
#GetMapping("/config")
public String show(ModelMap model) {
// code
model.put("form", productForm);
return "product"; // returning view name which will be resolved by a view resolver
}
product.jsp:
<form commandName="form" method="post">
<c:foreach items="${form.selectFields}" var="selectField">
<input...>
</c:foreach>
<input type="submit" value="Submit"/>
</form>
This submit action will be handled by a POST handler:
#PostMapping("/config")
public String submit(#ModelAttribute("form") ProductForm productForm,
RedirectAttributes redirectAttributes){
// code, may be service calls, db actions etc
return "redirect:/config";
}
This redirect to /config will be handled again by /config GET handler. (Or you can redirect to any GET handler of course)
i have existing web application where most of the time pages are submitted traditional way(like document.form.submit or )
I am planning to migrate to angularJS which i am learning. I am not sure how we can submit form in traditional way (without ajax) with angularJS ?
I know it won't be true Single Page App(SPA), but for starting i would like to go this way.
Approach for migrating traditional app to SPA :-
In future , i would like to go for SPA in which i will submitting the form thru ajax way using AngularJS. I have vague understanding
how will i approach this but would like to get experts advice on this.
My Understanding:-
Say i land to welcome page with a link for customer creation. I will make the ajax call from WelcomeController(angularJS Controller) to my servlet/spring controller
which will return html response containing js file. HTML response will be conatining below
1)HTML will be containing ng-view and ng-template which will be used by routeProvide
2)One of the js files will be containing routeProvider Info to map the ng-template with view
Please correct me if this is right approach ?
Use AngularJS for data-binding and form-validation. When you want to submit a form, you can rely on jQuery:
<div ng-controller="ctrl">
<form id="myform" name="myform">
Name: <input type="text" ng-model="person.name" name="person.name" /> <br />
<button ng-click="submit(person)">Submit</button>
</form>
</div>
Script
app.controller('ctrl', function($scope) {
$scope.submit = function(person) {
if ($scope.myform.$valid) {
$('#myform').submit();
}
}
});
For this to work, make sure you give your input fields properly scoped names so that it binds to your MVC models.
This approach does have its limitations. For example, input fields that use ngModel should not have any $formatters/$parsers which limits you to simple formats.
I was exactly looking for Single Page App with AngularJS which describes how you can have full fledged SPA web app using AngularJS(with features like router,controller,service etc) in a clear and succinct way
I am a beginner in the JSP World as per I have noticed that, there is one form tag which has action and method attribute. In action tag we must write the URL of the servlet which gets activated after clicking the submit button.
But my problem start here. I am trying to develop a register page.
I have two servlets:
one checks for the availability of existing user,
second register the user.
Does anyone have any idea how to achieve it without a href link or image button?
Move the code that checks for availability of the existing user and register the user to its own service class say UserService. Make the form submit to 2nd servlet which uses UserService to perform both the operations.
You can have two separate forms but not nested forms in HTML. If you want a single form to change its actions (its target URL) depending on which submit is used, the only way you can achieve that is through javascript.
You can do this with your existing approach by registering a Javascript function
<body>
<script type="text/javascript">
function submitType(submitType)
{
if(submitType==0)
document.userForm.action="CheckUserAvailability.do";
else
document.userForm.action="RegisterUser.do";
}
</script>
<form name="userForm" method="post">
--Other elements here
<input type="submit" value="Check User Availabiliy" onClick="submitType(0)"/>
<input type="submit" value="Check User Availabiliy" onClick="submitType(1)"/>
</form>
</body>
Yes You can.. In the action you give the Servlet name. and inside that servlet you can call java methods which are written in other classes.
Which means you can check
1.one checks for the availability of existing user
2.second register the user
Using two java classes(may be according to your choice)
Just call those methods with in the same servlet..Guess you got an idea.
I am working in a web application using struts. I am performing some operations in struts action class and using session.setAttribute i am setting result value. My struts action class sends result to jsp page where i am displaying result. I have to display message after loading jsp page, hence i am trying to use jquery. But i am not getting how to handle http sesion request in jquery.
Earlier i was taking one property in sturts-config.xml and setting the value instead of sending http session request parameter. But it doesn't work for me, because every time when i refresh my page it takes initial value from struts-config.xml. i am taking struts property as hidden field in jsp page by writing:
<html:hidden property="propname" styleId="id_propname" name="formname" />
for setting property value null I am writing following code in jquery.
<script type="text/javascript">
$(document).ready(function()
{
alert("some text");
$("#id_propname").val("");
});
</script>
Is there any way where i can directly get the http session request in jquery ? please reply me if you can give some suggestions I thanks to all valuable suggestions in advance.
IMHO there is no simple way to pass your session to the jquery . What you can do is to set the value of some hidden field and declare a global variable on the script and access the value and check for the valid condition if any .
Although its ugly and highly discouraged to use scriptlet inside jsp , this might work :-
<% String sessionVal = session.getAttribute("yourSessionValue").toString() %>
<html type="hidden" id="id_propname" name="propname" value=<%=sessionVal> >
In your jquery :
<script type="text/javascript">
var sessionVal;
$(document).ready(function()
{
sessionVal = $("#id_propname").val();
alert("this is the session value at Script " + sessionVal );
});
</script>
Null check for session is not done.
Or
If you are using tag libraries you can set the session value on form bean and use something like this in jsp :-
<logic:equal name="yourFormBean" property="yourProperty" value="someDefinedValue">
Do your action here
</logic:equal> <br />
Well http Sessions and Requests, in the form of java Objects and related to servlets, live in the server side. JQuery on the other hand will "normally" live in the client side... therefore your problem description is a bit "off".
The parameters you "send" in the httpsession or/and in the httprequest are for the jsp generation where jQuery does not play any part. What then gets sent to the browser is the HTML generated by the jsp engine. This HTML when in the browser can then be used by jQuery.
By the way the framework name is Struts and not Sturts.
Taking in account this information I don't really understand what in fact you want to do.