I've got an Enum class that stores the name and some relevant numbers for 10 different materials.
In my HTML page I want to select one material via a drop down. Therefore I iterate over them via JSTL. I used to have a scriplet for that but I replaced it now. This is my code:
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
if (session.getAttribute("materialArray") == null) {
session.setAttribute("materialArray", Material.values());
}
request.getRequestDispatcher("/jsp/input.jsp").forward(request, response);
}
JSP-Page:
{...}
<h2>
<fmt:message key="input.label.material" />
</h2>
<select name="s_material" id="s_material">
<c:set var="MaterialEnum" value="${materialArray}" />
<c:forEach items="${MaterialEnum}" var="material">
<option value="${material}"><c:out
value="${material.description}"></c:out></option>
</c:forEach>
</select>
{...}
Problem: When I click 'Run project on server' in eclipse and visit the URL in Chrome it works fine.
But when I export the project to a WAR file and deploy it on a server (same tomcat version, different machine) the drop down doesn't fill and I get a NullPointerException for Material.values(). Also when I look at it in the eclipse intern browser, the material drop down menu isn't filled. (I used System.out.println() in doGet() to check if it does anything, it only prints the materials when accessing the page via Chrome. In internal browser it simply prints nothing.)
Why? Is there a way to bypass these enum-methods .values() and .valueOf() (which I use later to process the selected value from the drop down)? Are there differences in when doGet() is called?
(The scriplet I used before worked in both environments.)
Related
I am working on DXP portal 7.2 and creating a CRUD application (Course) w Service Builder. When Delete task is performed on my data table, it works fine however the portal page is redirecting to a non available mode, example it says: Course is temporarily unavailable.
Please let me know what part I am doing wrong. thank you so much!
My view.jsp Delete part looks like this:
<%-- Delete action. --%>
<td>
<liferay-portlet:renderURL var="deleteURL">
<liferay-portlet:param name="mvcRenderCommandName" value="<%=ConstantsCommands.DELETE_COURSE %>"/>
<liferay-portlet:param name="backURL" value="<%= currentURL %>"/>
<liferay-portlet:param name="courseId" value="<%=
String.valueOf(course.getCourseId()) %>"/>
</liferay-portlet:renderURL>
<liferay-ui:icon-menu>
<liferay-ui:icon url="${deleteURL }" message="delete" >
</liferay-ui:icon>
</liferay-ui:icon-menu>
</td>
</tr>
Below is my MVC Render command Snippet for my Delete:
public class CourseDeleteMVCRenderCommand implements MVCRenderCommand{
#Override
public String render(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException {
long courseId = ParamUtil.getLong(renderRequest, "courseId");
try {
// Call service to delete the course.
_courseService.deleteCourse(courseId);
// Set success message.
SessionMessages.add(renderRequest, "courseDeleted");
}catch (PortalException pe) {
// Set error messages from the service layer.
SessionErrors.add(renderRequest, "serviceErrorDetails", pe);
}
return null;
}
#Reference
protected CourseService _courseService;
}
Use MVCRenderCommand and liferay-portlet:actionURL, using render url is possible but wrong.
The error comes from missing mvcPath paramenter in renderURL. Liferay does not know the destination jsp.
Some sample here
jsp: https://github.com/liferay/com-liferay-commerce/blob/abf23f6175549f302f8b18ce5c0407c969a2e7bd/commerce-subscription-web/src/main/resources/META-INF/resources/subscription_entry_action.jsp
action class: https://github.com/liferay/com-liferay-commerce/blob/abf23f6175549f302f8b18ce5c0407c969a2e7bd/commerce-subscription-web/src/main/java/com/liferay/commerce/subscription/web/internal/portlet/action/EditCommerceSubscriptionContentMVCActionCommand.java
Most important: "Thou shalt not change state in a render operation."
You're looking for an actionURL, and an MVCActionCommand to execute the operation (change state). Potentially a separate render, but that's often prior to the action (e.g. showing a particular option, with the possibility to delete it (if you don't have the delete button on your main UI)
Implementing a destructive operation within a UI rendering is just wrong and I'd recommend to go through any tutorial you find to learn the difference between action- and render-phase in a portlet. They're separated for a reason.
Typically, right after an actionCommand is executed, the UI is rendered.
On top, quite a critical part of a MVCRenderCommand as well as an MVCActionCommand is the #Component annotation (assuming you're taking the OSGi route)
I have the following project structure:
I am trying to navigate to concerts.jsp from index.jsp:
index.jsp
<li class="active">Concerts</li>
This is my ConcertsController:
#WebServlet("/ConcertsController")
public class ConcertsController extends HttpServlet {
private static final long serialVersionUID = 1L;
public ConcertsController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
request.getRequestDispatcher("/WEB-INF/pages/concerts.jsp").forward(request, response);
}
...
}
When I run the app, and click on the link in index.jsp, localhost:8080/ConcertsController URL opens and I get the
The requested resource is not available
error.
Edit 1: I am using Tomcat v7.0, servlets v3.0 and Java 8.
Edit 2 (possible duplicate): Well, surely I need to be able to do this without using the jstl library.
Edit 3: When localhost:8080/ConcertsController opens, I get the "resource not found" error. But when I manually edit the url to localhost:8080/AppName/ConcertsController, it works.
URL localhost:8080/ConcertsController means Application name is ConcertsController, port number is 8080 and the application is run locally. But you do not have ConcertsController Application.
so you are getting error
The requested resource is not available
There are 2 solutions
if you are not using JSTL.
Change <a href="/ConcertsController"> to <a href="<%${pageContext.request.contextPath}%>/ConcertsController">
If JSTL is used then <c:set var="contextPath" value="${pageContext.request.contextPath}" />
and then
change <a href="/ConcertsController"> to <a href="${contextPath}/ConcertsController">
Use
<a href="${pageContext.request.contextPath}/ConcertsController">
Also when forwarding the request to cencerts.jsp use ServletContext.getRequestDispatcher(....)
ServletRequest.getRequestDispatcher() method will evaluate the path relative to the path of the request. But for the method of ServletContext, the path parameter cannot be relative and must start with /( / means at the root of web application not current relative path).
Try using the following:
request.getRequestDispatcher("/pages/concerts.jsp").forward(request, response);
instead of:
request.getRequestDispatcher("/WEB-INF/pages/concerts.jsp").forward(request, response);
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
I have a doubt regarding the use of servlets.
In the application I'm building I use Html pages to ask the user for info.
Imagine a Html page that lets the user request to see on the screen the content of a data base. What I'm doing is:
1.- From the Html page I'm calling a servlet that will open a connection with the database.
2.- The servlet builds the web page that the user will see.
My question is: is there any other way of doing this? Do I have to build the web page in the servlet or is there any way of sending the information contained in the database to an .html file which will build the web page (in my case I need to show on the screen a table containing all the information) ?
Thanks
Servlets are meant to control, preprocess and/or postprocess requests, not to present the data. There the JSP is for as being a view technology providing a template to write HTML/CSS/JS in. You can control the page flow with help of taglibs like JSTL and access any scoped attributes using EL.
First create a SearchServlet and map it on an url-pattern of /search and implement doGet() and doPost() as follows:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Preprocess request here and finally send request to JSP for display.
request.getRequestDispatcher("/WEB-INF/search.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Postprocess request here. Get results from your DAO and store in request scope.
String search = request.getParameter("search");
List<Result> results = searchDAO.find(search);
request.setAttribute("results", results);
request.getRequestDispatcher("/WEB-INF/search.jsp").forward(request, response);
}
Here's how the JSP /WEB-INF/search.jsp would look like, it makes use of JSTL (just drop JAR in /WEB-INF/lib) to control the page flow.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<form action="search" method="post">
<input type="text" name="search">
<input type="submit" value="search">
</form>
<c:if test="${not empty results}">
<p>There are ${fn:length(results)} results.</p>
<table>
<c:forEach items="${results}" var="result">
<tr>
<td>${result.id}</td>
<td>${result.name}</td>
<td>${result.value}</td>
</tr>
</c:forEach>
</table>
</c:if>
Note that JSP is placed in /WEB-INF to prevent users from direct access by URL. They are forced to use the servlet for that by http://example.com/contextname/search.
To learn more about JSP/Servlets, I can recommend Marty Hall's Coreservlets.com tutorials. To learn more about the logic behind searchDAO, I can recommend this basic DAO tutorial.
To go a step further, you could always consider to make use of a MVC framework which is built on top of the Servlet API, such as Sun JSF, Apache Struts, Spring MVC, etcetera so that you basically end up with only Javabeans and JSP/XHTML files. The average MVC frameworks will take care about gathering request parameters, valitate/convert them, update Javabeans with those values, invoke some Javabean action method to process them, etcetera. This makes the servlet "superfluous" (which is however still used as being the core processor of the framework).
In addition to Servlets, Java has JSP pages, which are a mix of HTML and custom tags (including the Java Standard Tag Library or JSTL) which are eventually compiled into Servlets.
There are other technologies for making web applications, including things like Java Server Faces (JSF), Apache Struts, Spring, etc... Spring in particular is very widely used in modern web application development.
Ultimately, though, it's like Brian Agnew said... you have to communicate back and forth from the browser to the server. These are just various technologies to facilitate that.
Ultimately the browser has to send a request to the server for the database info. You can do this in many ways:
build the whole page in the servlet (perhaps the simplest)
build a page in the servlet containing (say) XML data, and the browser renders it into HTML (via XSL/Javascript etc.). That may be suitable if you want the browser to control the formatting and presentation.
build a page containing AJAX requests to go back to the server and get the data. That may be more suitable for data that updates regularly, or more interactive applications.
There are numerous ways to skin this cat. I suspect you're doing the simplest one, which is fine. I would tend towards this without explicit requirements that mean I need to do something else. Further requirements that complicate matters may include paging the data if there's too much to fit on the screen. All the solutions above can be made to incorporate this in some fashion.
My java is rusty but...
in your Data Access layer, iterate over the result set and build a custom object and insert it into an ArrayList;
class DataAccess {
public ArrayList foo() {
// Connect to DB
// Execute Query
// Populate resultSet
ArrayList result = new ArrayList();
while (resultSet.hasNext()) {
CustomObject o = new CustomObject();
o.setProperty1(resultSet.getInt(1));
o.setProperty2(resultSet.getString(2));
// and so on
result.add(o);
}
return result;
}
}
Call this method from your Servlet. After you have populated the ArrayList, put it on the Request object and forward on to your .jsp page
ArrayList results = DataAccessClass.foo();
Request.setAttribute("Results", results);
In your jsp, build your markup using scriptlets
<% foreach (CustomObject o in Request.getAttribute("Results"))
{%>
<td><%= o.getProperty1()</td>
<td><%= o.getProperty2()</td>
<% } %>
Good luck
For a customer, I need to write a Servlet which can print values in a form post. The form is hosted on another server and looks somewhat like this:
<form action="http://myserver/myServlet" method="POST">
<input type="text" id="someName" value="someInterestingValue"/>
<input type="submit" value="submit" />
</form>
I have a Tomcat 5.0.28 server available, running on a Java 1.4 jdk, so I made a simple servlet:
public class ProxyServlet extends HttpServlet {
public void doPost(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
PrintWriter out = res.getWriter();
Enumeration a =req.getAttributeNames();
while (a.hasMoreElements()){
String attrname = (String) a.nextElement();
out.println(attrname+"="+req.getAttribute(attrname)+"<br/>");
}
out.close();
}
}
When I go to the servlet by URL everything looks as expected. When I send a GET request with some parameters, I can see those as attributes in the debugger in the doGet() method (method was left out for brevety).
However, in the doPost(), my form fields seem to be missing. I've looked into the Tomcat logfiles, and nothing special is logged. I tried to add a crossdomain.xml to some directories but did not find a way to change this behaviour.
So to be clear: The Form as listed above is on server A. My servlet runs on an existing legacy Tomcat/Java application hosted on server B. When the form is of type "POST" none of the fields arrive at the Servlet on server B. Apache is NOT "in front" of Tomcat.
Is there some configuration setting I am missing in Tomcat?
Any tips or suggestions where to look next?
Help is greatly appreciated.
Request attributes? Don't you need to access them as request parameters using HttpServletRequest#getParameter() and so on?
Which adds more confusion is that you said that it works in the doGet(). How does its code look like then? Does it also access them as attributes? That would in a normal JSP/Servlet environment (i.e. you aren't using some filter which copies the parameters to attributes or so) have been impossible.
This has nothing to do with cross-site. As BalusC said, use getParameter... instead of getAttribute... methods
Found the problem. After a whole day of searching and coding, it all boils down to the fact that my code was working fine. The problem is in the form. the line:
<input type="text" id="someName" value="someInterestingValue"/>
Should read:
<input type="text" name="someName" value="someInterestingValue"/>
For people mentioning "getParameter" instead of "getAttribute" you are totally correct. In my test code I had both just to be sure (because I thought I lost it...) but both were not returning results, as the browser was simply not sending the name/value pairs.
I guess posting this on Stackoverflow did help, because I had to explain and re-read my problem I thought the "id=" looked funny. Coding is finding bugs in pieces of text you are overlooking...