I am trying to display the following ArrayList in the .jsp page shown but I can't seem to see any values once I run my portlet, where is the problem?
code.java
public class TestPortlet extends MVCPortlet {
public void displayProcess(ActionRequest request, ActionResponse response) {
ArrayList<String> process = new ArrayList<>();
process.add("a");
process.add("b");
process.add("c");
process.add("d");
process.add("e");
request.setAttribute("processName", process);
}
}
The jsp page is as shown:
<%# include file="/init.jsp"%>
<jsp:useBean id="processName" class="java.util.ArrayList" scope="request" />
<aui:select id="process" name="processitems">
<c:forEach items="${processName}" var="process">
<aui:option value="${process}">
${process}
</aui:option>
</c:forEach>
</aui:select>
Any help would be much appreciated.
Not sure if this is a complete answer, but some steps to figure out what the problem is. I'm taking your question as well as some comments:
You're implementing a portlet action handler, from there, you won't forward/dispatch to a particular jsp: A portlet's ACTION phase is only good for changing the state, while displaying the result is part of the VIEW phase. The code that you've posted (though it's obviously simplified) looks like it rather wants to live in doView().
In fact, that may be all you need: If you just display the portlet, only the VIEW phase will be triggered. Just displaying the portlet will not trigger the action handler, which you can validate in a debugger.
For the JSP: All you say is you "can't seem to see" any of the results. Validate where your problem is: Is the list there? Does enumerating the list work? Is your problem with the AUI taglib? You can easily check this by removing all of the other tags and rather generate pure output by removing a bit.
When you look at the output's source and any of the JSP stuff survives (e.g. the ${processName}, or <aui:select..>, <c:forEach...>, then you'll know that this is the root cause for "not seeing" anything. You might miss a taglib or other.
Last: I've never tried this, but <aui:select> is a tag that's meant to be used within a form, and I'm not sure what it does outside of a form - you may want to surround it with <aui:form ....> and see what happens then.
I found the solution:
I was to use:
public void displayProcess(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException {
instead of
public void displayProcess(ActionRequest request, ActionResponse response) {
and at the bottom of my method the following:
renderRequest.setAttribute("process", process);
super.render(renderRequest, renderResponse);
On the jsp page, at the topmost point; receive the ArrayList that you are passing as:
<% ArrayList<String> process = (ArrayList) request.getAttribute("process"); %>
.
The results are as follows:
Related
I am trying to get the parameters inside a portlet in Liferay 7.3. If I pass the parameter like:
http://localhost:8080/web/guest?name=abhi
in a web page, that contains my portlet. So My question is
Q1) can I get this parameter inside the Portlet Controller (doView method) when user reloads the above page, by doing something like:
import com.liferay.portal.kernel.util.ParamUtil;
public class MySamplePortlet extends MVCPortlet {
#Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
String name = ParamUtil.getString(renderRequest, "name");
System.out.println(name);
}
}
Here I am getting a blank for the 'name' when printing.
And
Q2) how I check the condition of this parameter in view.jsp view file (how to get the class variable value inside the view file) ?
<% if(name) %>
render form view
<% else %>
render messageBox view
......
I want to render different views according to the parameter value.
Parameters to a portlet are typically namespaced - e.g. a HTTP-parameter name could be anything to any portlet - and a page potentially has many portlets. All of them might think of name as something different: A city, a user, a customer, the currently used computer, a pet...
Thus any form typically submits values that look like (in jsp-lingo):
<input name="<portlet:namespace/>name" ..../> rather than <input name="name" ..../>
If you use tags that are portlet-aware, they might do the decoration automagically, e.g. <aui:input name="name" .../>.
Utilizing undirected and unnamespaced parameters in the portlet world might generate maintenance nightmares, specifically when you run into your first ambiguous name.
However, you can deactivate the namespacing, per portlet. Or you can manually access the underlying HTTPServletRequest. Both are strongly discouraged. Here's how you shoot yourself in the foot if you like to:
Set the portlet's property com.liferay.portlet.requires-namespaced-parameters=false
Utilize PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest)) (what these functions do - and why you need them both - is described, for example, here)
So the ParamUtil will work if the parameter is for the portlet. in this case it seems you want the parameter in the url in general meaning not specific for the portlet. to achieve this you need to use PortalUtil
HttpServletRequest httpReq = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(req));
String name = httpReq.getParameter("name");
Note im looking for the original request. not the portlet request.
hope it helps
I have a servlet
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
List<String> topics = new ArrayList<>();
ServletConfig config = getServletConfig();
topics.add(config.getInitParameter("first"));
System.out.println(config.getInitParameter("first")); //prints proper value, not null;
topics.add(config.getInitParameter("second"));
System.out.println(config.getInitParameter("second")); //prints proper value, not null;
topics.add(config.getInitParameter("third"));
System.out.println(config.getInitParameter("third")); //prints proper value, not null;
req.setAttribute("params", topics); //doesn't show up
req.setAttribute("name", config.getInitParameter("name")); //works good
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
and
index.jsp
...
<ol>
<c:forEach var="param" items="${params}">
<li>${param}</li>
</c:forEach>
</ol>
...
Servlet configuration is ok, initialization is ok, mapping and naming is also ok, that's why when I access respective URL, I do print the parameters in output console stream and they are there. However, for some strange reason, JSP displays:
1. {}
2. {}
3. {}
N.B. I don't want to use Scriptlet Java code, I'm trying to use JSTL. I have seen a lot of projects working in this way.. what's wrong here? just got tired of figuring out.
I presume you have:
<%# taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
In index.jsp?
I've spent on this half of my day, and at the end, it really got me tired and anxious, because it seems so obvious and simple code - what should be going wrong?
As some may be searching for the solution of same kind of problem, I think, it's better to have this answered here - what was the problem.
The crucial point here is the name of the iteration variable - the identifier param.
At the beginning of [probably] all .jsp files, we have the statement for importing core tags and we give it some prefix
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
The reason, why
...
<ol>
<c:forEach var="param" items="${params}">
<li>${param}</li>
</c:forEach>
</ol>
...
was not working and was showing
1. {}
2. {}
3. {}
is that, param is the keyword identifying one of the core tags, from jstl/core.
The <c:param> fetches/gets the Request Parameter(s) array.
So, each time forEach loop was iterating, param variable was assigned to request parameter(s) from query string rather than iteration value from ${params} variable/placeholder, and as I was passing nothing - empty array was appearing.
P. S. Be cautious not to use JSTL tags as variables/identifiers in your code.
Hope some of you will find this information useful.
I'm used to rails and the very handy yield functionality in erbs. I would like to be able to inject css/js script tags to the head when I'm running through many child jsp templates in the body tag. I know this is possible with Rails using yield, but I cant see a way of injecting a string higher than whats already outputted... here is my example
<head>
<!--- i want to inject script tags into here -->
</head>
<body>
<!-- running multiple child templates here -->
<!-- when the template needs a script tag, find a way of injecting it into the head -->
</body>
can I render into the head tag from further down the page, is this possible in jsp using string writers or some other way?
There are several ways to accomplish text juggling. As ERB, ruby on rails, also has a bit of Model-View-Controller separation, let's keep the same practice here:
A servlet (the controller) builds one or more data models and puts them in request attributes. Then it forwards to a JSP (the view).
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException {
List<Content> contents = new ArrayList<>();
...
request.setAttribute("contents", contents);
request.getRequestDispatcher("/contentsview.jsp")
.forward(request, response);
}
As I guess intended to do a loop on data emitting HTML and building a parallel list collected in a StringWriter, this already should solve the problem.
Now for doing (too much) work in the JSP: you can use the JspWriter also in methods, so order of evaluation is just as free.
<%!
private void printSomething() {
%><p>...</p><%
}
%>
I have a java class which performs some operations on files. Since the java code is huge I don't want to write this code in jsp. I want to call the methods in jsp whenever required.
Please tell me the path where I need to keep this file. Also some example code how to use it would be helpful.
In the servlet (which runs before the JSP):
Person p = new Person(); // instantiate business object
p.init(...); // init it or something
request.setAttribute("person", p); // make it available to the template as 'person'
In the template you can use this:
your age is: ${person.age} <%-- calls person.getAge() --%>
I think the question is, how do you make Java code available to a JSP? You would make it available like any other Java code, which means it needs to be compiled into a .class file and put on the classpath.
In web applications, this means the class file must exist under WEB-INF/classes in the application's .war file or directory, in the usual directory structure matching its package. So, compile and deploy this code along with all of your other application Java code, and it should be in the right place.
Note you will need to import your class in the JSP, or use the fully-qualified class name, but otherwise you can write whatever Java code you like using the <% %> syntax.
You could also declare a method in some other utility JSP, using <%! %> syntax (note the !), import the JSP, and then call the method declared in such a block. This is bad style though.
Depending on the kind of action you'd like to call, there you normally use taglibs, EL functions or servlets for. Java code really, really doesn't belong in JSP files, but in Java classes.
If you want to preprocess a request, use the Servlet doGet() method. E.g.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Preprocess request here.
doYourThingHere();
// And forward to JSP to display data.
request.getRequestDispatcher("page.jsp").forward(request, response);
}
If you want to postprocess a request after some form submit, use the Servlet doPost() method instead.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Postprocess request here.
doYourThingHere();
// And forward to JSP to display results.
request.getRequestDispatcher("page.jsp").forward(request, response);
}
If you want to control the page flow and/or HTML output, use a taglib like JSTL core taglib or create custom tags.
If you want to execute static/helper functions, use EL functions like JSTL fn taglib or create custom functions.
Although I'll not advice you to do any java calls in JSP, you can do this inside your JSP:
<%
//Your java code here (like you do in normal java class file.
%>
<!-- HTML/JSP tags here -->
In case you're wondering, the <% ... %> section is called scriptlet :-)
Actually, jsp is not the right place to 'performs some operations on files'. Did you hear about MVC pattern?
If you still interested in calling java method from jsp you can do it, for example:
1. <% MyUtils.performOperation("delete") %> (scriptlet)
2. <my-utils:perform operation="delete"/> (custom tag)
Anyway I recomend you to google about scriptlets, jsp custom tags and MVC pattern.
Best Regards, Gedevan
On the surface, this question will sound a lot like questions that may have been asked previously on SOF but I tried those answers long ago and no luck.
(For example, this question spring 3 not rendering model in jsp)
So I had a Spring 2.0 Controller that extended CancellableFormController, and it contained the following to bind the Command Object to the Form on JSP page render:
public class MyFormController extends CancellableFormController {
....
protected Object formBackingObject(HttpServletRequest request) throws ServletException {
MyCommand myCommand = new MyCommand();
... // add some list info to command object etc in preparation for page render
return myCommand;
}
....
}
The JSP Page looked something like the following:
<form:form method="post" commandName="myCommand">
<c:forEach items="${myCommand.myList}" var="myItem" varStatus="index">
</form:form>
To be clear, between the form tag definitions, a list of items was displayed on the JSP page. This is before any form submission has occurred (ie. at page render time). And what a beautifully simple world we lived in. Everything worked first time and there was peace on earth... sorry, enough sarcasm! ;)
OK, so I happily tried to upgrade this old code to Spring 3 and annotations. My current problem is ONLY getting the Command object to render on page load. When I enter data into form fields and submit the form etc, the data gets bound correctly. What I am trying to do is pre-populate the Command object, and then render that content into the JSP page before the form is populated and submitted.
I initially tried this:
#Controller
#RequestMapping(value = "/myContextPath")
public class MyFormController {
...
#RequestMapping(method = RequestMethod.GET)
public ModelAndView initForm(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView("myTilesViewName");
MyCommand myCommand = new MyCommand();
...
mv.addObject("myCommand", myCommand);
return mv;
}
...
}
Then I tried each of the following methods (the Controller class construct being the same as the above):
#RequestMapping(method = RequestMethod.GET)
#ModelAttribute("myCommand")
public String initForm(HttpServletRequest request, HttpServletResponse response) throws Exception {
MyCommand myCommand = new MyCommand();
....
return "myTilesViewName";
}
#RequestMapping(method = RequestMethod.GET)
public String initForm(ModelMap model, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyCommand myCommand = new MyCommand();
...
model.addAttribute("myCommand", cmd);
return "myTilesViewName";
}
I don't wish to add any confusion. I "imagine" that the answer to this problem is likely the same if I were just returning the view name of a JSP page... However, I am using Apache Tiles to handle the page selection. My definition looks something like:
<definition name="myTilesViewName" extends=".myTemplate">
<put-attribute name="title" value="MyTitle" type="string" />
<put-attribute name="body" value="/WEB-INF/jsp/myPage.jsp" />
</definition>
Please remember everything worked perfectly before with the Spring 2 CancellableFormController code. I have not changed the Tiles config or JSP pages at all so don't believe they are the source of this problem.
Thank you so much to anyone who can offer any assistance. It is certainly appreciated!
UPDATE:
This issue finally related to a Client side (JSP page) related problem. My assumption that "nothing had changed other than in the Controller" was incorrect. Sincere apologies to those who took the time to read this post and consider solutions. For anyone else reading with the same symptoms, please double check your View pages (JSP) and ensure they are syntactically correct for rendering. In my case, I had moved a JSP (with around 2000 lines of code) into a subfolder and broken a relative link to a nested jsp import declaration.