Struts 2 add an action to struts.xml - java

I want to add an action to my struts.xml but when I do it my webapp stop to work and I don't know why. I post here some details of my webapp.
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>ILIMobileLeborgne</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
struts.xml (in the src folder in Eclipse):
<?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" />
<constant name="struts.custom.i18n.resources" value="ilimobile" />
<package name="ilimobile" namespace="/" extends="struts-default">
<action name="index">
<result>/index.jsp</result>
</action>
<action name="registerIllimite">
<result>/registerIllimite.jsp</result>
</action>
<!-- When i try to do add the following action my app doesn't working, the browser said me that the ressource asked is unavailable and when i delete it my (little) app works correctly -->
<action name="registerClientInfo" class="action.SubscribeAction">
<result name="success">/paiement.jsp</result>
</action>
</package>
</struts>
my SubscribeAction (in the action package in the source folder) :
package action;
import model.*;
import com.opensymphony.xwork2.ActionSupport;
public class SubscribeAction extends ActionSupport {
private Client client;
private String abonnement;
public String getAbonnement() {
return abonnement;
}
public void setAbonnement(String abonnement) {
this.abonnement = abonnement;
}
#Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
And my JSP page which use the action defined :
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# 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>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="registerClientInfo">
<s:textfield key="client.nom"/>
<s:textfield key="client.prenom"/>
<s:textfield key="client.email"/>
<s:textfield key="client.adresse"/>
<s:textfield key="client.ville"/>
<s:textfield key="client.cp"/>
<s:submit/>
</s:form>
</body>
</html>
If you need some extra info ask me but i think you could see why my app doesn't want to work :/ I'm pretty sure that it's just a little error but i can't find it...
Thanks for all and have a happy new year party :)
(Sorry for my English I'm a french student ^^)
Edit : I post here the Eclipse stack trace which show me that he can't find my action class but i don't know why :/ I've a struts example made by my teacher and i don't think that he made some extra steps to deploy the app with a tomcat server on Eclipse
The stack trace :
Unable to load configuration. - action - file:/home/blackmario/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ILIMobileLeborgne/WEB-INF/classes/struts.xml:20:68
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:70)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:429)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:471)
at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:277)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:382)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:103)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4650)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5306)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: Action class [action.SubscribeAction] not found - action - file:/home/blackmario/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ILIMobileLeborgne/WEB-INF/classes/struts.xml:20:68
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.verifyAction(XmlConfigurationProvider.java:480)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:424)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:541)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:290)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:239)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
... 18 more

So, it sounds like your application fails to start when you add that action, correct? Nothing works, even the ones that worked before. So, you should look in the logs of the servlet container you are using. Nothing is more fundamental that finding where the logs are and becoming familiar with them.
When you do look in the logs, I'm guessing you'll see either
1) an error complaining that the syntax of the struts.xml is bad and the application fails when trying to parse it.
or
2) A ClassNotFoundException because the class file for that action is not on the classpath of the application. If this is the case make sure that the class files for that action are actually being put into the WAR file's WEB-INF/lib or WEB-INF/classes direcgtory; that's where a webapp's classloader looks for class files. If you don't know much about this, you should read more about Java Servlets.
Both of these are things that might cause the application to not successfully start. You must look at the logs; they will amost always tell you that the application had a specific issue. If you ask about that specific issue on this forum, you'll get very useful answers. Otherwise, I'm kind of guessing.

By default .action extension is used by the struts-default package that you extend. When you place the url in the browser make sure you have use correct url.

Try changing
<action name="registerClientInfo" class="action.SubscribeAction">
<result name="success">/paiement.jsp</result>
</action>
to
<action name="registerClientInfo" class="SubscribeAction">
<result name="success">/paiement.jsp</result>
</action>

Related

Struts 2 could not find a result for success returned from an action

I'm not a native English speaker, so my apologizes if I made some idiomatic mistake. I'm completely new on Struts2.
I developed a web project that contains 3 JSP pages, a deployment descriptor (web.xml), a struts configuration file (struts.xml) with 2 actions configured inside (an action named index and an action named welcome) and 1 class that implements the action logic for welcome action. When I try the index action it works perfectly but if I call the welcome action in the URL (welcome.action) I get the following error
Struts Problem Report
Struts has detected an unhandled exception:
Messages:
No result defined for action actions.WelcomeAction and result success
com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
...
Now I give you more information about the project and environment:
Development Environment
OS: Mac OS X 10.10.3
JRE: 1.8.0_20
IDE: NetBeans 7.4
App Server: GlassFish 4.0
Server Location: localhost:8080
Context Path: /AppStruts2Example
URL Project: http://localhost:8080/AppStruts2Example/
Web Project Development Information
Java EE Version: 7
Struts2 Version: 2.3.15
Code is described below
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
struts.xml
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.configuration.xml.reload" value="true" />
<!-- Configuration for the default package. -->
<package name="default" extends="struts-default">
<action name="index">
<result>/WelcomeFromIndexAction.jsp</result>
</action>
<action name="welcome" class="actions.WelcomeAction">
<result name="success">/WelcomeFromWelcomeAction.jsp</result>
</action>
</package>
</struts>
actions.WelcomeAction.java
package actions;
import com.opensymphony.xwork2.ActionSupport;
public class WelcomeAction extends ActionSupport{
#Override
public String execute(){
System.out.println("Inside of execute method in WelcomeAction.");
System.out.println("Result: " + SUCCESS);
return SUCCESS;
}
}
index.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Index JSP</title>
</head>
<body>
<h1>Welcome to index.jsp!</h1>
</body>
</html>
WelcomeFromIndexAction.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Index Action</title>
</head>
<body>
<h1>Welcome From Index Action</h1>
<br />
<h3>Current Page: WelcomeFromIndexAction.jsp</h3>
</body>
</html>
WelcomeFromWelcomeAction.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome Action</title>
</head>
<body>
<h1>Welcome From Welcome Action</h1>
<br />
<h3>Current Page: WelcomeFromWelcomeAction.jsp</h3>
</body>
</html>
Project works fine when:
I write directly the URL of anyone JSP on the browser
I invoke the index action as you can see below: /index.action or /index -> both redirect me to WelcomeFromIndexAction.jsp
Project fails when:
I invoke the welcome action as you can see below: /welcome.action or /welcome -> both shows me a web page with Struts Problem Report like described above
I thought it could be a problem with GlassFish Server, so I mounted a Debian on a VM and I installed a Tomcat 7 there. My next step was deploy the web application whit "Clean and Build" from NetBeans. It generated me a WAR file that I deployed into Tomcat 7 but I got the same problem. After this disappointing I disabled the Debian VM (Tomcat 7) and I come back to work with GlassFish 4.0
As you can see in WelcomeAction.java, it has a println statement within execute method. When I invoke welcome action on the browser, I can see that Struts effectively calls that method, the lines are printed on the output and after this call, when Struts2 has to process the Result then show me the error. This confirm me that Struts2 is not finding the result not the action, but I don't know why.
I tried configuring the filter dispatcher with old and new version of filter (FilterDispatcher/StrutsPrepareAndExecuteFilter). With both i get same problem.
I tried configuring the welcome action in struts.xml exactly the same index action (practically by default) but doesn't work too. Only index action run fine.
I tried configuring the welcome action in struts.xml of many many ways, but nothing works.
So, here i am, needing someone help me. I appreciate your answers.
Note: Stackoverflow doesn't allow me post image because i'm new. So, I uploaded an important print screen to my dropbox. https://dl.dropboxusercontent.com/u/101502868/NetBeans%20Struts2%20Error.png
At this print screen you can see the libraries added, execution of execute method, the customized print lines and start of Struts error's.
Thank's.
make entry in struts.xml with custom method in action class named editUser so that control dirctly goes to that perticuler method and handle the result accordingly your logic
<action method="editUser" name="editUser" class="com.action.EditUserAction">
<result name="true">/jsp/editUser.jsp</result>
<result name="false">jsp/index.jsp</result>
</action>
And add custom method in your class instead of override execute method
class EditUserAction extendes ActionSupport{
public String editUser(){
String status = "false";
/**
do your buisness logic
*/
return status;
}
}
After doing same if still the issues is persist then check your configuration carefully
The best way to fix this issue is using Maven to create your project and manage all dependencies you could need. That was the only solution that works to me.
Here is an official guide to create a Struts 2 Web Application using Maven (very simple example): http://struts.apache.org/docs/create-struts-2-web-application-using-maven-to-manage-artifacts-and-to-build-the-application.html
If you don't have installed Maven is OS X and you don't know how to install it, then follow the next steps to install it:
Download Maven (This example uses Maven 3.3.3. The name of the compressed file is apache-maven-3.3.3-bin.tar.gz): http://maven.apache.org/download.cgi
Unpack the downloaded file (This example assumes that the downloaded file is located in /Users/YourUser/Downloads/). After unpack, a new directory will be created with the same name and path of your maven file downloaded. (In this example: /Users/YourUser/Downloads/apache-maven-3.3.3/)
Open a Terminal
Move your maven directory to your home directory using this command:
mv ~/Downloads/apache-maven-3.3.3/ ~/
Now, you have to edit the file .bash_profile located on your home directory (~/.bash_profile). To edit it, we'll use vi commando as you can see below:
vi ~/.bash_profile
Once opened you must press i to edit it
Now you can edit the file, so you have to write the following:
export JAVA_HOME=$(/usr/libexec/java_home)
export MAVEN=$HOME/apache-maven-3.3.3/bin
Close the terminal and open it again. That's all, Maven should be already installed. Use the following command to verify that Maven is working:
mvn -version
If you see the information about Maven, Java and OS X that you are using it's because Maven is working fine.

Spring MVC resource Mapping

I have been testing some request mapping in Spring MVC, and I came across a strange situation in my application. I decided to create a simple cenario so that you can understand my problem. I will first show you the details of my project (the source), and then I'll get to my question.
I have the following directory structure in my project:
+webapp
+WEB-INF
+recursos
+estilos
test.css
+spring
fronte-beans.xml
+views
+testes
page1.jsp
page2.jsp
web.xml
My Tomcat deployment descriptor:
<?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/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.4">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>fronte</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/fronte-beans.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>fronte</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
My application context for DispatcherServlet:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd ">
<mvc:annotation-driven />
<mvc:resources mapping="/recursos/**" location="/WEB-INF/recursos/" />
<context:component-scan base-package="com.regra7.minhaapp.contro" />
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
My controller class for page1.jsp:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping(value="/path")
public class TestController
{
#RequestMapping(value="/to/something")
public String getPage()
{
return "testes/page2";
}
}
My page1.jsp:
<!DOCTYPE html>
<%# page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html lang="pt-BR">
<!-- ############################################### -->
<!-- HEADER -->
<!-- ############################################### -->
<head>
<title>Test Page</title>
<meta name="author" content="RDS" />
<meta name="description" content="? ? ?" />
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" href="recursos/estilos/test.css" media="all" />
</head>
<!-- ############################################### -->
<!-- BODY -->
<!-- ############################################### -->
<body>
<h1>PAGE 1</h1>
<p>This is a test, p1.</p>
<p>This is a test, p2.</p>
<p>This is a test, p3.</p>
CLICK TO PAGE 2
</body>
</html>
I can access page1.jsp and page2.jsp smoothly, but the CSS file of page2.jsp ends up not being found. The following text is printed on my console:
dez 29, 2014 8:16:22 PM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/testeSpringMvc/path/to/recursos/estilos/test.css] in DispatcherServlet with name 'fronte'
For what reason "/path/to" is being included in the resulting path? If I try to add different combinations of mapping, both class or method-level, the same thing happens. However, if I map the link to a query string (URL) as follows, the file is found without problems...
page1.jsp:
CLICK TO PAGE 2
Controller:
#Controller
#RequestMapping(value="/")
public class TestController
...
#RequestMapping(params="cd=page2")
public String getPage()
What's happening? How can I set a path I want so that my pages use and find the necessary resources? I'm trying to separate pages in different paths so that I can apply the security features from Tomcat (security constraints).
NOTE: I've tried using contextPath to help me in setting the CSS file path, but nothing worked. In fact, the situation worsened because Page1.jsp also turned out not having stylization:
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}recursos/estilos/test.css" media="all" />
As always, thank you for your attention and time.
Same was happening to me, and I found a solution. I hope this can help someone else:
As you see in the error message, paths you use for resources /testeSpringMvc/path/to/recursos/estilos/test.css are trying to be resolved by Spring's DispatchServlet.
This happens because in your web.xml file you have the following:
<servlet-mapping>
<servlet-name>fronte</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Your fronte servlet will try to resolve anything that starts with /.
Just add a simple extension to you <url-pattern>. Something like <url-pattern>/*.html</url-pattern> should do the job.
I just found the answer to my problems. I will leave here the solution, but unfortunately I did not understand how it solves the seen scenario.
I have found that this can be solved with JSTL. I read the JSTL documentation, and all I found was this description:
Creates a URL with optional query parameters.
If reference to the CSS file is changed by the following sentence, the problem will be solved:
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<link rel="stylesheet" type="text/css" href="<c:url value="/recursos/estilos/test.css" />" media="all" />
If any moderator see this and know the explanation of how this is resolved, I kindly ask you to expose it here. Edit my answer, or comment it out, please. I'm sure other people can have the same doubt as me in the future.
Thank you all for the attention and time.
Take a look at this blog entry. The relevant passage is:
If I want to apply main.css to url: www.mysite.com/index.html, I need
to use following construction in HTML code:
< link href="resources/css/main.css" rel="stylesheet" type="text/css"/ >
If I want to apply main.css to url: www.mysite.com/some/location.html,
I need to use following construction in HTML code:
< link href="../resources/css/main.css" rel="stylesheet" type="text/css"/ >
As a possible workaround, perhaps this might work:
<mvc:resources mapping="/**/recursos/**" location="/WEB-INF/recursos/" />
You can access resource as given below.
<link rel="stylesheet" type="text/css" href="/recursos/estilos/test.css" media="all" />
you are missing / at the beginning

Error 404 issues using Struts application

I am having some issues running a Struts web app since few days. I tried several solutions from StackOverflow relating to my problem but none of them works.
web.xml:
<display-name>Struts2 Application</display-name>
<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>
<welcome-file-list>
<welcome-file>Login.jsp</welcome-file>
</welcome-file-list>
struts.xml:
<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="login"
class="net.viralpatel.struts2.LoginAction">
<result name="success">Welcome.jsp</result>
<result name="error">Login.jsp</result>
</action>
</package>
</struts>
Login.jsp:
<%# page contentType="text/html; charset=UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>Struts 2 - Login Application | ViralPatel.net</title>
</head>
<body>
<h2>Struts 2 - Login Application</h2>
<s:actionerror />
<s:form action="login.action" method="post">
<s:textfield name="username" key="label.username" size="20" />
<s:password name="password" key="label.password" size="20" />
<s:submit method="execute" key="label.login" align="center" />
</s:form>
</body>
</html>
LoginAction.java:
package net.viralpatel.struts2;
public class LoginAction {
private String username;
private String password;
public String execute() {
if (this.username.equals("admin")
&& this.password.equals("admin123")) {
return "success";
} else {
return "error";
}
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Libs I have added:
commons-logging-1.1.3.jar
freemarker-2.3.19.jar
ognl-3.0.6.jar
struts2-core-2.3.15.1.jar
xwork-core-2.3.15.1.jar
Error accessing URL:
http://localhost:8080/StrutsHelloWorld/
HTTP Status 404 - /StrutsHelloWorld/
type Status report
message /StrutsHelloWorld/
description The requested resource is not available.
Apache Tomcat/7.0.42
I tried this tutorial.
There are no errors on my console, problem view.
The error 404 means that resource you have requested is not available, the same referred to the action that is didn't map to the request URL.
FilterDispatcher is deprecated and may not work with the current Struts version, use StrutsPrepareAndExcecuteFilter instead.
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
in the struts.xml add the following
<package name="default" extends="struts-default" namespace="/">
<action name=""><result>/Login.jsp</result></acton>
this will forward you to the login page. Also consider to use absolute paths to the JSP resources.
In the JSP use the form that needs to rewrite to
<s:form namespace="/" action="login" method="post">
<s:textfield name="username" key="label.username" size="20" />
<s:password name="password" key="label.password" size="20" />
<s:submit key="label.login" align="center" />
</s:form>
In the action attribute use the action name and provide namespace as you did in the package configuration.
Using method="execute" is useless in the s:submit tag, the method execute used by default, and it will not work because you have turned off DMI in the Struts configuration.
Adding libraries over the old libraries in the WEB-INF/lib doesn't help so much and your application probably would not work, until you remove and replace all lower version libraries with higher version and add new libraries needed by the current version of Struts framework.
for me it's I didn't add "lang3" to library, after adding it everything goes well

Struts 2 action class not working

I am using struts2 for developing a web application.
I have include the required jars for struts2 but when it is going to call the struts action class it is throwing 404 error.
There is no error on console and browser does not showing .action extension whitch it shows when struts.xml call an action class.
I am using jdk 1.6 and struts 2.0.
Am I missing any jar who is responsible for all this.
In jsp I am simply calling the function from
<s:form action = "Mergexmlaction" method = "post"/>
Here is my struts.xml and web.xml
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.multipart.maxSize" value="6000000000" />
<package name="default" namespace="/jsp" extends="struts-default">
<action name="Mergexmlaction" class="com.hm.merge.mergeaction.Mergexmlaction">
<result name="success" >/jsp/Result.jsp</result>
<result name="error" >/jsp/Browse_multiplexmlfiles.jsp</result>
<interceptor-ref name="fileUpload">
<param name="maximumSize">600000000</param>
</interceptor-ref>
</action>
</package>
</struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="xml_file_merging" 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>xml_file_merging</display-name>
<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>
<welcome-file-list>
<welcome-file>jsp/Browse_multiplexmlfiles.jsp</welcome-file>
</welcome-file-list>
</web-app>
There are a few issues.
<package name="default" namespace="/jsp" extends="struts-default">
1) I'd recommend against having a namespace of "jsp", it doesn't make any sense. Namespaces should be something meaningful to the application and/or user.
<action name="Mergexmlaction" class="com.hm.merge.mergeaction.Mergexmlaction">
2) Don't name an action with "action", there will either be a .action extension, or no extension at all. Either way, there's no reason to duplicate "action" in the first case, and no reason to use "action" if there's no extension. Just "mergexml", "mergeXml", etc.
<result name="success" >/jsp/Result.jsp</result>
3) I recommend putting your JSP pages under WEB-INF to avoid direct client access.
<interceptor-ref name="fileUpload">
4) Once you declare any interceptors, you must declare all interceptors. This action has only a single interceptor running. It's possible this is okay, but it's almost never the right thing to do.
<welcome-file>jsp/Browse_multiplexmlfiles.jsp</welcome-file>
5) And this is the ultimate issue, depending on how you're accessing the application. You show the welcome file as being a JSP page, which is presumably using S2 tags. This won't work: the tags depend on their being a complete S2 request, a value stack, etc.
All access to an S2 app should take place through an S2 action, not a JSP. If you look at the rendered HTML for the directly-accessed JSP you'll see neither namespace nor action extension rendered.
an error 404 is a bad link. means you just are calling a link that doesnt exist. Check your mapping in your struts config file and make sure you use the correct url.
The namespace attribute of package element is optional and if it is not present, the default value "/" is assumed. If the namespace attribute has a non-default value, the namespace must be added to the URI that invokes the actions in the package.
For example, the URI for invoking an action in a package with a default namespace is this:
/context/actionName
To invoke an action in a package with a non-default namespace, you need this URI:
/context/namespace/actionName

Struts 2 DisplayTag only shows table of DB information only when form is submitted

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.

Categories

Resources