I have a web application using struts2, spring and hibernate frameworks. Now I want to expose some of its methods via soap web service. I have a class and I simply annotated it with #WebService annotation and an Service endpoint interface. Now when I deploy my application on glassfish it deploys fine but when I try to access wsdl via glasssfish admin console. It gives me the following error.
There is no Action mapped for namespace [/] and action name [UsersControllerImplService] associated with context path [/ossoc].
I understand its something related to configuration but I am unable to figure out what configuration.
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>ossoc</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
struts2.xml
<!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.objectFactory" value="spring" />
<package name="user" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="authentication" class="com.riteshsangwan.ossoc.core.interceptors.AuthenticationInterceptor"></interceptor>
<interceptor-stack name="authStack">
<interceptor-ref name="authentication"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="authStack"></default-interceptor-ref>
<global-results>
<result name="login" type="redirect">/index.action</result>
</global-results>
<action name="register" class="com.riteshsangwan.ossoc.core.actions.RegisterAction">
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/index.jsp</result>
<result name="error">/register.jsp</result>
<result name="input">/register.jsp</result>
</action>
<action name="login" class="com.riteshsangwan.ossoc.core.actions.LoginAction">
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/user/home.jsp</result>
<result name="error">/index.jsp</result>
<result name="input">/index.jsp</result>
</action>
<action name="activate" class="com.riteshsangwan.ossoc.core.actions.ActivateAction">
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/user/home.jsp</result>
<result name="error">/index.jsp</result>
<result name="input">/index.jsp</result>
</action>
<action name="index">
<interceptor-ref name="defaultStack"></interceptor-ref>
<result>/index.jsp</result>
</action>
<action name="home">
<result>/user/home.jsp</result>
</action>
<action name="showfiles" class="com.riteshsangwan.ossoc.core.actions.ShowFiles">
<result name="success">/user/files.jsp</result>
</action>
<action name="edit">
<result>/user/edit.jsp</result>
</action>
<action name="logout" class="com.riteshsangwan.ossoc.core.actions.LogoutAction">
<result name="success">/index.jsp</result>
</action>
<action name="changepassword" class="com.riteshsangwan.ossoc.core.actions.ChangePassword">
<result name="success">/user/edit.jsp</result>
</action>
<action name="upload" class="com.riteshsangwan.ossoc.core.actions.UploadFile">
<result>/user/home.jsp</result>
</action>
<action name="showgrid" class="com.riteshsangwan.ossoc.core.actions.ShowFiles">
<result name="success">/user/files.jsp</result>
</action>
<action name="deletefile" class="com.riteshsangwan.ossoc.core.actions.DeleteFile">
<result name="success">/user/files.jsp</result>
</action>
<action name="downloadfile" class="com.riteshsangwan.ossoc.core.actions.DownloadFile">
<result name="success" type="stream">
<param name="contentType"></param>
<param name="inputName"></param>
<param name="contentDisposition"></param>
<param name="bufferSize"></param>
<param name="allowCaching"></param>
<param name="contentLength"></param>
</result>
</action>
</package>
</struts>
applicationCOntext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- Database Configuration -->
<import resource="DataSource.xml"/>
<import resource="HibernateSessionFactory.xml"/>
<!-- Beans Declaration -->
<import resource="UsersBean.xml"/>
</beans>
Why everyone here is so eager to vote down.
This was the problem.
In web.xml the struts2 filter has /* url pattern mapped so struts2 will filter every request that comes to it including the request to the webservice servlet. Since filters execute before servlets so I was getting the action not mapped error.
From the struts2 documentation.
The action mapping extension has been changed to .action plus "" it means if I simply enter name of servlet in the address bar the struts2 will take it as action and check struts2.xml for relevant action mapping since there are no action mapping so it will throw error.
Solution
I just add the .extension after url in URL pattern mapping so struts2 will treat as a servlet request other option will to use
<constant name="struts.action.excludePattern" value="URLTOEXCLUDE"/>
and configure the webservice to use the excluded URL
Hope this helps others.
Related
I have the problem on struts.xml of Struts 2 web project.
I have the login page and after login, the URL will add /secure/*.action.
I tried to have two packages in struts.xml. One is normal / and second is /secure. But it will cause 404 not found page after login. If I make the second package also \ in namespace and call the membersite.action with only / namespace , it will be OK and successfully direct but with only /*.action in URL. I need to have this URL /secure/*.action in infrastructure issue. Is there any hints?
<package name="awip" namespace="/" extends="tiles-default, struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
<global-results>
<result name="sessionTimeout" type="tiles">.logon.LogonForm</result>
<result name="errorRedirect" type="tiles">.errorPage</result>
</global-results>
<action name="logon" class="logonAction" method="displayLogonForm">
<result name="displayLogonForm" type="tiles">.logon.LogonForm</result>
</action>
<action name="doLogon" class="logonAction" method="doLogon">
<result name="displayLogonForm" type="tiles">.logon.LogonForm</result>
<result name="displayMainPage" type="redirectAction">
<param name="namespace">/secure</param>
<param name="actionName">membersite.action</param>
</result>
</action>
</package>
<package name="secureAwip" namespace="/secure" extends="tiles-default, struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
<global-results>
<result name="sessionTimeout" type="tiles">.logon.LogonForm</result>
<result name="errorRedirect" type="tiles">.errorPage</result>
</global-results>
<action name="membersite" method="unspecified" class="membersiteAction">
<result name="displayMembersiteMain" type="tiles">.membersite.Main
</result>
</action>
</package>
The action name should not have an extension .action. If you write it with the action name the action mapper can't find the appropriate mapping for the action's result.
The code
<param name="actionName">membersite.action</param>
should be changed to
<param name="actionName">membersite</param>
When I run my strust2 web application, I want to execute an action for the root path [/].
It would be something like an action with no name or just "/", something like:
<action name="/" class="ControllerName" method="execute">
<result name="success">ShowTheFirstPageAfterTheAction.jsp</result>
</action>
...
<struts>
...
<package name="user" namespace="/" extends="struts-default">
<action name="" class="ControllerName" method="execute">
<result name="success">ShowTheFirstPageAfterTheAction.jsp</result>
</action>
// Other actions depending on how you've designed your application
<package
// Other packages (also) depending on how you've designed your application
</struts>
i have a problem loading a page. I defined in the struts.xml (located in Java Resources/src/com.infopool.action) the next configuration:
<struts>
<package name="demo" namespace="/demo" extends="struts-default">
<action name="Inicio" class="com.infopool.action.Demo">
<result name="success">/View/demo/start.jsp</result>
</action>
<action name="Hola" class="com.infopool.action.Demo" method="hello">
<result name="success">/View/demo/hello.jsp</result>
</action>
<action name="Chau" class="com.infopool.action.Demo" method="goodbye">
<result name="success">/View/demo/goodbye.jsp</result>
</action>
</package>
</struts>
So, in the package com.infopool.action i have the next class defined:
package com.infopool.action;
public class Demo {
public String execute(){
return "success";
}
public String hello(){
return "success";
}
public String goodbye(){
return "success";
}
}
The views are located into WebContent/View/demo. When i try to browse the page, an 404 Tomcat error appear. The URL is:
http://localhost:8080/Infopool/demo/Inicio.action
My web.xml have the next configuration:
<filter>
<filter-name>Main</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.infopool.action</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Main</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
What is wrong with my configuration ?.
the use of this one is to pass an action package where all the action classes has been declared
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.infopool.action</param-value>
</init-param>
but your Demo action class doesnt have any annotation configuration like (if im not mistaken.)
#Namespace("/demo")
#Action("/Inicio")
#ResultPath(value="/")
#Result(name="success",location="/View/demo/start.jsp")
public class Demo {
....
You used the other way on configuring your action class which is your struts.xml
<struts>
<package name="demo" namespace="/demo" extends="struts-default">
<action name="Inicio" class="com.infopool.action.Demo">
<result name="success">/View/demo/start.jsp</result>
</action>
<action name="Hola" class="com.infopool.action.Demo" method="hello">
<result name="success">/View/demo/hello.jsp</result>
</action>
<action name="Chau" class="com.infopool.action.Demo" method="goodbye">
<result name="success">/View/demo/goodbye.jsp</result>
</action>
</package>
</struts>
so no need to declare/create this,
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.infopool.action</param-value>
</init-param>
inside of your struts filter.
#1 look at this : Providing an init-parameter in struts filter
#2 see this sample : struts2 annotation
With some help of the people here, I've managed to get my project to call the default actions of the packages without the suffix .htm. However, the request end up to index.jsp inside the webapp folder if I call the URL without the forward slash.
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.action.extension" value="htm,," />
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.devMode" value="true"/>
...
<package name="home" namespace="/secured" extends="default">
<default-action-ref name="index" />
<action name="index" class="homeAction" method="execute">
<result name="success" type="tiles">home</result>
</action>
</package>
</struts>
Actions are executed if I call http://someurl/someproject/secured/, but calling the URL http://someurl/someproject/secured end up to the file index.jsp.
What to do? Thanks
When you are calling http://someurl/someproject/secured url the secured is treated like action w/o suffix, because you have configured that actions can have empty suffix (which is also default btw). If you want that this url redirects to /secured namespace you can declare secured action with redirectAction result in package with empty or / namespace.
<package name="..." namespace="/" extends="struts-default">
...
<action name="secured">
<result type="redirectAction">
<param name="actionName">index</param>
<param name="namespace">/secured</param>
</result>
</action>
...
</package>
I am new to struts2. In application there is Action called userLogin. when i enter to url http://servername:9090/appName/userLogin, It should forward the request directly to to /jsp/account/login.jsp. it should not call action method. how can i ensure that when request is through get then forword to loginPage else if Request is Post then it should call the action
Struts.xml is as follows
<?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="ApplicationResources" />
<package name="default" extends="struts-default">
<action name="index">
<result>jsp/index.jsp</result>
</action>
<action name="userLogin" class="com.ril.tc.action.LoginAction">
<result>jsp/account/login.jsp</result>
<result name="success">jsp/index.jsp</result>
<result name="error">jsp/account/login.jsp</result>
</action>
<action name="ministatement" class="com.ril.tc.action.MiniStatementAction">
<result>jsp/account/ministatement.jsp</result>
<result name="success">jsp/account/ministatementdetails.jsp</result>
<result name="error">jsp/account/ministatement.jsp</result>
</action>
</package>
</struts>
1. You can simply check the request method in action method before the business method executes.
It will add 2-3 lines of java code in action method and a line modification in xml configuration.
2. Or you can strictly restrict the execution of the Action method by using an interceptor.
Interceptor requires a seperate java class and a few lines of xml configuration.
Method 1
a) Java code
public String execute (){ // or your method name
if(ServletActionContext.getRequest().getMethod().equals("GET")){
return "getrequest";
}
........
//your business logic
}
b) xml configuration
<action name="userLogin" class="com.ril.tc.action.LoginAction">
<result name="getrequest">jsp/account/login.jsp</result>
<result name="success">jsp/index.jsp</result>
<result name="error">jsp/account/login.jsp</result>
</action>
Method 2.
a) Java Code
public GetRequestFilterInterceptor extends AbstractInterceptor{
#Override
public void intercept (ActionInvocation action){
if(ServletActionContext.getRequest().getMethod(). equals("GET")){
return "getrequest";
}else{
action.invoke();
}
}
}
b) Xml configuration
<struts>
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="getUrlFilter" class="packagename.GetRequestFilterInterceptor"/>
<interceptor-stack name="requestFilter">
<interceptor-ref name="getUrlFilter"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
......
<action name="userLogin" class="com.ril.tc.action.LoginAction">
<interceptor-ref name="requestFilter"/>
<result name="getrequest">jsp/account/login.jsp</result>
<result name="success">jsp/index.jsp</result>
<result name="error">jsp/account/login.jsp</result>
</action>
</package>
</struts>
I recommend you to use interceptors, if you want to filter a lot a methods. If you have want to filter only one method, the first one is better.