In struts2 i have one default interceptor and lot of actions in the struts.xml page.
My struts.xml is like this
<struts>
<package>
<interceptors>
<interceptor-ref name="" class="" >
<interceptor-stack name="" >
<interceptor-ref name="" />
<interceptor-ref name="" />
</interceptor-stack>
</interceptor-ref>
</interceptors>
<action name="" class="package.class" method= "method" >
<result name="success">jsp page</result>
<result name="success">jsp page</result>
</action>
<action name="" class="package.class" method= "method" >
<result name="success">jsp page</result>
<result name="success">jsp page</result>
</action>
<action name="" class="package.class" method= "method" >
<result name="success">jsp page</result>
<result name="success">jsp page</result>
</action>
</package>
</struts>
In the default interceptor i have check the session. But if session is not set i need to redirect the page to login page, hence it should be work in all actions?. How do i implement this. Do i need to call the interceptor in all action or if i use default interceptor how can i set the redirect page in all actions?.
For this purpose you can make your own interceptor that will check if session is set or not. If it is not set it will redirect your request to login page. And then you can add this interceptor to the default interceptor stack where ever you want. And you don't need to call the interceptor each time, the struts2 framework will automatically call the interceptor before and after every action.
You can check from here how to make your own interceptor.
Related
I am developing a simple struts2 login page using spring security.The problem is that whenever I login, it always show my custom access denied page no matter the user is valid or not. I don't understand the error, as no error is showing except a warning:
org.apache.struts2.components.ServletUrlRenderer.warn No configuration found for the specified action: 'j_spring_security_check' in namespace: '/'. Form action defaulting to 'action' attribute's literal value.
my web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>*.action</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>/jsp/index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
my applicationContext-security.xml
<http auto-config="true">
<intercept-url pattern="/direct.action" access="permitAll()" />
<intercept-url pattern="/admin.action" access="hasRole('ROLE_Admin')" />
<access-denied-handler error-page="/jsp/deniedAccess.jsp" />
<form-login login-page="/jsp/login.jsp" default-target-url="/admin.action"
authentication-failure-url="/validateUser.action?error"
username-parameter="username" password-parameter="password" />
<logout logout-success-url="/logout.action?logout" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE_User" />
<user name="admin" password="admin" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
struts.xml
<struts>
<package name="default" extends="struts-default" namespace="/">
<action name="direct" class="action.LogAction" method="reDirect">
<result name="success">/jsp/login.jsp</result>
</action>
<action name="admin" class="action.LogAction" method="directAdmin">
<result name="success">/admin/adminHome.jsp</result>
</action>
<action name="validateUser" class="action.LogAction" method="errorDirect">
<result name="success">/jsp/login.jsp</result>
</action>
<action name="logout" class="action.LogAction" method="directLogout">
<result name="success">/jsp/login.jsp</result>
</action>
</package>
index.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Redirecting...</title>
</head>
<body>
Redirecting...
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=direct.action">
</body>
I don't know what is the error.Any help will be appreciated
login.jsp
<s:form action="j_spring_security_check" namespace="/" method="post">
<s:textfield name="username" label="Username"/>
<s:password name="password" label="Password"/>
<s:submit align="center" value="Login"/>
</s:form>
Your login.jsp form tag points at j_spring_security_check, which isn't an action name in your struts.xml. Change that to whatever action name which will handle the login post.
If you have written a method in action.LogAction (or implemented execute()) to actually handle your login, you need to provide both a success and a failure result in the struts.xml The success result should take the user to wherever they should be after successful login, the failure result takes them back to the login jsp. See the struts docs here for more info.
I am using struts-json-plugin.2.2.3 for Actions whose result type is json, here is an demo configuration:
<action name="dept_*" class="com.XXX.action.DepartmentAction" method="{1}">
<result name="search">dept_search.jsp</result>
<result name="search_ajax" type="json"><param name="root">deptList</param><param name="excludeNullProperties">true</param><param name="noCache">true</param></result>
<result name="save" type="json"><param name="root">jsonResult</param><param name="excludeNullProperties">true</param><param name="noCache">true</param></result>
<result name="count" type="json"><param name="root">pageCount</param><param name="excludeNullProperties">true</param><param name="noCache">true</param></result>
</action>
This configuration works fine. But for all Actions in my project, noCache and excludeNullProperties have same configuration value just like code above, so I am searching a way to configure them in one place and used for all. I find in JSONInterceptor class, there are same name properties, so I configured like this:
<interceptors>
<interceptor-stack name="ecsStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="json"><param name="noCache">true</param><param name="excludeNullProperties">true</param><param name="contentType">application/json;charset=utf-8</param></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="ecsStack"></default-interceptor-ref>
And remove same configurations in Action result, but it does not work as expected, there is no cache-control, expires and pragma information in response headers, and null properties are sent to browser.
So why it does not work?
If there is a convenient way to configure these two parameters?
Try this result-type configuration in struts.xml file:
<result-type name="json" class="org.apache.struts2.json.JSONResult">
<param name="noCache">true</param>
<param name="excludeNullProperties">true</param>
</result-type>
I'm using atocompleter in my form with json.
This is the part of my struts.xml
<package name="json" namespace="/" extends="json-default">
<result-types>
<result-type name="json" class="com.googlecode.jsonplugin.JSONResult" />
</result-types>
<action name="test" class="testClass" method="populate">
<result type="json" name="success">
<param name="root">itemList</param>
<param name="contentType">text/html</param>
</result>
</action>
</package>
This is the jsp
<s:form id="frm_demo" name="frm_demo" theme="simple" action="test2">
<s:url id="remoteurl" action="test" />
<sj:autocompleter
id="lst"
name="lst"
list="%{remoteurl}"
listValue="name"
listKey="id"
selectBox="true"
/>
<s:submit value="submit"/>
</s:form>
This is the action class method
public String populate() throws Exception{
itemList.put("1", "a");
itemList.put("2", "b");
itemList.put("3", "c");
return "success";
}
With the above code in struts.xml my jsp renders like this.{"3":"c","2":"b","1":"a"}
But when I delete the "contentType" parameter, in other words the content type is "application/json" the jsp pops the download window.
I need theauto completer to return the key when i click submit button. But the page doesn't load with the autocompleter. Any solutions?
p.s. itemList i used in my action class is a HashMap... does that matter?
Using map is OK with collection-backed components. I think there's couple of problems with your code.
First in you action configuration you have set the root object to your itemList, this way only content of the list will be converted to json so you can't refer to the list itself in your autocompleter.
Second you have to set the href attribute for your autocompleter and set the remoteUrl as it's value. So your code could be like:
<package name="json" namespace="/" extends="json-default">
<action name="test" class="testClass" method="populate">
<result type="json"/>
</action>
</package>
In your autompleter:
<s:form id="frm_demo" theme="simple" action="test2">
<s:url id="remoteurl" action="test" />
<sj:autocompleter href="%{remoteurl}"
id="lst"
name="lst"
list="itemList"
listValue="name"
listKey="id"
selectBox="true"/>
<s:submit value="submit"/>
</s:form>
See if that works.
I think your code is ok,Just remove this code
<param name="contentType">text/html</param>
I am getting this exception when using struts 2 with tiles
org.apache.tiles.definition.NoSuchDefinitionException: /index.jsp
//tiles.xml
<tiles-definitions>
<definition name="baseLayout" template="/index.jsp">
<put-attribute name="title" value="/Template" />
<put-attribute name="header" value="/Header.jsp" />
<put-attribute name="menu" value="/Menu.jsp" />
<put-attribute name="body" value="/body.jsp" />
<put-attribute name="footer" value="/Footer.jsp" />
</definition>
<tiles-definitions>
//index.jsp
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="footer"/>
</body>
</html>
//web.xml
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
<context-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.
DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles.xml</param-value>
</context-param>
//struts.xml
<package name="default" namespace="/test" extends="struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
<action name="login" class="com.medics.action.LoginAction">
<result name="SUCCESS" type="tiles">/index.jsp</result>
</action>
</package>
I have searched a lot but found nothing
org.apache.tiles.definition.NoSuchDefinitionException: /index.jsp
Means that there is no tiles definition, that is no definition of the name "/index.jsp"
When using struts and tiles... Your request comes into struts then out to tiles where tiles composes the view so you shouldn't have any tiles definitions called "anything.jsp".
So just replace
<result name="SUCCESS" type="tiles">/index.jsp</result>
with
<result name="SUCCESS" type="tiles">baseLayout/result>
Now that is resolved... I would rename index.jsp, template.jsp (I think it's less confusing), why do you have a put-attribute called "/Template" ?
Now to fix the issue I recommended that you change the struts2 result target to "baseLayout" but this is probably not what you mean, so you probably want to use your baseLayout definition for new pages so add a new definition:
<definition name="index" extends="baseLayout">
<put-attribute name="title" value="My Title for Index" />
<put-attribute name="body" value="/index.jsp" />
</definition>
Now the above will take that value in defaultTemplate and add (or if the name is the same, override) what was in the base template creating a page for index.jsp, and now your struts.xml should have
<result name="SUCCESS" type="tiles">index</result>
I encountered this problem today.
Although it was a question long ago, I found the solution as below:
<result name="SUCCESS" type="dispatcher">/index.jsp</result>
Just replacing the type tiles with dispatcher works for me.
I want to use json with Struts2. However, when I set the action return type to "json", I got "there is no result type defined for type 'json' mapped with name 'success'." Bellow is struts.xml file.
<?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.custom.i18n.resources" value="resource"/>
<package extends="struts-default" name="test">
<action name="inputHandler" class="inputHandlerAction">
<result name="input">/index.jsp</result>
<result>/result.jsp</result>
</action>
<action name="setLangHandler" class="com.sesoft.test.setLanguageHandler">
<result>/index.jsp</result>
</action>
<action name="Handler" class="com.sesoft.test.Handler">
<result>/test2.jsp</result>
</action>
</package>
<package name="example" extends="json-default">
<action name="ajaxHandler" class="com.sesoft.test.AjaxHandler">
<result name="success" type="json" />
</action>
</package>
</struts>
Before I added the json Action, all other action performs fine. But after I added the json Action, the server failed to action with error code 503.
libs I've added "jsonplugin-0.33.jar" to the lib directory.
You don't have the JSON result defined in your struts.xml package. If you only need default things then you can just extend json-default instead of struts-default. If you need to customise the package then include the following and that should do the trick:
<result-types>
<result-type name="json" class="com.googlecode.jsonplugin.JSONResult"/>
</result-types>
you package should extends json-default
<package name="json-default" extends="struts-default">
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult"/>
</result-types>
<interceptors>
<interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
</interceptors>
</package>
If using Maven you may need to add the dependency e.g.
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.2.3</version>
</dependency>
Here is my configuration in pom.xml:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.1.2</version>
</dependency>
In the action result you only need to specify type="json" :
<result type="json"/>
Remember the variable getter and setter in type="json" response give getters in the action.
Include json-default in the extends parameter:
<package name="default" extends="struts-default,json-default">
<action>
...
...
</action>
</package>