strust2.5 exception-mapping not worked - java

I used Struts 2.5.16,follow code is struts.xml content:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="authorizeInterceptor" class="web.comm.Interceptor.authorizeInterceptor"></interceptor>
</interceptors>
<action name="home">
<result type="dispatcher">/view/index.jsp</result>
</action>
<action name="exp" class="web.comm.userAndAuthorize.commUserOp" method="jsonChangePass">
<interceptor-ref name="authorizeInterceptor"/>
<exception-mapping result="Exception" exception="java.lang.Exception"/>
<result name="Exception" type="chain">/view/UserAndAuthorize/error.jsp</result>
<allowed-methods>jsonChkLogin,jsonChangePass,createUser</allowed-methods>
</action>
url is http://localhost/exp
follow code is method of jsonChangePass()
public String jsonChangePass()throws Exception{
int b=0,a=1;
int c=a/b;
follow content is chorme showed:
Struts Problem Report Struts has detected an unhandled exception:
Messages: / by zero ......
see the web showing content, action is already working.why the exception-mapping not worked?thanks for ervery one help.

Since you're not running the exception mapping interceptor, it won't work.
Once you define <interceptors> in a package you must define all the interceptors: this is not an additive element, this is a declaration of the interceptors used in that package.
IIRC you can use an <interceptor-ref> to get the defaultStack (or whichever you actually intended to use) and add your authorizeInterceptor.

Related

Adding a custom interceptor for some actions

I have created an interceptor which I want to map to some particular methods in some action and I don't want to disturb the existing code:
struts.xml:
<package name="francis" namespace="/francis" extends="struts-default,json-default">
<interceptors>
<interceptor name="authentication" class="main.java.com.commdel.commons.struts2.interceptors.AuthenticationInterceptor"/>
<interceptor name="authorization" class="main.java.com.commdel.commons.struts2.interceptors.SecurityInterceptor"/>
The custom interceptor csrf:
<interceptor name="csrf" class="main.java.com.commdel.commons.struts2.interceptors.CsrfTokenInterceptor"/>
<interceptor-stack name="commonStack">
<interceptor-ref name="authentication"/>
<interceptor-ref name="authorization"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="commonStack"/>
<global-results>
<result name="error" type="velocity">/results/velocity/common/globalerror.vm</result>
<result name="AUTHORIZATIONERROR" type="velocity">/results/velocity/common/sessionError.vm</result>
</global-results>
Mapping csrf to some action:
<action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
<interceptor-ref name="csrf"/>
</action>
</package>
You seem to think that the default Interceptor Stack applies to all actions, and that the eventual interceptor you're specifying for to the single actions are added to the default stack. They're not.
The default stack is the stack used for all the actions that does not specify any stack (or single interceptor, like in your case).
If you want to add an interceptor, then specify also the stack it should add to,
<action name="addUpdateClaimHeadMetronic"
class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction"
method="addUpdateClaimHead">
<interceptor-ref name="commonStack"/>
<interceptor-ref name="csrf"/>
</action>
or define a new stack and use it:
<interceptor-stack name="commonStack">
<interceptor-ref name="authentication"/>
<interceptor-ref name="authorization"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
<interceptor-stack name="csrfStack">
<interceptor-ref name="authentication"/>
<interceptor-ref name="authorization"/>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="csrf"/>
</interceptor-stack>
....
<default-interceptor-ref name="commonStack"/>
....
<action name="addUpdateClaimHeadMetronic"
class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction"
method="addUpdateClaimHead">
<interceptor-ref name="csrfStack"/>
</action>
Note that the first approach violates DRY if you have a lot of actions sharing the secondary interceptor stack configuration, and it can be used only if your Interceptor is good to be placed as first or as last. If you need it in the middle (eg. after param, but before workflow) you have to define a stack by exploding the defaultStack, copying it from struts-default.xml.
If you add a custom interceptor to the action configuration like
<action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
<interceptor-ref name="csrf"/>
</action>
then only csrf interceptor will be configured to this action mapping. Other interceptor's included in the commonStack will be omitted even if you use
<default-interceptor-ref name="commonStack"/>
Struts allows to override the action configuration which will not use the default-interceptor-ref, it you add a custom interceptor to the action mapping. By overriding the action configuration you can use a custom set of interceptors.
You might be missing some important interceptors from the defaultStack that drive the Struts2 framework if you forget to include all references of interceptors in the custom action mapping.
Note: interceptors in Struts2 add additional functionality to the action before or after the action is executed. But missing some important interceptors might break the action execution.
If you want to add a custom interceptor reference to the existed action, then you should add, along with your custom interceptor, a reference to the default stack in your action mapping before or after depends on your code.
<action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
<interceptor-ref name="csrf"/>
<interceptor-ref name="commonStack"/>
</action>
Note: interceptors are invoked by the order they are used in the xml configuration.

Struts 2 remove .action extension when redirect

Before starting, I'm sorry for my bad English, because English is not my first language. However, I have a problem with Struts 2 redirecting.
One part of my Struts.xml file is like this:
<package name="login" namespace="/" extends="struts-default">
<action name="login" class="Action.loginAction">
<result name="success" type="redirectAction">
<param name="actionName">search</param>
<param name="namespace">/</param>
</result>
<result name="error">/login.jsp</result>
<result name="input">/login.jsp</result>
</action>
</package>
I have a loginAction that's responsible for logging in the user (no matter what is the content of this file). When the result of this action is success, I want to redirect to search action. Everything works fine, but my problem is, when I redirect to search action, the URL looks like this: http://localhost:8080/MyWebApplication/search.action
I want to have the .action removed from the URL, when redirecting to a particular action. What do I need to change to fix this?
Thanks for your attention.
By default struts2 framework will add .action you can override it by following configuration.
<constant name="struts.action.extension" value=""/>
For ref:
http://struts.apache.org/release/2.3.x/struts2-core/apidocs/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.html

Get Request in Struts 2

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.

Adding interceptors in struts.xml for all Action classes

I've used the Struts 2 framework and I have created a web application which has a Login Page. I have three different Action classes named Action1, Action2, Action3, and different views for JSP pages which are rendered by running some business logic in the Action classes.
Now, I want to check whether a user has logged in before the Action class carries out processing. So,
I created an interceptor below that works fine:
public String intercept(ActionInvocation invocation) throws Exception
{
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
if(session.isNew())
{
response.sendRedirect("Login.action");
}
System.out.println("Interceptor Fired");
String result = invocation.invoke();
return result;
}
What I want to be in struts.xml is instead of adding an interceptor for all the actions like the one below
<interceptor-ref name="newStack"/>
My struts.xml file has:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="printMsgInterceptor" class="LoginInterceptor"></interceptor>
<interceptor-stack name="newStack">
<interceptor-ref name="printMsgInterceptor"/>
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<action name="actone" class="Action1">
<result name="success">/success.jsp</result>
<interceptor-ref name="newStack"/>
</action>
<action name="acttwo" class="Action2">
<result name="success">/success.jsp</result>
<interceptor-ref name="newStack"/>
</action>
<action name="actthree" class="Action3">
<result name="success">/success.jsp</result>
<interceptor-ref name="newStack"/>
</action>
</package>
For every action I want to have some definition written in struts.xml which runs the interceptor rather than manually adding
<interceptor-ref name="newStack"/>
<interceptor name="test" class="Full path for LoginInterceptor" />
<interceptor-stack name="testStack">
<interceptor-ref name="test"/>
<interceptor-ref name="defaultStack"/> //here you are including default stack
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="testStack"></default-interceptor-ref>
Now testStack will execute for every request
Use
<default-interceptor-ref name="newStack"/>
If you not putting interceptor-ref manually for each action you could use the default-interceptor-ref to intercept all actions that has not explicitly defined interceptors configuration. See How do we configure an Interceptor to be used with every Action.
We can create our own named stacks and even declare a new default interceptor stack for a package
<package name="default" extends="struts-default" >
<interceptors>
<interceptor-stack name="myStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
However, if you say that the interceptor above works fine I will encourage you to be cautious about a business logic that the login action will not be executed if it fails on the first execution. Instead of checking for the new session you should check for results of the authenticated user and save these results in the session that you could check in the interceptor. See this question for example.
The example of writing the interceptor that use the authenticated user information with the session you could find here.

How to configure #SkipValidation by XML configuration in Struts 2

In Struts 2,
I am trying to skip validation on method base on XML configuration.
As per my application I can not use annotation. So I cannot use #SkipValidation annotation. Is there any alternative for this?
I have one action class which has five methods create, update, delete, search, and view. I want to validate only two methods create and update.
You should configure in the struts.xml package with interceptors
<interceptors>
<interceptor-stack name="validateWorkflowStack">
<interceptor-ref name="basicStack"/>
<!-- ... whatever interceptors -->
<interceptor-ref name="validation">
<param name="excludeMethods">delete, search, view</param>
</interceptor-ref>
<interceptor-ref name="workflow"/>
</interceptor-stack>
</interceptors>
then use action configuration
<action name="create" class="your.package.CreateAction" method="create">
<result name="input">/path/to/form.jsp</result>
<interceptor-ref name="validateWorkflowStack"/>
</action>
apply interceptor to each action that has a validation interceptor referenced explicitly on action or implicitly via <default-interceptor-ref on the package.
You must configure validation interceptor for your action to exclude methods names that you do not want to be validated.
<action name="..." class="...">
<interceptor-ref name="defaultStack">
<param name="validation.excludeMethods">input,back,cancel,browse,delete,search,view</param>
</interceptor-ref>
<result>...</result>
</action>

Categories

Resources