How to remove Public render parameter from jsp or render phase of portlet class - liferay-6.2

I have two portlets :
1. Blog Portlet.
2. Author Portlet.
I used the concept of Public render parameter to send data (say key "urlTitle") from Blog portlet to Author portlet
But after sending "urlTitle" from Blog portlet how can I remove the data from Public render parameter
In Blog Portlet
EX code: view.jsp
<portlet:renderURL var="viewEntryURL">
<portlet:param name="struts_action" value="/blogs/view_entry" />
<portlet:param name="redirect" value="<%= currentURL %>" />
<portlet:param name="urlTitle" value="<%= entry.getUrlTitle() %>" />
</portlet:renderURL>
Send Data
Now how I can remove "urlTitle" form the public render parameter after data is sent.
Please give feedback.
-Thanks in advance

You could think about the following:
The LiferayPortletURL (the class that models portlet render, action and resource URLs tags) offers a method called setCopyCurrentRenderParameters
https://docs.liferay.com/portal/6.2/javadocs/com/liferay/portal/kernel/portlet/LiferayPortletURL.html#setCopyCurrentRenderParameters(boolean)
which when set to false, avoids copying render parameters, and the URLs are "cleaned" from those.
The caveat with this is that you would need to create a LiferayPortletURL in the back end doing the following:
LiferayPortletURL renderUrl = PortletURLFactoryUtil.create(
httpServletRequest,
themeDisplay.getPortletDisplay().getId(),
themeDisplay.getPlid(),
PortletRequest.RENDER_PHASE);
renderUrl.setCopyCurrentRenderParameters(false);
and after that pass it to your JSP set as an attribute (maybe renderRequest.setAttribute("renderUrl",renderUrl)?). I haven't done this for render URLs, but for resource URLs and it works!

You need to set
javax.portlet.init-param.copy-request-parameters=false
in your portlet class.

Related

Pass data from Thymeleaf template to springboot controller

I have simple web application written using Springboot and Thymeleaf templates. Report controller receives the data from form and builds the TestPlanReportResponse object which is added as model attribute like this:
#PostMapping("/report")
public String homeSubmit(#ModelAttribute HomeFormInput homeFormInput, Model model, Errors errors) {
final TestPlanReportResponse response = new TestPlanReportResponse(homeFormInput);
model.addAttribute("allData", response);
return "charts";
}
I can work with that data in "charts" thymeleaf template and show the data I need, but I need to send exactly the same object back to controller when button is clicked, but i getting TestPlanReportResponse
object as parameter with nulls set.
#PostMapping("/report/send")
public String sendReport(#ModelAttribute TestPlanReportResponse reportData, Model model) {
//reportData contains just nulls
}
Here is how my button is set in charts template:
<form action="#" th:action="#{/report/send}" th:object="${allData}" method="post">
<button type="submit">Send the report</button>
</form>
So my question is how to send the object back from thymeleaf template? Should i create a hidden input and put there the "allData" object just to send it back? It looks for me like dirty hack. What would be the appropriate way to pass data back? I want to have this app stateless so don't to store the data on a server side.
When I used to work with Spring and Thymeleaf and form, we had the same issue, passing the data back and forth between a form, the template, and different controllers.
And what you suggest is what we did, we used hidden input as dirty as it may look,it was the standard suggested answer, we did not find anything better.
You need to create an input, with a type a value and link it to a field, like this:
<form action="#" th:action="#{/report/send}" th:object="${allData}" method="post">
<input type="hidden" th:value="*{allDataValue1}" th:field="*{allDataField1}" />
//Do this for all your attributes/values that you wish to pass to the controller
<button class="btn btn-info btn-lg btn-block" type="submit">Send the report</button>
</form>
Though, i found this answer, you can try looking into this thread

Hidden field "ufprt" being added to Razor Umbraco Form - Why?

I have got a form (below) that is posted to an umbraco surface controller.
#using (Html.BeginUmbracoForm("AddToBasket", "Basket"))
{
<h1>#Model.productSelectionModel.Product.Title - #Model.productSelectionModel.Product.Price.ToString("C")</h1>
<ul>
#foreach (var productOption in Model.productSelectionModel.ProductOptions)
{
<li>#productOption.Option.Title</li>
#Html.DropDownList(productOption.Option.Id.ToString(), productOption.ValuesInOptions.ToSelectList(f => f.OptionValue.OptionValue1,
f => f.Id.ToString(),
"Select"));
}
</ul>
<input type="submit" value="Add To Basket">
}
When I look at the HTML rendered for this form it seems to have added a hidden field called ufprt. Does any one know what this is? Why is it being added, I'm not using it any where ( I don't think I am anyway)
Any ideas?
<input name='ufprt' type='hidden' value='6C01896EF3D5F430F9ED041DD2B0D31F89FA969A085C6F4FDEC3C9D4B906846E7AA80041CEA12573E9F58C1740893B770AAE3319FAA8FA35C89A54D301CFE31B85ADC0D3D9506D208DB068D1257C5F0D5F1B3B90FD59A5C2938EED0A2EB1168AD4573CD5D043D47A8F1AA789E988CC614686B89BE57D35DA8EAAA110044C393F' />
It is to route the form to the correct controller/action method (Umbraco has the ability to route forms via that input value rather than the typical MVC approach of using the URL). I believe this is particular to surface controllers (i.e., it wouldn't apply to a normal controller, API controller, or RenderMvcController).
It is not a CSRF token as another answer indicates. If it were, it would likely have a name of "__RequestVerificationToken" as indicated here: http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-%28csrf%29-attacks
EDIT: This information has been added here: https://github.com/kgiszewski/LearnUmbraco7/blob/a97e85e5ad17e2ba9fc463f02c76885911046b57/Chapter%2006%20-%20Surface%2C%20WebAPI%20and%20RenderMVC%20Controllers/02%20-%20Surface%20Controllers.md#special-routing

<form:form have method GET or POST

This may be a very basic question but I am confused. I have couple of doubts:
In spring form <form:form if method is not specified then is it GET or POST?
If a spring form has <form:form with commandName then is that GET or POST?
The second question is because I see a "form:form commandName=xyz action=abc" in the code
When I check the HTML code (view source) it translates to
"form action=abc method=POST"
Please help me with this.
HTML form without specified action is always GET. It's HTML standard.
http://www.w3.org/TR/html401/interact/forms.html#h-17.3
But when you look inside FormTag in Spring source you'll notice this code:
public class FormTag extends AbstractHtmlElementTag {
/** The default HTTP method using which form values are sent to the server: "post" */
private static final String DEFAULT_METHOD = "post";
So for spring tag <form:form action is post by default.
commandName is just name for model attribute binded with your form. It has nothing to method type. Moreover, it's equivalent to modelAttribute so you can use either.
Spring form has default method as POST. If you want to do the get, you have to write, method="get" in form:form tag.

Passing values between View and Controller in MVC 2

I'm constantly confused about how to pass values between Views and Controllers in MVC. I know I can set ViewData in the Controller and use that in the View, but what about the other way around?
What I have found is I can use a hidden field and then access it through Request.Form["name"] like this:
<% using (Html.BeginForm("Upload", "Customers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<br />
<input id="currentDir" type="hidden" name="currentDir" value="" />
<input type="file" name="fileTextbox" id="fileTextbox" />
<br />
<br />
<input type="submit" value="Send" />
<% } %>
What complicates it even more is that the value originally comes from a jquery script, so that's why the input field was the only way I could think of. But it still feels wrong... Maybe it isn't but I'd basically like to know if there are other more "proper" established ways to pass values between the View and Controller (both ways). Should one use querystrings instead? If so, how would they look in the html.beginform htmlhelper?
Also, what I'm trying to do here is enable upload possibilities for my application. And I'm trying to make the whole application as "Ajaxy" as possible. But this form will make a complete post. Is there another way to do this and not have to reload the entire page for this upload?
Let's ignore the "AJAX-y" aspects for a moment (because that's a different issue) and just look at passing data between views and controllers. I would first recommend that you check out the NerdDinner Tutorial which provides some good insights into how MVC works and how you use some of the features of MVC.
To address your specific question of how data is passed from View to Controller and back, there are a few ways to do this. However, the one that tends to make sense to most people is the idea of using strongly-typed views.
Let's say you have a model called Person. For now, don't worry about how we store Person data - we just have a Person class in the Models folder inside your MVC project.
public class Person {
public string FirstName;
public string LastName;
public Person() {
FirstName = "John";
LastName = "Doe";
}
}
When we want to display data about Person in a View, we make a request to a specific controller. In this case (and for clarity) we'll call this controller the MainController. This will go in the Controllers folder and will be called MainController. Let's call the Action (an action is really just a specialized method) we want to get data from Index. Due to how ASP.NET MVC routing works, the path to our server will be: http://localhost/Main/Index. Notice the Controller (minus the "Controller" name), and the Action make up the path. (The first part is your server name, of course.)
Let's look at your controller - I'm going to keep it very simple for now:
public class MainController : Controller {
public ActionResult Index() {
Person person = new Person();
return View(person);
}
}
What we have going on inside the Index Action is that it is returning a View (which, by default, has the same name as the Action) and a model to correspond with that view. Now, we have to create our view.
The important part here is that you want to strongly-type the model that is being returned in the controller to your view. You do that with this line (which is first in your aspx file).
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewUserControl<Project.Namespace.Person>" %>
Notice the "Inherits" attribute and notice that your Person model makes up that attribute.
Now, just code the rest of your view as normal. Let's say we want to display the current Person name, and allow someone to change the name. The page would look like this (I'm not making this pretty):
<% using (Html.BeginForm()) { %>
<%: Html.LabelFor(model => model.FirstName) %>
<%: Html.TextBoxFor(model => model.FirstName) %>
<%: Html.LabelFor(model => model.LastName) %>
<%: Html.TextBoxFor(model => model.LastName) %>
<input type="submit" value="Submit" name="submitButton" />
<% } %>
This is the important part about getting data back and forth between Controllers and Views. What we are doing here is that we are taking your strongly-typed view (which is typed with the Person class) and using helper methods (like LabelFor and TextBoxFor) to tie the model together with its data and, ultimately, together with the actions contained in the controller (which we have to finish developing here in one moment).
So, you can now see the data. But, if a user changes the name and clicks submit - we want the page to display the new name. This means we need to add one more action to MainController - the one that receives the data.
[HttpPost]
public ActionResult Index(Person person) {
// Do whatever you want with the Person model. Update a database, or whatever.
return View(person);
}
This action looks very similar to the other action we just developed. However, this one takes a person object (from the form that is being submitted) and it gives the controller an opportunity to do whatever needs to be done with that object. Once this is done, you can choose to redirect to a different page, redisplay the page (useful if there are errors), or do any number of other things.
Again, this is ALL covered (and much more) in the NerdDinner Tutorial. I highly recommend you read and follow through that.
As for the AJAX-y aspects you discussed, the premise is still the same (although there is a little bit of JavaScript/jQuery work that goes on in there). I won't go into it now, but the basics are also covered in the NerdDinner tutorial.
I hope this gets you started. I remember being a bit confused too when I first started working with web technologies, so I hope this helps you out!

extending spring form tag library attributes

I'm using Spring's form tag library in a Spring MVC application that I am developing. The company I am working for has implemented some company-wide policies based on the definition of custom attributes for certain tags. For instance, by default (though the inclusion of a standard javascript file) all tags have their values automatically converted to upper case. In order to disable this one would define their tag with a custom attribute in the following way:
<input type="text" uppercase="false" />
The problem is that the addition of these custom attributes to a spring:form tag causes an error at runtime. I've pasted the error below.
org.apache.jasper.JasperException: /WEB-INF/jsp/reportCriteria.jsp(45,5) Attribute uppercase invalid for tag input according to TLD
My question is: is there any way to extend the TLD to allow for these attributes, or is there any other way add these custom attributes to these spring:form tags?
Ok, 2 years later... here we go!
HOW TO CREATE OUR OWN TAG EXTENDING CLASSIC ONE WITH NEW ATTRIBUTES IN SPRING MVC 3
1. Create your own taglib.tld
You need to create your own TLD file. There you are going to add the new attribute you are going to use. The best option is copy/paste spring-form.tld. You can find it in spring-mvc package (org.springframework.web.servlet-.jar).Search in META-INF folder.
Feel free to put it directly inside WEB-INF or in a subfolder. I putted it in /WEB-INF/tld.
Now search inside your new TLD file for the tag you are going to modify. I modified input tag, so i had to search for:
...
<tag>
<description>Renders an HTML 'input' tag with type 'text' using the bound value.</description>
<name>input</name>
<tag-class>org.domain.tags.CustomTags</tag-class>
<body-content>empty</body-content>
<attribute>
...
Copy from to and paste it below. Change the of the new tag for your own name. Mine was myInput. So now we have this:
...
<tag>
<description>Renders an HTML 'input' tag with type 'text' using the bound value.</description>
<name>input</name>
<tag-class>org.springframework.web.servlet.tags.form.InputTag</tag-class>
<body-content>empty</body-content>
<attribute>
...
</tag>
<tag>
<description>Renders an HTML 'input' tag with type 'text' using the bound value.</description>
<name>myInput</name>
<tag-class>org.domain.tags.CustomTags</tag-class>
<body-content>empty</body-content>
<attribute>
...
</tag>
SUMMARY: now I have a new file called taglib.tld here: /WEB-INF/tld/taglib.tld. Pay attention to the <tag-class> part
In your own new tag add a new attribute (copy/paste another one) call render.
<attribute>
<description>Enables/Disables the field rendering</description>
<name>render</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.Boolean</type>
</attribute>
Now we have created the taglib file we need. Let's see how to use it.
2. Create your own handler
Now we are going to create the class that will handle the new attribute (and the classic ones). I created the class CustomTags.java en el paquete org.domain.tags. Let's see first the code and explain it:
package org.domain.tags;
import javax.servlet.jsp.JspException;
import org.springframework.web.servlet.tags.form.InputTag;
import org.springframework.web.servlet.tags.form.TagWriter;
public class CustomTags extends InputTag {
private static final long serialVersionUID = 1L;
private boolean render;
public boolean isRender() {
return render;
}
public void setRender(boolean render) {
this.render = render;
}
protected int writeTagContent(TagWriter tagWriter) throws JspException {
if(render){
super.writeTagContent(tagWriter);
return SKIP_BODY;
}
else
return SKIP_BODY;
}
}
Of course, if we are going to add some features to the Input tag of Spring framework, we must extend it in order to mantain the rest of the features. As you can see, we have just added the render private attribute as boolean (in taglib.tld we also put it).
We have added to the getter and setter methods for this attribute.
Finally we have overwrite the writeTagContent method in order to make the JSP do what we want. In this case we want the input field to be shown if render is true. Otherwise the field can't be shown. That's why we call the writeTagContent of the parent class.
If we need to make some changes on the tag behaviour, this method is the right place to do them.
3. Using the new tag.
Now we only need a JSP with a form to use the new tag. It's easy to do, so i only let here the code:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix = "newtags" uri = "/WEB-INF/tld/taglib.tld" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 3.0 MVC Series: Welcome World</title>
</head>
<body>
<h1>User Data</h1>
Please, fill the fields with your information:<br>
<newtags:form name="userForm" id="userForm" modelAttribute="userForm" action="user.htm" method="POST">
Name: <newtags:myInput type="text" name="textName" path="userName" render="true" size="50" /><newtags:errors path="userName" /><br>
Surname: <newtags:myInput type="text" name="textSurname" path="userSurname" render="true" size="50" /><newtags:errors path="userSurname" /><br>
Age: <newtags:myInput type="text" name="textAge" path="userAge" render="true" size="2" /><newtags:errors path="userAge" /><br>
Example: <newtags:myInput type="text" name="textSurname" render="false" size="20" path="userSurname"/>
<hr>
<input type="submit" value="Next" />
</newtags:form>
</body>
</html>
Now instead of calling springframework tld, we call our own TLD. As you can see the only field that is not going to be shown is Example one.
Good Luck all!
It's implemented in Spring 3.0 (SPR-5931).

Resources