Reload jsp and lose request.getParameter("...") on servlet - java

I have 2 jsp-page. In first jsp-page I use combobox who choosing subject, several radio button for action. On servlet this page I get request.getParameter("subjectID").
Better If I show servlets and jsp
<form action="/TutorWebApp/controller" method="POST" name="editTestForm">
<p>
Choose subject
<select name='subject'>
<c:forEach items="${subjects}" var="subject" >
<option value="${subject.key}">
${subject.value.getName()}
</option>
</c:forEach>
</select>
</p>
<input type="radio" name="command" value="add_test">
Add test <br />
<input type="radio" name="command" value="add_subject">
Add subject <br />
<input type="submit" value="OK"/>
</form>
In this page I choose subject from combobox. And choose "Add test". After I go to servlet where
class AddTestCommand implements Command {
private static final String PARAM_TEST_NAME = "testName";
private static final String PARAM_SUBJECT = "subject";
#Override
public String execute(HttpServletRequest request) throws ServletException, IOException {
String page = " ";
String message = " ";
String testName = request.getParameter(PARAM_TEST_NAME);
if (testName != null && (!"".equals(testName))) {
HttpSession session = request.getSession(true);
Integer userID = (Integer) session.getAttribute("userID");
Integer subjectId =
Integer.valueOf(request.getParameter(PARAM_SUBJECT));
if(AddTestLogic.addTest(userID, subjectId, testName)){
message = "Success";
} else{
message = "This test already exist";
}
request.setAttribute("result", message);
}
page = ResourceBuilder.getPropertyManager(PropertyEnum.JSP_PAGE).
getProperty("path.page.addtest");
return page;
}
}
There I can get value of subject as request.getParameter("subject"); near with testName before if(){} And next step - go to next jsp
<form action="/TutorWebApp/controller" method="POST" name="addTestForm">
<input type="hidden" name="command" value="add_test" />
Name of new test:
<input type="text" name="testName" value=""/>
<input type="submit" value="Add test"/>
</form>
An after input data in jsp I go to the same servlet again. But I lose value request.getParameter("subject").
I try to use HttpSession but on first page I send Map. And get with request just choosen subjectID from Map.
I don't know how resolve this problem.
Thanks

You can retain request parameters for the next request with a hidden field. Request parameters are available by the ${param} map in EL. So, this should do:
<input type="hidden" name="subject" value="${fn:escapeXml(param.subject)}" />
Note that I'm using JSTL fn:escapeXml() to escape HTML entities; this will prevent possible XSS attacks.

Related

convert parameter from multiselect checkbox of jsp page

<input type="checkbox" name="premium" value="HBO">HBO <br>
<input type="checkbox" name="premium" value="FOXP">FOX Película <br>
<input type="checkbox" name="premium" value="FOX">FOX + <br><br>
<input type="submit" value="cotizar" name="Cotizar" />
<br><br>
I'm trying to bring from an index.jsp the premium parameter of a checkbox, in a servlet of a client of a web service. I have to save it as a list but what I have tried has not worked
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String plan = request.getParameter("plan");
String PREMIUM = request.getParameter("premium");
How do I convert request.getParameter ("premium") into a list?
Try this:
String[] premiums = request.getParameterValues("premium");
You need to put all the checkbox inside of form then only multiple values will be sent to server.
HTML:
<form method="post">
<input type="checkbox" name="premium" value="HBO">HBO <br>
<input type="checkbox" name="premium" value="FOXP">FOX Película <br>
<input type="checkbox" name="premium" value="FOX">FOX + <br><br>
<input type="submit" value="cotizar" name="Cotizar" />
</form>
Servlet:
To get multiple values we need to use getParameterValues(), if you any value for the given parameter name it will give string array of values. If we have one value it will given string array with length of 1.
String[] premiums = request.getParameterValues("premium");
If no value sent to server then above method will return null value.

Reading table html rows values to a servlet to another jsp page for editing

I want to get the values for the rows which is then sent to a Java servlet then read by another page and inserts those values into the text boxes for the user to edit and write it back into the text file.
So it gets read by ProductIO which reads the textfile.
Its then entered into a jsp table
<c:forEach var="product" items="${products}">
<tr>
<td ><c:out value='${product.code}'/></td>
<td ><c:out value='${product.description}'/></td>
<td >${product.priceCurrencyFormat}</td>
<td><form action="editproduct" method="post">
<input type="submit" value = "Edit">
</form>
</td>
<td><form action="deleteproduct" method="post">
<input type="submit" value = "Delete">
</form>
</td>
</tr>
</c:forEach>
The User Clicks either the delete or edit button which will then send action to either the deleteproduct servlet or the editproduct servlet(only asking about the edit for now)
The edit product servlet
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String url = "/editproduct.jsp";
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
String action = request.getParameter("action");
if (action == null) {
action = "editproduct"; // default action
} else if (action.equals("editproduct")) {
String productCode = request.getParameter("productCode");
String descString = request.getParameter("description");
//HttpSession session = request.getSession();
Product product = (Product) session.getAttribute("cart");
if (product == null) {
product = new Product();
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
}
Which the three Values are put into three text boxes on the editProduct.jsp page(where im having a problem getting the values to insert into the text boxes for it to be written back to the text file with the new information)
<form action="Product" method="post" >
<input type="hidden" name="action" value="add">
<label>Code:</label>
<input type="text" name="code" value='<%=request.getAttribute("code")%>'
required><br>
<label >Description:</label>
<input type="text" name="desc" value='<%=request.getAttribute("description")%>'
required ><br>
<label >Price:</label>
<input type="text" name="price" value='<%=request.getAttribute("price")%>'
required ><br>
<label> </label>
<!--<input type="submit" value="Update Product" class="margin_left">-->
<!--<input type="submit" value="View Product" class="margin_left">-->
<button type="submit">Update</button><br>
I can share more code if needed.
You aren't calling request.setAttribute() with any of the attributes in your Servlet. I assume you meant to add something like
request.setAttribute("code", productCode);
request.setAttribute("description", descString);
request.setAttribute("price", product.getPrice());
Before forwarding the request.

QTIWorks LTI request parameter is empty

I'm trying to implement LTI in our education platform to connect with QTIWoks in Java.
I have a simple tool consumer that generates the following HTML Form:
<html>
<head> </head>
<body>
<form action="http://192.168.0.114:8080/qtiworks-engine/lti/domainlaunch" name="ltiLaunchForm" id="ltiLaunchForm" method="post" target="basicltiLaunchFrame" enctype="application/x-www-form-urlencoded" style="display: block;">
<input type="hidden" name="context_id" value="cid-00113">
<input type="hidden" name="context_label" value="SI106">
<input type="hidden" name="context_title" value="Design of Personal Environments 1">
<input type="hidden" name="ext_note" value="Instructor from first course">
<input type="hidden" name="launch_presentation_locale" value="en_us">
<input type="hidden" name="lis_person_contact_email_primary" value="sian#imscert.org">
<input type="hidden" name="lis_person_name_family" value="Instructor">
<input type="hidden" name="lis_person_name_given" value="Siân">
<input type="hidden" name="lis_person_sourcedid" value="school.edu:user">
<input type="hidden" name="resource_link_description" value="This learning space is private">
<input type="hidden" name="resource_link_id" value="res-0012612">
<input type="hidden" name="resource_link_title" value="My Weekly Wiki">
<input type="hidden" name="roles" value="Instructor">
<input type="hidden" name="tool_consumer_info_product_family_code" value="sakai-unit">
<input type="hidden" name="tool_consumer_info_version" value="0.9">
<input type="hidden" name="tool_consumer_instance_description" value="University of School (LMSng)">
<input type="hidden" name="tool_consumer_instance_guid" value="lmsng.school.edu">
<input type="hidden" name="user_id" value="user-0016">
<input type="hidden" name="oauth_callback" value="about:blank">
<input type="hidden" name="custom_simple_key" value="custom_simple_value">
<input type="hidden" name="custom_complex____________key" value="Complex!##$^*(){}[]½Value">
<input type="hidden" name="lti_version" value="LTI-1p0">
<input type="hidden" name="lti_message_type" value="basic-lti-launch-request">
<input type="hidden" name="oauth_version" value="1.0">
<input type="hidden" name="oauth_nonce" value="Z2WVNEPUZkzsolOe4hRvKbkXtOSmYiyw">
<input type="hidden" name="oauth_timestamp" value="1429793062">
<input type="hidden" name="oauth_consumer_key" value="feras">
<input type="hidden" name="oauth_signature_method" value="HMAC-SHA1">
<input type="hidden" name="oauth_signature" value="g908qTtVGh8MsOgVUdarVlSBmC0=">
<input type="hidden" name="ext_submit" value="Finish Launch">
</form><iframe name="basicltiLaunchFrame" id="basicltiLaunchFrame" src="" width="100%" height="900" scrolling="auto" frameborder="1" transparency="">
</iframe>
<script type="text/javascript">
document.getElementById("ltiLaunchForm").style.display = "none";
nei = document.createElement('input');
nei.setAttribute('type', 'hidden');
nei.setAttribute('name', 'ext_submit');
nei.setAttribute('value', 'FinishLaunch');
document.getElementById("ltiLaunchForm").appendChild(nei);
document.ltiLaunchForm.submit();
</script>
</body>
</html>
then it calls the dominlaunch from qtiworks
#RequestMapping(value="/domainlaunch", method=RequestMethod.POST)
public String ltiDomainLevelLaunch(final HttpSession httpSession, final HttpServletRequest request,
final HttpServletResponse response)
throws IOException {
/* Decode LTI launch request, and bail out on error */
final DecodedLtiLaunch decodedLtiLaunch = ltiLaunchService.decodeLtiLaunchData(request, LtiLaunchType.DOMAIN);
if (decodedLtiLaunch.isError()) {
response.sendError(decodedLtiLaunch.getErrorCode(), decodedLtiLaunch.getErrorMessage());
return null;
}
final LtiLaunchData ltiLaunchData = decodedLtiLaunch.getLtiLaunchData();
/* Make sure this is a domain launch */
final LtiUser ltiUser = decodedLtiLaunch.getLtiUser();
final LtiDomain ltiDomain = ltiUser.getLtiDomain();
if (ltiDomain==null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "The tool consumer has attempted a domain-level launch using a link-level key");
return null;
}
/* Extract/create the corresponding LtiResource for this launch */
final LtiResource ltiResource = ltiLaunchService.provideLtiResource(decodedLtiLaunch); /* (May be null for candidates) */
final UserRole userRole = ltiUser.getUserRole();
if (userRole==UserRole.INSTRUCTOR) {
/* If user is an instructor, we'll forward to the LTI instructor MVC after
* "authenticating" the user by creating and storing an LtiDomainTicket
* in the session */
final LtiAuthenticationTicket ltiDomainTicket = new LtiAuthenticationTicket(ltiUser.getId(), ltiResource.getId(),ltiLaunchData.getLaunchPresentationReturnUrl());
LtiResourceAuthenticationFilter.authenticateUserForResource(httpSession, ltiDomainTicket);
return "redirect:/lti/resource/" + ltiResource.getId();
}
else if (userRole==UserRole.CANDIDATE) {
/* If user is a candidate, then we'll launch/reuse a candidate session */
if (ltiResource==null) {
return "candidateLaunchError";
}
/* Extract relevant data */
final String returnUrl = ltiLaunchData.getLaunchPresentationReturnUrl();
final String lisOutcomeServiceUrl = ltiLaunchData.getLisOutcomeServiceUrl();
final String lisResultSourcedid = ltiLaunchData.getLisResultSourcedid();
/* Launch and redirect to session */
try {
final CandidateSessionTicket candidateSessionTicket = candidateSessionLaunchService.launchDomainLevelLtiCandidateSession(httpSession,
ltiUser, ltiResource, returnUrl, lisOutcomeServiceUrl, lisResultSourcedid);
return GlobalRouter.buildSessionStartRedirect(candidateSessionTicket);
}
catch (final CandidateException e) {
return "candidateLaunchError";
}
}
else {
throw new QtiWorksLogicException("Unexpected LTI userRole " + userRole);
}
}
the problem is decodedLtiLaunch.isError() returns true and my request is not performed.
I debugged the problem and found that HttpServletRequest request has no item in parameterMap
however, it's working well when the request comes from moodle (request's parameterMap has the passed params)
how can I solve this please?
thanks in advance.
Without knowing what the exact error code you are seeing is, I am going to make a very strong guess that your signature is bad
Since you are using JAVA I would suggest that you utilize the basiclti-util library that IMSGlobal provides to generate a signature
Add the following dependency
<dependency>
<groupId>org.imsglobal</groupId>
<artifactId>basiclti-util</artifactId>
<version>1.1.2</version>
</dependency>
Then use the following code to generate the signature
Map<String, String> signedParameters = new LtiOauthSigner()
.signParameters(parameters, key, secret, url, "POST");
Then take all of the key-value pairs in the signedParameters map, and use that to construct the form input tags you have in your example.

Displaying error on Play! 2 Framework

I am having big difficulties following Play! 2.2.x documentation and i am currently stuck on how to display error from my form validation.
This is my code:
Route
GET /account/create controllers.Account.create()
POST /account/create controllers.Account.createAccount()
Model
public static UserAccount create(UserAccount data){
UserAccount account = data;
String salt = BCrypt.gensalt();
account.email = data.email;
account.salt = salt;
account.hash = BCrypt.hashpw(data.hash, salt);
account.save();
return account;
}
Controller
// handles POST method
public static Result createAccount(){
Form<UserAccount> userForm = form(UserAccount.class).bindFromRequest();
if(userForm.hasErrors()){
return badRequest();
}else{
UserAccount.create(userForm.get());
Logger.info("Username is: " + userForm.get().email);
return ok("ok, I recived POST data. That's all...");
}
}
// Handles GET method
public static Result create(){
return ok(
views.html.account.form.render()
);
}
Views
#if(form.hasGlobalErrors) {
<p class="error">
#form.globalError.message
</p>
}
#helper.form(action = routes.Account.createAccount()) {
<input type="text" name="email" placeholder="Your Email Address"/><br/>
<input type="password" name="password" placeholder="Your Password"/><br/>
<input type="text" name="fname" placeholder="Your First Name"/><br/>
<input type="text" name="midname" placeholder="Your Middle Name"/><br/>
<input type="text" name="lname" placeholder="Your Last Name"/><br/>
<input type="text" name="dob" placeholder="Your Birthday"/><br/>
<select name="gender" id="gender">
<option value="1">Male</option>
<option value="2">Female</option>
<option value="3">Undecided</option>
</select><br/>
<input type="submit" value="Login" />
}
Error Message
value hasGlobalErrors is not a member of object views.html.account.form
Can anyone tell me what's wrong with my code? I am frustrated with the given example.
EDIT #1:
This is what i have done so far:
Models:
public static UserAccount create(UserAccount data){
UserAccount account = data;
String salt = BCrypt.gensalt();
account.email = data.email;
account.salt = salt;
account.hash = BCrypt.hashpw(data.hash, salt);
account.save();
return account;
}
Controllers:
// HANDLES GET REQUEST
public static Result create(){
return ok(
views.html.account.form.render(userForm)
);
}
// HANDLES POST REQUEST
public static Result createAccount(){
Form<UserAccount> userForm = form(UserAccount.class).bindFromRequest();
if(userForm.hasErrors()){
return badRequest(views.html.account.form.render(userForm));
}else{
// UserAccount.create(userForm.get());
// Logger.info("Username is: " + userForm.get().email);
UserAccount data = userForm.get();
return ok(data.email);
}
}
VIEWS/TEMPLATE
#(form: Form[UserAccount])
#if(form.hasGlobalErrors) {
<h1>Please fix the following error first</h1>
<p>
#form.globalError.message
</p>
<ul>
#for(error <- form.globalErrors) {
<li>#error.message</li>
}
</ul>
}
#helper.form(action = routes.Account.createAccount()) {
<input type="text" name="email" placeholder="Your Email Address"/><br/>
<input type="password" name="password" placeholder="Your Password"/><br/>
<input type="text" name="fname" placeholder="Your First Name"/><br/>
<input type="text" name="midname" placeholder="Your Middle Name"/><br/>
<input type="text" name="lname" placeholder="Your Last Name"/><br/>
<input type="text" name="dob" placeholder="Your Birthday"/><br/>
<select name="gender" id="gender">
<option value="1">Male</option>
<option value="2">Female</option>
<option value="3">Undecided</option>
</select><br/>
<input type="submit" value="Login" />
}
So far, according to firebug when i deliberately put errors on the form the server will return badrequest. However, no error is displayed by the template.
If i change the controller as such:
public static Result createAccount(){
Form<UserAccount> userForm = form(UserAccount.class).bindFromRequest();
if(userForm.hasErrors()){
return ok(userForm.errorsAsJson().toString());
}else{
// UserAccount.create(userForm.get());
// Logger.info("Username is: " + userForm.get().email);
UserAccount data = userForm.get();
return ok("ok, I received POST data. That's all...");
}
}
Or if i do this on my View/Template
<pre>#form.errorsAsJson.toString()</pre>
It works, and errors are printed accordingly. Do anyone know what i am missing here?
EDIT #2:
The best thing that works for me to output the error is by doing this on my View/Template
#(form: Form[UserAccount])
#if(form.hasErrors) {
<h1>Please fix the following error first</h1>
<ul>
#for(error <- form.errors) {
<li>#error.toString</li>
}
</ul>
}
Which outputs this:
(email,[ValidationError(email,error.required,[])])
(hash,[ValidationError(hash,error.required,[])])
Since I am trying to display an appropriate message to user, the message is rather useless.
After looking deeper at your code, there are two things to note:
In your template you need to use the helper tags for your form fields. The helpers will display field specific errors for you: http://www.playframework.com/documentation/2.2.x/JavaFormHelpers
I don't think your form has any global errors, which is why that code isn't displaying anything.
Try the helpers and see if that works for you.
You can use the flash scope:
Controller:
public Result create(){
flash("error", "error msg");
return badRequest(view.render());
}
View:
#flash.get("error")
The problem is that your form doesn't have "global errors", it has errors for the fields email and hash. It's different.
You can check the error for the fields using:
#if(form.error("email") != null) { }
And you can fire global error as belor on controller:
form.reject("global error");
More info:
http://www.playframework.com/documentation/2.0/JavaSessionFlash
I need to see your full template, controller, and routes file. I think the problem is that you don't have a method signature at the top of your template file, something like this:
#(userForm: Form[User])
Once you fix the template, you have another problem that you are not passing the form to the view template in the "badRequest()" flow. Try changing your controller action to look like this:
public static Result createAccount(){
Form<UserAccount> userForm = form(UserAccount.class).bindFromRequest();
if(userForm.hasErrors()){
return badRequest(views.html.createUserTemplate.render(userForm));
}else{
UserAccount.create(userForm.get());
Logger.info("Username is: " + userForm.get().email);
return ok("ok, I recived POST data. That's all...");
}
}
Your global errors code is mostly correct, it should look like this:
#if(userForm.hasGlobalErrors) {
<ul>
#for(error <- userForm.globalErrors) {
<li>#error.message</li>
}
</ul>
}

Liferay doesn't catch form in portlet, and doesn't process

I have .jsp in liferay, and use javascript with applet, but after the form sent to the portlet, on the server side, portlet doesn't catch the form, and do not show in logs additional messages.
jsp page's snippet:
<script type="text/javascript">
function processSigning(){
var applet = document.applets["SignApplet"];
var path_to_certificate = document.getElementById("certificate").value;
var pass = document.getElementById("password").value;
var filePath = document.getElementById("documentSign").value;
applet.filePath = document.getElementById("documentSign").value;
applet.profileTestPKCS12(path_to_certificate, pass);
document.getElementById("file").value = applet.getDocumentString(filePath);
document.getElementById("sign").value = applet.getSignString();
document.getElementById("cert").value = applet.getCertificateString();
document.getElementById("mainForm").submit();
}
</script>
<form id="mainForm" action="<portlet:actionURL>
<portlet:param name="COMMAND" value="LOAD"/>
</portlet:actionURL>">
<hidden id="file" value="asdf"></hidden>
<hidden id="cert" value="asdf"></hidden>
<hidden id="sign" value="asdf"></hidden>
<input type="button" onClick="processSigning();" value="click here!" >
</form>
portlets snippet:
public void processAction(ActionRequest request, ActionResponse response) throws PortletException {
session = request.getPortletSession(true);
String command = request.getParameter("COMMAND");
System.out.println("command=" + command);
log.info("command=" + command);
if ("LOAD".equals(command)) {
{
System.out.println("file");
log.info("file");
String fileBase64 = request.getParameter("file");
System.out.println(request.getParameter("file"));
log.info(request.getParameter("file"));
}
}
}
Check your portlet.xml if the portlet-class is pointing to MVCPortlet or your custom portlet class. It should point to the custom portlet class.
Try this form and see if it works for you:
<portlet:actionURL var="myActionURL"></portlet:actionURL>
<form id="mainForm" action="${myActionURL}" method="post">
<input type="hidden" name="COMMAND" id="COMMAND" value="LOAD" />
<input type="hidden" name="file" id="file" value="asdf" />
<input type="hidden" name="cert" id="cert" value="asdf" />
<input type="hidden" name="sign" id="sign" value="asdf" />
<input type="button" onClick="processSigning();" value="click here!" >
</form>
Hope this helps.
There is method for the form must be specified, because Liferay Portal works with "post" method, also the names of hidden parameters must be used with "name" attribute, because request works with name, not ids

Categories