When creating portlet in Liferay IDE, I have configured it to have Liferay's configuration mode. In response, the wizart created JSP file with the following text:
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
This is the <b>MyPortlet</b> portlet in Config mode.
How to call this page from Liferay to see this text? When clicking wrench icon and selecting Configuration I see nothing similar.
UPDATE
Path is set correctly because it was set by wizard.
The question is how to call this JSP from web interface by a mouse?
Usually the problem is that the path to the configuration jsp is not properly set.
In portlet.xml
Add the following:
<init-param>
<name>config-template</name>
<value>/path/to/configuration.jsp</value>
</init-param>
as a child of the <portlet> element that corresponds to the portlet you're trying to modify.
Your final portlet.xml should look something like:
<portlet-app>
<portlet>
<portlet-name>my-portlet</portlet-name>
<display-name>My Portlet</display-name>
<portlet-class>com.liferay.portlet.StrutsPortlet</portlet-class>
<init-param>
<name>config-template</name>
<value>/path/to/configuration.jsp</value>
</init-param>
<init-param>
<name>view-action</name>
<value>/my_portlet/view</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
</portlet>
</portlet-app>
From the wiki (no shame here though, took me a very long time to find it):
Add Config Page to Plugin Portlet <- get more info here
liferay-portlet.xml->
<portlet>
<portlet-name>configuration-example</portlet-name>
<icon>/icon.png</icon>
<configuration-action-class>com.sample.jsp.action.ConfigurationActionImpl</configuration-action-class>
<instanceable>true</instanceable>
<header-portlet-css>/css/test.css</header-portlet-css>
<footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
</portlet>
ConfigurationActionImpl.java (or your class)->
public class ConfigurationActionImpl implements ConfigurationAction {
public void processAction(PortletConfig config, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {
String portletResource = ParamUtil.getString(actionRequest, "portletResource");
PortletPreferences prefs = PortletPreferencesFactoryUtil.getPortletSetup(actionRequest, portletResource);
//Read, validate, and then set form parameters as portlet preferences
prefs.store();
SessionMessages.add(actionRequest, portletConfig.getPortletName() + ".doConfigure");
}
public String render(PortletConfig config, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
return "/configuration.jsp";
}
}
Configuration.jsp
<%# taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%# taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<portlet:defineObjects />
<form action="<liferay-portlet:actionURL portletConfiguration="true" />" method="post" name="<portlet:namespace />fm"> <input name="<portlet:namespace /><%=Constants.CMD%>" type="hidden" value="<%=Constants.UPDATE%>" />
Type: <select name="<portlet:namespace />type"> <option value="casual">Casual</option> <option value="formal">Formal</option> </select> <br/>
<input type="button" value="Save" onClick="submitForm(document.<portlet:namespace />fm);" /> </form>
"Note the portletConfiguration attribute in the liferay-portlet:actionURL tag."
Related
I have a spring MVC web application and using JSPs to create my web pages.
The problem is that when I directly submit a form the encoding is "application/x-www-form-urlencoded". When I submit the same data from the same form via an AJAX-Request the encoding is "application/x-www-form-urlencoded; charset=UTF-8".
I need the utf8 encoded characters typed in be a user in my controller. For example: A user types "äöüß" my controller gets "äöüÃ". When I send the data via an AJAX-Request I get "äöüß" which is correct.
What am I doing wrong? This is a simple form submit via http-post. It can't be impossible to do this utf8 encoded.
My application is running on a tomcat 8.5.11 with Spring 5.0.1. The web pages are all in HTML5 and I use the JSTL 1.2.5 in a servlet 3.1 environment. The JSON mapping and serialization is done by fasterxml 2.9.2
The configuration is completely Java-based.
My WebAppInitializer (a.k.a. web.xml)
...
#Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(),
new CharacterEncodingFilter("UTF-8", true, true) };
}
In my servlet config I explicitly set a charset for the StringHttpMessageConverter.
...
#Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
converters.add(new ResourceHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter());
}
The Webpage looks like
<%#page contentType="text/html;charset=UTF-8"%>
<%#page pageEncoding="UTF-8"%>
<%#page session="true" %>
<%#page trimDirectiveWhitespaces="true" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html lang="de">
...
<meta charset="UTF-8"/>
...
<form id="createArticleForm" action="<c:url value='/article/save' />" method="post">
<input type="hidden" name="utf8" value="✓" />
...
<input type="text" name="name" required="required" />
...
</form>
As you can see I also tried the utf8 hacks with a hidden field. But nothing works. Even if I set the form attributes accept-charset="UTF-8" and/or encoding="application/x-www-form-urlencoded; charset=UTF-8" nothing changes.
Edit1
I checked the HTTP Request Header sent from the browser to the server. And I found out that all parameters are correct. So I assume a spring configuration problem.
I found the solution myself. The problem lies in the initialiation of the characterEncodingFilter.
In a web.xml you do the following:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Since with Spring 5 Java-based Annotation Configuration is favored, according to the documentation you can do the following in your WebApplicationInitializer which is much simpler than the code above:
#Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(),
new CharacterEncodingFilter("UTF-8", true, true) };
}
BUT this is NOT working properly with every HttpRequest coming in!!!
The solution is to not use the provided convenient way to automatically map the filter to the servlet.
Instead you must:
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("characterEncodingFilter", new CharacterEncodingFilter("UTF-8", true, true));
filterRegistration.addMappingForUrlPatterns(null, false, "/*");
filterRegistration = servletContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter() );
filterRegistration.addMappingForUrlPatterns(null, false, "/*");
super.onStartup(servletContext);
}
And here you have your filter mapping back in sight and this works perfect!
This question already has answers here:
What causes "java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute"?
(7 answers)
Closed 6 years ago.
I am beginner to Spring MVC Framework. I started to learn Spring two days back. For learning purpose I am developing one simple Application. i.e., Get user input from form and display values in another page. I got an Exception " java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute". I cant figure out what's wrong in my code. I searched Google and tried many solution but the problem is still here.
Here is my view
index.jsp
<form:form action="/addDisplay" method="POST">
<form:label path="name"><h3>Name</h3></form:label>
<form:input type="text" path="name" cssClass="form-control text-center" required="required"/>
<form:label path="age"><h3>Age</h3></form:label>
<form:input type="number" path="age" cssClass="form-control text-center" required="required"/>
<form:label path="work"><h3>Work Place</h3></form:label>
<form:input type="text" path="work" cssClass="form-control text-center" required="required"/>
<form:label path="designation"><h3>Designation</h3></form:label>
<form:input type="text" path="designation" cssClass="form-control text-center" required="required"/>
<form:label path="area"><h3>Area</h3></form:label>
<form:input type="text" path="area" placeholder="Where Are You From?" cssClass="form-control text-center" required="required"/>
<form:label path="mobile"><h3>Mobile Number</h3></form:label>
<form:input type="number" path="mobile" placeholder="Your Mobile Number.!" cssClass="form-control text-center" required="required"/>
<form:label path="email"><h3>Email</h3></form:label>
<form:input type="email" path="email" placeholder="Your Email Id..!" cssClass="form-control text-center" required="required"/>
<br/>
<input type="submit" value="Generate" class="btn btn-success form-control"/>
</form:form>
myself.jsp
<div style="margin-top: 3%; font-size: 20px;">
<h3>My Introduction.</h3>
<p>
Hi, I am ${name} my age is ${age} and I am from ${area}. I am working as a ${designation}
in ${work}. You can contact me in my mobile ${mobile} and You can also shoot mail to
${email}.
</p>
</div>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringWork</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.infofaces.spring.form" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="com/infofaces/spring/form/MySelf" />
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
</beans>
My model name is Myself.java and it has private variables and getter, setter methods for that variable. Here is my controller.
HelloController.java
package com.infofaces.spring.form;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class HelloController {
#RequestMapping(value = "/display", method = RequestMethod.GET)
public ModelAndView display() {
return new ModelAndView("myself", "command", new MySelf());
}
#RequestMapping(value="/addDisplay", method = RequestMethod.POST)
public String addDisplay(#ModelAttribute("command") MySelf myself, ModelMap model) {
model.addAttribute("name",myself.getName());
model.addAttribute("age", myself.getAge());
model.addAttribute("work", myself.getWork());
model.addAttribute("designation", myself.getDesignation());
model.addAttribute("mobile", myself.getMobile());
model.addAttribute("email", myself.getEmail());
return "myself";
}
}
Full Stack Trace.
type Exception report
message java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:465)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:179)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:199)
org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:130)
org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)
org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:90)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:103)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.index_jsp._jspx_meth_form_005flabel_005f0(index_jsp.java:265)
org.apache.jsp.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:170)
org.apache.jsp.index_jsp._jspService(index_jsp.java:105)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Please help to find problem in my code. Thanks in advance.
You are missing commandName="command" in your index.jsp file .
<form:form action="/addDisplay" method="POST" commandName="command" >
Make sure that command object is available in your request attribute before index.jsp is being processed. I hope this would work.
EDIT : As you said in comment when you call index.jsp definatily you will get java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute error.
Because when your jsp is being rendered command object not available for that first you have to make request to controller , put object into Model name it command and then provide view name index.jsp
For example :
#RequestMapping(value = "/index", method = RequestMethod.GET)
public ModelAndView display() {
return new ModelAndView("index", "command", new MySelf());
}
Now you won't get that error. I hope this would work.
Instead of forwarding to your index.jsp via welcome-files list, you should add
<mvc:view-controller path="/" view-name="index"/>
to your mvc configuration, and an accompanying controller mapping where you will add the command object to the model, e.g.
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model model) {
model.addAttribute("command", new MySelf());
return "index";
}
Your problem is that you got forwarded to the index.jsp via welcome-files and the request wasn't process by spring. Yet you use spring's form:form which if not otherwise renamed via commandName or modelAttribute attributes expects an object with the key command inside the request attributes
you have used spring form tag in index.jsp where a command/modelAttribute object should be available as a request parameter to bind form data, which is you have not done and the exception message what it says.
To solve this problem follow below steps:
Step 1:
Remove all welcome-file-list from web.xml.
Step 2:
add "/" into display GET handler.
#RequestMapping(value = {"/", "/display"}, method = RequestMethod.GET)
public ModelAndView display() {
return new ModelAndView("myself", "command", new MySelf());
}
Step 3:
add modelAttribute name in form tag:
<form:form action="${pageContext.request.contextPath}/addDisplay"
method="POST"
modelAttribute="command">
Consider, you have HTML form like below
Login Form:
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<body>
<form:form action="doLogin.html" method="post" modelAttribute="loginEntity" name="loginForm">
<!-- Form inputs -->
</form:form>
</body>
</html>
You want to perform login by calling action doLogin.html. As you have specified modelAttribute="loginEntity" attribute in Spring form which is created using above code snippet. You must set an empty Object of model which hold required request params in Controller. Observe below code carefully:-
Model Class:
public class Login {
private String userName = "";
private String password = "";
// getters/setters
}
Controller Class:
#Controller
public class LoginController {
#RequestMapping(value = "/showLoginForm", method = RequestMethod.GET)
public ModelAndView showLoginForm() {
System.out.println("In login form...");
ModelAndView mv = new ModelAndView("login");
mv.addObject("loginEntity", new Login());
return mv;
}
#RequestMapping(value = "/doLogin", method = RequestMethod.POST)
public ModelAndView doLogin(#ModelAttribute Login login, BindingResult result) {
String userName = login.getUserName();
String password = login.getPassword();
if ("OO7".equals(userName) && "OO7".equals(password)) {
return new ModelAndView("forward:success.html");
} else {
return new ModelAndView("forward:failure.html");
}
}
}
In the controller, I have added an empty model new Login() for the modelAttribute loginEntity in the showLoginForm() function. This will map all the request parameters & allow to set &/or retrieve values from them.
Now, you can add link to your index.jsp which will give a call to Controller to display login.jsp just like below :-
Index Page:
<html>
<body>
<ul>
<li>Login</li>
</ul>
</body>
</html>
Overall Request Flow:
At application start index.jsp will load having a link to login.jsp.
On click of link Login a call to controller is made & it searches for request mapping showLoginForm in it.
Once he found the specified mapping, he proceed further to display login.jsp page.
On submit of the login form, a request for doLogin.html is made. Once again control goes to Controller to search for doLogin request mapping.
Once he found doLogin request mapping, depending on the login credentials, you will be redirected to either success.jsp or failure.jsp page.
NOTE:
Don't mix commandName & modelAttribute in Spring form. You are only allow to use any of them.
If you forgot to add empty model in the Controller, then you will face below exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for
bean name 'loginEntity' available as request attribute
I hope this will clear your idea of using #ModelAttribute in Spring.
How can I call a specific method in a class using this tag?
<jsp:useBean id="user" scope="??" class="com.example.User" type="com.example.User" />
Assuming your bean User has a method called getName()
<jsp:useBean id="user" scope="request" class="com.example.User" />
// ...
<h1>Hello <jsp:getProperty name="user" property="name" /></h1>
The scope could be something else than request : depends on what you want (session, page, etc)
EDIT: your second question was about calling a business method in your jsp
The fact is, you should not call business method into your JSPs. Your JSP pages should only display static (html, etc) and dynamic (beans for example) content. If you follow MVC pattern, business job is delegated to servlets. Your JSPs are only simple views (reading properties of beans) and are forbidden (in directory WEB-INF).
For your JSP pages, proceed as following:
Action of html form is your servlet controller (method POST)
Add hidden input to help servlet recognize what to do: <input
type="hidden" name="action" value="update" /> or <input
type="hidden" name="action" value="register" />
You can also display dynamic content (beans). For that, you should consider using JSTL.
Example (servlet sends an ArrayList of Movie beans on request scope):
<c:forEach items="${requestScope.results}" var="movie">
// ${movie.title}
// etc
</c:forEach>
For your servlet controller, proceed as following:
In doPost method (because we're using POST method in html form), you can dispatch business logic depending on action received: request.getParameter("action")
If action is update, then we perform update business logic.
If action is register, then we perform register business logic.
etc ...
Now, we can store some data in request scope to communicate to jsp page:
ArrayList<Movie> results = new ArrayList<Movie>();
results.add(new Movie(...));
// etc...
request.setAttribute("results", results);
And finally, send data and display jsp:
request.getRequestDispatcher("/WEB-INF/update.jsp").forward(request, response);
An example of web.xml (with a servlet mapped as welcome file index.jsp)
<servlet>
<servlet-name>Search</servlet-name>
<servlet-class>Servlets.Search</servlet-class>
</servlet>
<servlet>
<servlet-name>Register</servlet-name>
<servlet-class>Servlets.Register</servlet-class>
</servlet>
<servlet>
<servlet-name>Update</servlet-name>
<servlet-class>Servlets.Update</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Search</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Register</servlet-name>
<url-pattern>/Register.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Update</servlet-name>
<url-pattern>/Update.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp:useBean id="user" scope="request" class="com.example.User" type="com.example.User" />
<jsp:setProperty name="user" property="*" />
<c:set var="saveStatus" value="${user.save()}" />
I'm trying to build a Java servlet, and I've done everything according to the instructions my prof gave our class, but I'm getting a weird error.
Background: I'm working with Java EE Helios and Tomcat 7.
I started a new dynamic web project in Eclipse, I made an index.jsp page that just gets the user's name and sends it to the servlet, and is then supposed to print out Hello, [username]. The code is all sample code that the prof gave us and works for other people in my class.
I made a new Servlet called ServletHome and it's in a package called servlets.
When I run the program from Eclipse, it starts up Tomcat fine, no problems. I can navigate to the index.jsp page, and it looks fine.
The problem is that when I fill in my name and press my 'submit' button, I get a tomcat 404 error with the message:
"The requested resource (/MyFirstServlet/ServletHome) is not available."
Any ideas?
Thanks!!
--- Edit: Code ---
index.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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>Insert title here</title>
</head>
<body>
<form action="ServletHome" method="POST">
First Name: <input type="text" name="firstName" size="20"><br>
Last Name: <input type="text" name="lastName" size="20"> <br>
<br> <input type="submit" value="Submit">
</form>
</body>
</html>
ServletHome.java:
package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletHome extends HttpServlet {
private static final long serialVersionUID = 1L;
public ServletHome() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
}
/**
* The function that gets the name and returns an HTML file with Hello to them
* #param request
* #param response
* #throws ServletException
* #throws IOException
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
//set type of output
response.setContentType("text/html;charset=UTF-8");
//get writer
PrintWriter out = response.getWriter();
//get first name
String firstName = request.getParameter("firstName").toString();
//get last name
String lastName = request.getParameter("lastName").toString();
//write the file
out.println("<html>");
out.println("<head>");
out.println("<title>Test Title</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>Welcome, " + firstName + " " + lastName + "!</p>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>ServletHome</servlet-name>
<servlet-class>servlets.ServletHome</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletHome</servlet-name>
<url-pattern>/servlets/*</url-pattern>
</servlet-mapping>
</web-app>
The resource is no available because:
Your action attribute is wrong, or;
You didn't map your servlet corretly. To do this, you can:
Use #WebServlet annotation, since you are using Tomcat 7:
#WebServlet( name = "ServletName", urlPatterns = { "/path/to/your/servlet/myName" } )
public class ServletName extends HttpServlet {
// your code here
}
Or map your servlet in web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- more code here... -->
<servlet>
<servlet-name>ServletName</servlet-name>
<servlet-class>yout.package.here.ServletName</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletName</servlet-name>
<url-pattern>/path/to/your/servlet/myName</url-pattern>
</servlet-mapping>
<!-- more code here... -->
</web-app>
Another thing that you need to pay attention is that you MUST implement the doXXX methods that corresponds to the HTTP methods (get, post, etc.) that you want your servlet to serve.
To request this servlet through you form, you need to set the action attribute as:
<form action="/path/to/your/servlet/myName">
<!-- form fields here... -->
</form>
To finish, you can use the method attribute in your form to choose the HTTP method that your browser will use to request the Servlet. If you don't provide, the default method is get. As I already said, if the get method is used, you need to implement the doGet method in the servlet.
I'm using Struts 2 and the Display Tag table formatting tool to display query results from a database (a SELECT * query). I'm running into an odd error. After submitting a record to the database from Add.jsp, it takes me to View.jsp, where the table is correctly displayed. However, if I go to View.jsp directly, or via a hyperlink from the Add.jsp page WITHOUT submitting an entry to the database, it seemingly does not execute the methods necessary to retrieve the database entries into a variable to let the table display. In that case, I end up with a phrase, "nothing to display" where the table should be.
I was told this is most likely a problem with my method names, and the Struts 2 side of things, not any functionality on the Java side. I'm extremely new to Struts, and would appreciate some help at identifying and fixing the bugs. Some code excerpts are below, but I can post the whole thing if required. Also- no errors are shown when View.jsp is loaded, either after form submission or via direct link.
Add.jsp
<%# page contentType="text/html; charset=UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Add Development Environment</title>
</head>
<body>
<div id="main">
<h2>Add Development Environment</h2>
<p><s:a href="View.jsp">View Entries</s:a></p>
<s:actionerror />
<s:form action="doEntries.action" method="post" validate="true">
<s:textfield name="OS" key="label.OS" size="20" />
<s:textfield name="OSVersion" key="label.OSVersion" size="20" />
<s:textfield name="Note" key="label.note" size="20" />
<s:submit method="doEntries" key="label.submit" />
</s:form>
</div>
</body>
</html>
View.jsp
<%# page contentType="text/html; charset=UTF-8" language="java" %>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="display" uri="http://displaytag.sf.net" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/"WebContent/View.jsp"DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>View Development Environments</title>
</head>
<body>
<div id="main">
<h2>View Development Environments</h2>
<p><s:a href="Add.jsp">Add Entry</s:a></p>
<!--<s:set name="items" value="entries" scope="request"/>-->
<display:table name="entries" class="DevEnvironment" requestURI="" id="itemsList" export="false" pagesize="15">
<display:column property="did" title="id"/>
<display:column property="OS" title="Operating System"/>
<display:column property="OSVersion" title="Operating System Version" />
<display:column property="note" title="Note"/>
</display:table>
</div>
</body>
</html>
DatabaseAction.java
public class DatabaseAction extends ActionSupport{
private static final Logger logger = Logger.getLogger(DatabaseAction.class);
DBO myDBO;
private String OS;
private String OSVersion;
private String note;
private ArrayList<DevEnvironment> entries;
private double offset;
private double limit;
public DatabaseAction(){
super();
//connect to DB
myDBO = new DBO("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/devenvironments?user=root&password=mysqliscool");
}
public String doEntries(){
logger.info("puting stuff in DB! =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-==-=-=");
if(myDBO.connect() && myDBO.setEntry(OS, OSVersion, note)){
return "success";
} else {
return "error";
}
}
public ArrayList<DevEnvironment> getEntries() {
logger.info("-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=getEntries called");
entries = myDBO.getEntry(0, -1);
return entries;
}
public void setEntries(ArrayList<DevEnvironment> entries){
this.entries = entries;
}
public String retrieveEntries(){
logger.info("-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=retrieveEntries called");
if(myDBO.connect()){
logger.info("-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=EXECUTING SQL SELECT METHOD");
//entries = myDBO.getEntry(0, -1);
//offset, limit
return "success";
} else {
return "input";
}
}
Struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<package name="default" extends="struts-default" namespace="/">
<action name="doEntries" method="doEntries" class="net.josh.devenvironments.DatabaseAction" >
<result name="success">View.jsp</result>
<result name="input">Add.jsp</result>
</action>
<!--
<action name="retrieveEntries" method="retrieveEntries" class="net.josh.devenvironments.DatabaseAction" >
<result name="success">View.jsp</result>
<result name="input">Add.jsp</result>
</action>
-->
</package>
</struts>
You can get to the View.jsp because it is publicly accessible. As a rule put all JSP's under /WEB-INF the reason for this is that View.jsp will not make sense unless it is backed by an action. If you just go to View.jsp as you are now it does not go though an action it just hits the JSP directly and tries to parse it, the tags not finding any data probably gracefully fail (S2 tags typically do this, can't find the property just give up).
Now with the JSP under the /WEB-INF folder the only way to access it is with "doEntries" (you can leave off the dot action unless you're only filtering .action with s2 but if you don't have good reason you shouldn't be). Of course don't forget to update the action mapping to /WEB-INF/View.jsp
Now you could create another action called view to get there but if all it is going to do is the same thing as "doEntries" there really isn't any point, just use "doEntries".
When you get sick of writing XML (which is good practice but isn't really necessary) add the struts2-conventions-plugin to your class path. After it is added do the following:
Create a new package called struts2, create a class in it like this:
package struts2;
class HelloWorld extends ActionSupport{
public String greetings = "Hello from HelloWorld Class!";
}
Then create a jsp called "hello-world.jsp" under /WEB-INF/content
that has a
<s:property value="greeting"/>
tag now if you enter "hello-world" where index.html is probably located you'll see a little hello message... For most simple cases by following a simple Class to JSP naming convention you can avoid XML all together. If you don't like the convention you can easily override what you don't like, but if you add the conventions plugin to your class path both your xml and future conventions action will live in harmony.
PS: Yes I suppose the HelloWorld class should have getters and setters but it works just fine that way, and makes the example shorter.