I am curious if anyone knows if it is possible for a single portlet to contain multiple pages, let's say JSP pages. Furthermore is it possible to link to these different pages within the same portlet?
For example. Let's say I have a single portlet. And in this portlet I want the initial view to be a JSP page with just 5 links on it to 5 different JSP pages. And when a user clicked on one of these 5 links, it would load the appropriate JSP page into the portlet.
The end goal would basically be a little mini website all contained inside a portlet.
Now, I understand that this might not be the best use of a portlet, but for the sake of a project I am working on, I still would like to know if it is possible.
Thanks!
Sure, a portlet can contain more than one JSP.
You can display any JSP you want via the PortletRequestDispatcher in your doView (or doHelp or doEdit) method:
protected void doView(RenderRequest req, RenderResponse resp)
throws PortletException, IOException, UnavailableException {
resp.setContentType("text/html");
String myview = req.getParameter("myview");
String view = "/WEB-INF/jsp/" + (myview==null ? "bar" : myview) + ".jsp";
PortletRequestDispatcher dispatcher =
getPortletContext().getRequestDispatcher(view);
dispatcher.include(req, resp);
}
You could use a parameter to set the view. In the JSP with the links, you'd need to use the Portlet API to create/encode the links to the Portlet. For example:
<portlet:renderURL>
<portlet:param name="myview" value="foo"/>
</portlet:renderURL>
(I haven't really kept abreast of JSR286/Portlet 2.0 - this stuff should work with JSR168/Portlet 1.0 - so it is worth checking the new API if you're using it.)
Related
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:
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 want to develop a webapplication using Java. But I am quite confused what all these different technologies are and how they work together:
HTTP
HTML
CSS
Javascript
jQuery
Web Container
Servlets
JSP
JSTL
Expression Language (EL)
There is a huge amount of resources which can be found on the web regarding these topics, and each of them looks like you need to read several books to understand them. Can you explain these technologies so that I have a basic understanding of them when starting to develop a webapplication?
Note that the goal of this explanation is to give a general understanding, not to examine all the details of each topic. Experienced users will surely find points which seem to be "too general", but let's don't confuse new users. Links for further reading are provided in each topic.
Let's start with the fundamental basics. You need to know how a webpage comes to your computer in order to understand all the following technologies.
HTTP
HTTP stands for Hyper Text Transfer Protocol. It describes how the browser communicates with the webservers in order to retrieve their content (webpages). Webpages are stored on servers, and the browser needs a way to tell a server which webpage it would like to get. The server, on the other hand, needs to tell the browser if the requested resource was found or not and send this information to the browser.
The browser sends a request to the server. The request consists of several parts:
The URL, e.g. "https://stackoverflow.com/questions/ask", so the server knows which page to deliver.
The HTTP method. Most common are get, which indicates that the browser wants to retrieve information (e.g. a single page, or a websearch), and post, which indicates that the browser pushes some information to the webserver, like a forum post. Post usually changes something on the server (like the new post in a forum), while get does not.
Request body, which can contain for example the text of a textbox, an image to be uploaded, etc.
The server sends back a response, which is the answer of the browser's request. It consists of:
A HTTP status code. This is a three-digit-number which shows the result of the request. Most common are OK (2xx), REDIRECTION (3xx), CLIENT ERROR (4xx) and SERVER ERROR (5xx). Redirection status codes are the best way to redirect the browser to another page.
Response body, this contains the webpage (if any).
HTML
HTML stands for Hyper Text Markup Language and presents the content. HTML text is sent from the server to the client (which is, the browser) and is rendered by the browser to display it to the user. Example HTML:
<!DOCTYPE HTML>
<html>
<head>
<title>My first webpage</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
Since HTML has improved over the years, it is important that the first line of each HTML page contains the DOCTYPE declaration. It tells the browser how the different tags (like <p>) should be rendered. The rendering process is done by the browser. Everything, that is done by the browser on the local computer, is called client-side. Remember that term!
CSS
Means Cascading Style Sheets. This adds style to a webpage, like colors, font sizes, positions of elements, etc. CSS definitions are often kept in separate files to improve maintainability. Rendering of styles is also done client-side.
JavaScript
No, this has nothing to do with Java. Repeat: nothing. It is a totally different programming language that is executed by the browser on client-side. With JavaScript, you can include programming logic to your webpage and do things like:
Validating user inputs
Fancy slideshows
Even programming games!
You need to be aware of that JavaScript can be turned off in the browser, and then no JavaScript code will be executed. So you should not rely on the availability of JavaScript for your webapplication (except you have to, like for a game). JavaScript can be abused for things like redirection (where you should use HTTP status codes) or styling of elements (use CSS for that). So before doing something with Javascript, check if it is possible somehow else. Even dropdown menus are possible with only HTML and CSS!
jQuery
jQuery is nothing else than a library written in JavaScript. It becomes handy when you want to make your JavaScript cross-browser compatible, because different browsers have some minor differences in their JavaScript implementations. It is also useful for selecting certain elements of a page, effects, etc. It is still JavaScript, so it runs on client-side.
Web Container
This is a software which is located on your server and runs on server-side. Your webapplications are usually placed in a web container. It is the interface between client requests and your webapplication and does several things to make programming webapplications more comfortable. For example, Apache Tomcat is a web container.
Servlets
Now we get to the Java world. Servlets are part of your webapplication which is located on a server inside a web container, they run on server-side. Servlets are Java classes which process the request from the client and send back a response. A typical HTTP Servlet looks like this:
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML>");
out.println("<html>");
out.println("<head>");
out.println("<title>Hi</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>Hello World!</p>");
out.println("</body>");
out.println("</html>");
}
}
HttpServlet classes have several doXxx methods, one for each HTTP method, which can be overridden by the developer. Here, doGet is overridden, which means that this code is executed when a GET request is sent to this servlet. This method gets the request and response as parameters, HttpServletRequest and HttpServletResponse.
To make this Servlet accessible via a URL, the web.xml has to be configured:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.example.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
Now, a client can make a request to our servlet using GET and /hello as URL. For example, if our webapplication runs on www.example.com, correct URL to be used would be http://www.example.com/hello using GET.
JSP
Stands for Java Server Pages. As you have seen, using Servlets to send responses to the client is rather unhandy. Some clever guys had the idea: "What if we could just add Java code to HTML pages?" Well, and that's what JSP is:
<!DOCTYPE HTML>
<html>
<head>
<title>Hello JSP</title>
</head>
<body>
<%
for(int i=0; i<10; i++){
out.print("Loop number " + i);
}
%>
</body>
</html>
In fact, JSPs are translated to Java Servlet code (by the web container) and compiled. Really! It's no magic. That means, they are nothing else than Servlets! This is the equivalent Servlet code for the above JSP:
public class ServletAbc extends GenericServlet {
public void service(ServletRequest req,ServletResponse res)
throws ServletException, IOException{
PrintWriter out = res.getWriter();
out.println("<!DOCTYPE HTML>");
out.println("<html>");
out.println("<head>");
out.println("<title>Hello JSP</title>");
out.println("</head>");
out.println("<body>");
for(int i=0; i<10; i++){
out.print("Loop number " + i);
}
out.println("</body>");
out.println("</html>");
}
}
You see, all Java code is processed on server-side before the response is sent to the client.
JSTL
Stands for Java Standard Tag Library. Like the name says, it is a library which you need to include before you can use it.
JSPs with Java code are still not the best solution. It becomes very unreadable as the size of the pages grows, reduces maintainability and is difficult to read. So, what if we could just use additional tags to implement page flow, loops etc. and let Java classes do the programming logic? Welcome using tag libraries!
There are many tag libraries out there, and JSTL is the "basic" one, providing core functionality. This includes if/else constructs, loops, etc. It is included in JSPs, translated and compiled to Servlets and therefore runs on server-side.
EL
Means Expression Language and is used to evaluate expressions and to access values of Java objects you have created in Java classes. Usually, you combine Servlets, JSP, JSTL and Expression language:
A client request comes to a Servlet. The Servlet does some programming logic (like reading data from a Database) and stores some Java objects in the request. After that, it forwards the request to another resource on the server, like a JSP. Forwarding happens inside the webapplication and is not a redirect.
The JSP uses EL to access the Java objects in the request, displays them and sends the response to the client.
For example, this is your Servlet:
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// access databases, do calculations etc. here
String hello = "Hello world!";
String someBoolean = true;
request.setAttribute("helloObject", hello);
request.setAttribute("myBoolean", hello);
RequestDispatcher dispatcher = request.getRequestDispatcher("/result.jsp);
dispatcher.forward(request, response);
}
}
And the result.jsp:
<!DOCTYPE HTML>
<html xmlns:c="http://java.sun.com/jsp/jstl/core">
<head>
<title>Hello EL</title>
</head>
<body>
${helloObject}
<c:if test="${myBoolean}">
The expression is true.
</c:if>
</body>
</html>
This will output Hello world! The expression is true..
Things to keep in mind
I think I have shown clear enough what runs on server-side and what runs on client-side. Don't mix them up.
Always use the right tool for the right job. HTML for content, CSS for layout and style, Javascript for client-side programming logic. Don't rely on Javascript if you don't need it, some users have it turned off.
Most other technologies, like JSF, are built on top of existing technologies. Find out on what they are built on to understand where they are running (client, server) and what they are supposed to do.
How can I use Servlets to access the HTML uses of having JSP without having to have all my client-facing pages called *.jsp?
I would rather do this than using all the response.write() stuff because I think it is easier to read and maintain when it is all clean "HTML".
Is this is fair assesment?
EDIT: What I'm going for is having the Servlets output things to the screen without having to redirect to a .jsp file.
In this way, I could write all the JSP stuff, but when it comes time to display it, the page the URL the user sees is essentially, "http://blah.com/posts/post-id" which is the address of the servlet and not "http://blah.com/posts.jsp?pos=post-id".
But I would still write all presentation logic in an external .jsp.
Just hide the JSP away in /WEB-INF folder so that noone can access it directly and create a servlet which forwards the request to this JSP file. Don't do a redirect, else you will see the new URL being reflected in the address bar. E.g.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String postId = request.getPathInfo();
// Do your business thing here. Any results can be placed in request scope. E.g.
request.setAttribute("post", post); // post is a bean containing information you'd like to display in JSP.
// Then forward request to JSP file.
request.getRequestDispatcher("/WEB-INF/posts.jsp").forward(request, response);
}
Map this servlet on an url-pattern of /posts/*.
In the /WEB-INF/posts.jsp make use of taglibs to control page flow and EL to access the data. E.g.
<h2>${post.title}</h2>
<p><fmt:formatDate value="${post.date}" type="date" /> - ${post.message}</p>
Finally just invoke the servlet by http://example.com/posts/postid. The /postid part will be available by HttpServletRequest#getPathInfo(). You need to parse the value yourself and do the business thing with it.
I'm not entirely sure what you're asking here. You can ge servlets themselves to write HTML, but that's not clean at all.
An alternative is to get your servlets to create HTML via a templating engine, such as Velocity or Freemarker. The syntax in the templates may be cleaner for your particular application, if less fully featured.
Back in ancient times (think '98...) this was called a "Model 2 architecture": a servlet received the request, processed it, and handed the request over to a JSP page that handled the view.
See this article for one example of how this is done, or simply search for "JSP Model 2".
Edit: for that, you can use RequestDispatcher.include() instead of forward() as described in the previous article. The rest should still be applicable.
If I understand correctly you want to hide *.jsp extension from user, right?
In that case when your Servlet redirects to a jsp page have it do this:
RequestDispatcher disp = request.getRequestDispatcher("hidden.jsp");
disp.forward(request,response);
By using Request Dispatcher instead of redirect you "hide" your .jsp extension behind the servlet name. However in case your JSP page redirects to another JSP page this won't work.
If you want the .jsp file to be visible use response.encodeURL or response.sendRedirect
I think you're looking for the Front Controller Pattern - this is the basis of "JSP Model 2" web apps (as #andri mentioned) and pretty much all the (hundreds?) of Java web frameworks.
This question already has answers here:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
(6 answers)
Closed 5 years ago.
I've developed an application using Tomcat, Mysql and Servlets.
One of the options the user can choose is to see on the web browser the information of one of the tables of a database. When the user chooses this option a servlet is used. This servlet opens a connection to the data base and iterates over the rows, showing the information. This works without problems.
In order to show this information in the browser I'm using a lot of "out.println()" lines.
Although the functionality is implemented I'd like to know if there is any other way of showing this information on the browser. If anyone could name a method or provide me with links to examples it would be great.
thanks a lot.
Create a Javabean class which represents each item (row) of the table. Create a DAO class which returns a list of those items using JDBC. Then in the servlet, just put the list of items in the request scope using HttpServletRequest#setAttribute(), forward the request to a JSP file using RequestDispatcher#forward() and iterate over the list of items using JSTL (just drop jstl-1.2.jar in /WEB-INF/lib) c:forEach tag.
Basic kickoff example:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Item> items = itemDAO.list();
request.setAttribute("items", items); // It's now available as ${items} in EL.
request.getRequestDispatcher("/WEB-INF/result.jsp").forward(request, response);
}
where result.jsp look like this:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
...
<table>
<c:forEach items="${items}" var="item">
<tr>
<td>${item.someProperty}</td>
<td>${item.anotherProperty}</td>
</tr>
</c:forEach>
</table>
For more hints and examples you may find this article an useful starting point.
It's a Good Thing that you asked this. Putting presentation logic in a Servlet class is a bad practice. Any of those out.println() statements inside a Servlet class needs to be eliminated. It belongs in a JSP file.
To go some steps further, you can also use a MVC framework so that you basically end up with only a Javabean class and a JSP file (i.e. the role of the servlet have been taken over by the MVC framework).
Just choose one web framework among many
Try using Java Server Pages along with the JavaServer Pages Standard Tag Library. JSP's with JSTL is a way of using html like syntax (xml) to create dynamic Java web pages. JSP's are converted to Servlets at runtime.
There are many different ways to achieve the same ( thanks to the abundance of web frame works)
To list a few:
Pure Servlets (As you have done)
Servlet + JSP
Servlet + JSP ( using JSTL)
Struts frame work involving JSP and action classes
Spring webflows (involves JSP)
Velocity, Tapestry, Cocoon, Stripes ( all require JSP knowledge) ... and it is endless
An ideal way is to separate content out of Servlets.
Content should go into pages such as JSPs. Servlets' out.println is so.. 90s.
Java web technology has come a long way since then.
Cheers!