I am starting to study struts 2. I followed the example here.
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.devMode" value="true" />
<package extends="struts-default">
<action name="hello"
class="com.tutorialspoint.struts2.HelloWorldAction"
method="execute">
<result name="success">/HelloWorld.jsp</result>
</action>
</package>
</struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>HelloWorld3</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>
</web-app>
index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>Struts2</h1>
<form action="hello">
<label for="name">Please enter your name</label><br/>
<input type="text" name="name"/>
<input type="submit" value="Say Hello"/>
</form>
</body>
</html>
HelloWorldAction.java
package com.tutorialspoint.struts2;
public class HelloWorldAction{
private String name;
public String execute() throws Exception {
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
But after running and submitting the form, 404 error occurs.
type: Status report
message: /HelloWorld3/hello
description:The requested resource (/HelloWorld3/hello) is not available.
It does not produce any error in the console. I think the action class is not getting mapped. I know this kind of error is common to all struts beginners but I swear I've been googling this since yesterday.
struts.xml is inside /src/, I also tried putting it inside WEB-INF/classes, still got no luck.
I'm using eclipse gallileo and tomcat 6 inside it.
Replies are really appreciated.
My bad, just realized the web.xml is not the same with the web.xml in the tutorial. Also I forgot to specify the package name in struts.xml. After correcting these, I then encountered an error in the console,
java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
To solve this problem I added commons-lang3-x.y in the WEB-INF/lib directory together with other jars required by the tutorial to be added.
your class could extend ActionSupport class or Action Interface then only it will become an action class. And no need call the method execute explicitly by default it will call execute method. If you were overriding it you need to mention that method name.
And it's not mandatory to use ActionSupport class. This is basically a helper class which provides many out of the box features for you, but at same time Struts2 framework do not ask to use this class, all it want is an entry method for your action class with return type as String and which can throw a general Exception
beside validation or Internationalization this class also provides many other features like Action level Errors etc.
<action name="hello"
class="com.tutorialspoint.struts2.HelloWorldAction">
package com.tutorialspoint.struts2;
public class HelloWorldAction extends ActionSupport{
private String name;
public String execute() throws Exception {
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
add commons-lang3.x.y.z jar and commons-fileupload-x.y.z jar to your buildpath to avoid 'resource not available' error
http://viralpatel.net/blogs/tutorial-create-struts-2-application-eclipse-example/
You can get the Simple Struts 2 Example Demo with the jar files.
Related
This question already has answers here:
"The Struts dispatcher cannot be found" error while deploying application on WebLogic 12.1.3
(2 answers)
Closed 1 year ago.
I started implementing "hello world" program in struts2 but got following error on running the web application:
org.apache.jasper.JasperException: The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag. - [unknown location]
Files of my project are:
index.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
<s:property value="msg" default="guest"></s:property>
<s:form action="demostrutsclass">
<s:textfield name="username"></s:textfield>
<s:submit value="submit"></s:submit>
</s:form>
</body>
</html>
web.xml
<%--
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
<s:property value="msg" default="guest"></s:property>
<s:form action="demostrutsclass">
<s:textfield name="username"></s:textfield>
<s:submit value="submit"></s:submit>
</s:form>
</body>
</html>
--%>
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<struts>
<package name="pak" extends="struts-default">
<action name="demostrutsclass" class="pak.demostrutsclass" method="execute">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
demostrutsclass.java
package pak;
public class demostrutsclass {
private String username;
private String msg;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String execute(){
msg = "hi, "+username;
return "success";
}
}
All essential libraries from struts-2.5.26 are already added.
This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag.
You are likely hitting index.jsp without an associated action. Since your index.jsp page has S2 tags, there must be an action.
There are multiple solutions; which makes the most sense depends on your needs. You can either have index.jsp not use S2 tags, or you can set up your welcome page to be an action instead of a "raw" JSP.
I am trying to upgrade struts version from 2.3.35 to 2.5.17 but I encountered an issue as below:
java.lang.NullPointerException
at com.opensymphony.xwork2.util.fs.StrutsJarURLConnection.getInputStream(StrutsJarURLConnection.java:170)
at com.opensymphony.xwork2.util.fs.JarEntryRevision.needsReloading(JarEntryRevision.java:84)
at com.opensymphony.xwork2.util.fs.DefaultFileManager.fileNeedsReloading(DefaultFileManager.java:65)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.needsReload(XmlConfigurationProvider.java:428)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.needsReload(StrutsXmlConfigurationProvider.java:163)
I have been using this guide to migrate to struts version 2.5.17:
https://cwiki.apache.org/confluence/display/WW/Struts+2.3+to+2.5+migration
I suspect it to be issue with tiles.
I have upgraded all struts related jar to version 2.5.17 including struts2-tiles-plugin. I have also upgraded all tiles related jars to 3.0.7.
Also I have removed the Xwork-core jar as from 2.5 xwork being merged to struts2-core jar.
Am I doing anything wrong.
Please note: I have not done any code changes as of now. The code works perfectly with struts version 2.3.35. But as soon as I have upgraded the struts version along with tiles version I started getting this issue.
Can some one please suggest If I am doing anything wrong?
Yes, there are supposed to be errors without code changes.
I don't think you are doing something wrong.
After adding the new .jars and removing the old ones it will only work when the code is compliant with the new framework.
Code changes would be:
.xml
Add the following <code> to web.xml.
<filter>
<filter-name>struts2</filter-name>
<filter-class> org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
Change struts-config.xml to struts.xml and make following changes:
You can remove struts-config.xml completely and use annotations instead of .xml file.( since struts 2.5.17 )
<?xml version="1.0" encoding="ISO-8859-1" ?> <!-- change to UTF-8 -->
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd "> <!-- change to struts-2.5.dtd -->
<struts-config> <!-- change to <struts> -->
<!-- add <include file="struts-default.xml"/> -->
<form-beans>
<form-bean name="MyClassForm" type="forms.MyClassForm">
</form-bean>
</form-beans>
<action-mappings> <!-- change to <package name="hello-default" extends="struts-default"> -->
<action path="/MyClass" name="MyClassForm" type="actions.MyClassAction"
validate="false">
<action name = “MyClass” class = “actions.MyClass”>
<forward name="success" path="/Index.jsp"/>
<result> /Index.jsp </result>
</action>
</action>
</action-mappings> <!-- change to </package> -->
<message-resources parameter="resources"/>
</struts-config> <!-- change to </struts> -->
.java
Remove ActionForm.java files.
Properties are included in ActionSupport class which our Action class is supposed to extend.
Change Action.java
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class MyClassAction extends Action // change to ActionSupport {
//fields are now a property of the ActionSupport class
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// change to public String execute() throws Exception {
MyClassForm input = (MyClassForm) form; // don't need this
input.setField1(“Hello”); // change to setMessage(“Hello”);
return mapping.findForward(“success”); // change to return Action.SUCCESS;
.jsp
Actions to be performed in this JSP are:
Replace <%# taglib %> directive
Use new set of tags defined by the struts-tags.tld
<%# taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello!</title>
</head>
<s:form action="submit.action" method="post">
<body>
<s:textfield label="Name" name=" field1" />
<s:property value="field1"/>
<s:submit" />
</body>
</s:form>
</html>
Cheers.
I got this resolved by upgrading struts version to 2.5.18. It also worked fine when I downgraded the struts version to 2.5.13.
But it is not recommended to use struts version between 2.5.16 and 2.3.36 (inclusive), so I have upgraded it to 2.5.18
I'm trying to make a simple JSF hello world, with JSF 2.0, JBoss AS 7.0
Here's my xhml file :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Page 1</title>
</h:head>
<body>
<f:view>
<h:outputLabel value="Hello Stock Manager Hello JSF again" />
<br/>
<h:outputLabel value="Tester Bean : #{testerBean.message}" />
</f:view>
</body>
</html>
and here's the managed bean class :
package prv.stockmanager.web.beans;
public class TesterBean {
private String message = "This is a message";
public TesterBean() {
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
And here's the faces-config (which is in the web-inf) :
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
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-facesconfig_2_0.xsd">
<managed-bean>
<managed-bean-name>testerBean</managed-bean-name>
<managed-bean-class>prv.stockmanager.web.beans.TesterBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property> <property-name>message</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
</managed-bean>
</faces-config>
The page works fine without exception if I remove the call to the managed bean. But when I call the managed bean I get this :
Bean or property class prv.stockmanager.web.beans.TesterBean for managed bean testerBean cannot be found.
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:265) [jsf-impl-2.1.3-b02-jbossorg-2.jar:2.1.3-SNAPSHOT]
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244) [jsf-impl-2.1.3-b02-jbossorg-2.jar:2.1.3-SNAPSHOT]
Is it because JBoss AS 7.0 is using JSF 2.1 jar file or something? Should I use JSF 2.1 then? How to change that?
Problem resolved, I figured out that Eclipse is not generating the class. I disabled the automatic build and it worked fine. There should be a problem with JBoss Studio that I am using.
I'm writing a simple custom function in Facelets with a sample method. The problem is that the JSF 2 application fails to locate that function. The error message is:
/test.xhtml #15,73 rendered="#{test:isGranted('ONE_ROLE')}" Function 'test:isGranted' not found.
I've been checking and rechecking and can't find the problem. Any comment here would be really appreciated as it's clear that I'm missing something (but it seems that the steps involved are really simple).
Do you know if there are other requisites?
Thanks in advance.
The relevant code:
In the web.xml the tag XML descriptor is declared
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/test.taglib.xml</param-value>
</context-param>
The file test.taglib.xml:
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.test.com/security/tags</namespace>
<function>
<function-name>isGranted</function-name>
<function-class>com.test.security.taglibs.IsGranted</function-class>
<function-signature>boolean isGranted(java.lang.String role)</function-signature>
</function>
</facelet-taglib>
The tag class:
public class IsGranted extends TagHandler {
public static boolean isGranted(String role) {
// Do nothing. Just a test.
return false;
}
}
And the test file:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:test="http://www.test.com/security/tags">
<body>
<h:outputText value="You should NOT see this." rendered="#{test:isGranted('ONE_ROLE')}"/>
</body>
</html>
In your example you are declaring the sec namespace prefix but use the test prefix in your function call. But maybe that was just a copying mistake.
Another possible cause would be the header of your taglib file, which uses the facelets 1.0 DTD instead of the JSF 2.0 version. This might be problematic depending on your JSF implementation, for example for MyFaces see this bug report and discussion thread. The header for a JSF 2.0 taglib would be:
<facelet-taglib version="2.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-facelettaglibrary_2_0.xsd">
I'm using GlassFish 3.1, and trying to pass parameter to commandButton action. Following is my code:
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_0.xsd" />
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.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-facesconfig_2_0.xsd" />
ManagedBean class
package actionParam;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named("bean")
#RequestScoped
public class ActionParam {
public ActionParam() {
super();
}
public String submit(int param) {
System.out.println("Submit using value " + param);
return null;
}
}
and finally,
View
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1" />
<title>Test Action Param</title>
</h:head>
<h:body>
<h:form id="actionForm">
<h:commandButton id="actionButton" value="Submit"
action="#{bean.submit}">
<f:param name="param" value="123"></f:param>
</h:commandButton>
</h:form>
</h:body>
</html>
When I click submit button, I get javax.el.MethodNotFoundException.
If I remove <f:param ... /> and pass parameter as follows,
.
:
<h:commandButton id="actionButton" value="Submit"
action="#{bean.submit(123)}">
</h:commandButton>
:
.
it works OK.
But I was thinking first way (using f:param) is correct one.
Which is the correct way to pass parameter?
Thanks in advance.
The <f:param> sets a HTTP request parameter, not an action method parameter. To get it, you would need to use <f:viewParam> or #ManagedProperty. In this particular case, the latter is more suitable. You only have to replace CDI annotations by JSF annotations in order to get #ManagedProperty to work:
#ManagedBean(name="bean")
#RequestScoped
public class ActionParam {
#ManagedProperty("#{param.param}")
private Integer param;
public String submit() {
System.out.println("Submit using value " + param);
return null;
}
}
When you're targeting a Servlet 3.0 container (Tomcat 7, Glassfish 3, JBoss AS 6, etc) with a web.xml whose <web-app> root declaration definies Servlet 3.0, then you should be able to just pass the parameter straight into the action method by EL as that's supported by EL 2.2 (which is part of Servlet 3.0):
<h:commandButton id="actionButton" value="Submit"
action="#{bean.submit(123)}">
</h:commandButton>
with
public String submit(Integer param) {
System.out.println("Submit using value " + param);
return null;
}
If you target an old Servlet 2.5 container, then you should still be able to do this using JBoss EL. See also this answer for installation and configuration details: Invoke direct methods or methods with arguments / variables / parameters in EL