I have a global result that returns a 404 error to the user.
I also have a default action that I would like to do the same thing.
I would like my success result in the default action to extend my global notfound result, but I don't see how to. Am I missing something?
<default-action-ref name="notfound" />
<global-results>
<result name="notfound" type="httpheader">
<param name="error">404</param>
<param name="errorMessage">Oh No You Didn't</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="com.me.s2ui.AccessException" result="notfound" />
</global-exception-mappings>
<action name="notfound">
<result type="httpheader">
<param name="error">404</param>
<param name="errorMessage">Oh No You Didn't</param>
</result>
</action>
As stated by #Aleksandr M and #Roman C in the comments, what I wanted was not possible. After posting the question I realized I wanted logging in the default action, so I ended up writing a class.
#org.apache.struts2.convention.annotation.Action("notfound")
public class DefaultAction implements Action, ServletRequestAware
{
private static Logger logger = LogManager.getLogger(DefaultAction.class);
private HttpServletRequest request;
#Override
public String execute() throws Exception
{
logger.warn("Unknown target "+request.getRequestURI());
return "securityerror";
}
#Override
public void setServletRequest(HttpServletRequest req)
{
this.request = req;
}
}
Struts.xml
<default-action-ref name="notfound" />
<global-results>
<result name="intLogin" type="redirect">${#request.loginUrl}</result>
<result name="input" type="tiles">user</result>
<result name="securityerror" type="httpheader">
<param name="error">404</param>
<param name="errorMessage">Oh No You Didn't</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="com.me.s2ui.AccessException" result="securityerror" />
</global-exception-mappings>
Related
we are new at WebSphere deployment. Junk data get added in JSON response after deploying Struts 2 based web application WebSphere 8.5 on Linux platform .But same is working fine with web-logic ,tomcat ,glass-fish ..
We are not receiving any Exception in SystemOut or SystemErr.log file .
Sample response from our application :
{"code":0,"data":{"some data"}}¬‹í\ís›8 ÿW<|Î]yÇä ¶IÊS¿ÁIsM†áEN™8à³qÛ\'ÿû³’0–N®©›¹Ì\'SÂîJúíj -VïRR¤H:•O¤4*#éô»äa2
f“ax6tÎ¥SõDrÇ \…Þ#:•ô»¹×¿”N¤Ñ¼çøïÝ %çÛå ˆ“yØŸÏfî¸Ä? Ц3wäÍGát6 Mo2v†áȇž ÑrƒN$Ï ?\õÝSoæ÷dV|ìát8÷i»r½þÜßmè*
3pgÞ… x nè
‡“K ³ `ôfèôû“ù8‡ž¬H§ŸnN$
ÇÞ8 ¸ã
}¬;îèô“ mRúá§G/š,Ý<Ö¶p?ö߇~ÏgšÓŸ÷ü~HTý?}’zS#Hèa0©~v8pwG¿š²¿B‡~-îÇ“prrW¾„±º³àl6ªnýÑ( 9³ ` Òúæf7ôÀ%ÃS
½qàΰézÎø˜6
Java code:
public class MasterDataAccess extends ActionSupport ModelDriven<AccessBean> {
public String execute() throws Exception {
try {
byte[] b=jsonResp.getBytes("UTF-8");
final InputStream inputStream = new ByteArrayInputStream(b,0,b.length);
requestBean.setInputStream(inputStream);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
public class AccessBean {
private String terminal;
public void setTerminal(String terminal) {
this.terminal = terminal;
}
public void setInputStream(final InputStream inputStream) {
this.inputStream = inputStream;
}
}
Struts XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> (http://struts.apache.org/dtds/struts-2.5.dtd%27%3E)
<struts>
<constant name="struts.devMode" value="false" />
<package name="struts" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="SessionInterceptor" class="com.sagar.interceptors.SessionInterceptor"></interceptor>
<interceptor name="ParameterInterceptor" class="com.sagar.interceptors.ParameterInterceptor"></interceptor>
<interceptor name="OrderInterceptor" class="com.sagar.interceptors.OrderInterceptor"></interceptor>
<interceptor-stack name="commonStack">
<interceptor-ref name="timer" />
<interceptor-ref name="SessionInterceptor" />
<interceptor-ref name="ParameterInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<global-results>
<result name="unhandledError">/unhandledErrorPage.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="unhandledError" />
</global-exception-mappings>
<action name="masterData" class="com.sagar.common.services.MasterDataAccess">
<interceptor-ref name="commonStack" />
<result type="stream" name="success">
<param name="contentType">text/plain</param>
<param name="inputName">inputStream</param>
</result>
</action>
</struts>
I want to open an excel sheet (.csv file) on click of a hyper link in html.The document will be stored in a folder within the current project root folder.
//for action you need to do following code
public String execute() throws Exception {
fileInputStream = new FileInputStream(new File("C:\\test.csv"));
return SUCCESS;
}
//Struts.xml file need following changes.fileInputStream contains the FileInputStream to be added to struts.xml.
<action name="download" class="com.expertwebindia.action.DownloadAction">
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">fileInputStream</param>
<param name="contentDisposition">attachment;filename="test.csv"</param>
<param name="bufferSize">1024</param>
</result>
</action>
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>
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.
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>