I have written an interceptor to prevent caching but the pages still cache.
Interceptor:
public class ClearCacheInterceptor implements Interceptor {
public String intercept(ActionInvocation invocation)throws Exception{
String result = invocation.invoke();
ActionContext context = (ActionContext) invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
HttpServletResponse response=(HttpServletResponse) context.get(StrutsStatics.HTTP_RESPONSE);
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
return result;
}
public void destroy() {}
public void init() {}
}
Struts.xml
<struts>
<constant name="struts.devMode" value="true"/>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="caching" class="com.struts.device.interceptor.ClearCacheInterceptor"/>
<interceptor-stack name="cachingStack">
<interceptor-ref name="caching" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<action name="Login" class="struts.device.example.LogIn">
<interceptor-ref name="cachingStack"/>
<result>example/Add.jsp</result>
<result name="error">example/Login.jsp</result>
</action>
</package>
</struts>
Application works fine; it executes interceptor but it doesn't prevent caching.
I have solved my problem. Thanks to developer tools for helping me to trace out.
A slight sequence change in my code helped me out: as per the Struts 2 interceptor docs the result is rendered before invocation.invoke() returns. Setting the headers before the result is rendered back to the client sets the headers in the returned result.
i.e.,
public String intercept(ActionInvocation invocation)throws Exception{
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
return invocation.invoke();
}
Related
i am calling a struts2 action by passing parameter from a dynamic image url
<img src="<s:url action='ImageAction?imageId=logo.jpg' />"/>
With this my action is calling properly but the parameter imageId=logo.jpg is not passing to my action class.
But if i manully pass parameter from the browser url then, parameter is correctly showing into my java page eg. http://localhost:8080/mypoject/jspHomepage/bookstransaction/secure/ImageAction?imageId=logo.jpg
What could be reason for this?
Please help me.
struts.xml
`
`<package name="Image" extends="struts-default,json-default">
<result-types>
<result-type name="imageResult"
class="v.esoft.actions.changetheme.CustomImageBytesResult" />
</result-types>
<action name="updatethemeimageform" class="v.esoft.actions.changetheme.ThemedetailsEditAction" method="updateThemesImage">
<result name="success" type="json"/>
<result name="input" type="json"/>
</action>
<action name="Display" class="v.esoft.actions.changetheme.DisplayAction">
<result name="success" type="json"/>
</action>
<action name="ImageAction" class="v.esoft.actions.changetheme.ImageAction">
<result name="success" type="imageResult">
</result>
</action>
</package>`
ImageAction.java
public class ImageAction extends ActionSupport implements ServletRequestAware {
byte[] imageInByte = null;
String imageId;
private HttpServletRequest servletRequest;
public String getImageId() {
return imageId;
}
public void setImageId(String imageId) {
this.imageId = imageId;
}
public ImageAction() {
System.out.println("ImageAction");
}
public String execute() {
return SUCCESS;
}
public byte[] getCustomImageInBytes() {
System.out.println("imageId" + imageId);
}
}
Following is untested.
Use param tags to add parameters.
<s:url package="Image" action="ImageAction" var="myUrl">
<s:parm name="imageId" value="'logo.jpg'"/>
</s:url>
<img src="<s:property value="#myUrl"/>"/>
Note: I suspect in the final line myUrl should be sufficient (without the #) but don't remember at the moment.
I want to upload an image using struts2 using the function copyFile()
but when i use ServletRequestAware not supported yet exception is thrown. please help me to solve this problem.
here is my code
index.jsp
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<body>
<s:form action="uploadAction.action" method="post" enctype="multipart/form-data">>
<s:textfield label="caption" name="caption"/>
<input type="file" name="userImage"/>
<s:submit name="submit" label="Submit"/>
</s:form>
</body>
</html>
uploadFile.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>
<package name="attribute" extends="struts-default">
<action name="uploadAction" class="com.scrolls.fileupload.action.UploadImageAction" method="uploadImage">
<interceptor-ref name="fileUpload">
<param name="maximumSize">2097152</param>
<param name="allowedTypes">
image/png,image/gif,image/jpeg,image/pjpeg
</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">ImageUploadSuccess.jsp</result>
<result name="input">index.jsp</result>
</action>
</package>
</struts>
UploadImageAction.java
package com.scrolls.fileupload.action;
import com.opensymphony.xwork2.ActionSupport;
import java.io.File;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.interceptor.ServletRequestAware;
public class UploadImageAction extends ActionSupport implements ServletRequestAware {
private File userImage;
private String userImageContentType;
private String caption;
private HttpServletRequest servletRequest;
public String uploadImage() {
try {
HttpSession session = servletRequest.getSession();
ServletContext context = session.getServletContext();
String filePath = context.getRealPath("/");
System.out.println("Server path:" + filePath);
File fileToCreate = new File(filePath, this.caption);
FileUtils.copyFile(this.userImage, fileToCreate);
}
catch (Exception e) {
System.out.println(e);
return INPUT;
}
return SUCCESS;
}
public File getUserImage() {
return userImage;
}
public void setUserImage(File userImage) {
this.userImage = userImage;
}
public String getUserImageContentType() {
return userImageContentType;
}
public void setUserImageContentType(String userImageContentType) {
this.userImageContentType = userImageContentType;
}
public String getCaption() {
return caption;
}
public void setCaption(String caption) {
this.caption = caption;
}
#Override
public void setServletRequest(HttpServletRequest hsr) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
ImageUploadSuccess.jsp
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<body>
<h2>Struts2 Image Upload</h2>
<b>Image Uploaded To Folder :</b><s:property value="userImage"/>
<br/>
<b>Content Type:</b> <s:property value="userImageContentType"/>
<br/>
<b>Uploaded Image Name:</b> <s:property value="caption"/>
<br/>
<b>Uploaded Image Preview :</b>
<br/>
<img src="<s:property value="userImageFileName"/>"/>
</body>
</html>
Exception:
SEVERE: Servlet.service() for servlet [default] in context with path [/fileupload] threw exception [java.lang.UnsupportedOperationException: Not supported yet.] with root cause
java.lang.UnsupportedOperationException: Not supported yet.
at com.scrolls.fileupload.action.UploadImageAction.setServletRequest(UploadImageAction.java:81)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:131)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:268)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:50)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:504)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
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)
... You're throwing that exception, precisely where the stack trace tells you you are.
Are you unaware of Java stack traces? Are you unable to read the information it provides?
It's pointing to your code.
First of all defaultStack already includes fileUpload interceptor so you have to configure that interceptor instead of adding it twice to your action interceptors stack.
<action name="uploadAction" class="com.scrolls.fileupload.action.UploadImageAction" method="uploadImage">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">2097152</param>
<param name="fileUpload.allowedTypes">
image/png,image/gif,image/jpeg,image/pjpeg
</param>
</interceptor-ref>
<result name="success">ImageUploadSuccess.jsp</result>
<result name="input">index.jsp</result>
</action>
Second: in Struts2 you do not need to read submitted file from request. Read about file upload http://struts.apache.org/2.x/docs/file-upload.html.
You can try download example project from this link.
http://javapostsforlearning.blogspot.com/2012/07/file-upload-in-struts-2.html
I have tried it already, it works.(thanks to the tutorial creator)
I'm a beginner in Struts2. I am used in PHP, while logging to save authentification in a session variable, which I can destroy after logging out. I wonder how I can do the same process in Struts2 : to set a session variable while logging in and to destroy it while logging out. Thank you a lot.
Update ( An additional solution )
In addition to the useful answers and comments, we can use :
session.remove("session_var_name"); // instead of session.clear();
to remove one exact session variable instead of removing all the session variables. Thank you all.
You can do one of the following
public class MyAction extends ActionSupport implements ServletRequestAware
{
private HttpServletRequest httpServletRequest;
public void setServletRequest(HttpServletRequest request)
{
this.httpServletRequest = request;
}
public String login()
{
httpServletRequest.getSession(false).setAttribute("key", your_session_object);
return SUCCESS;
}
public String logout()
{
httpServletRequest.getSession(false).removeAttribute("key");
return SUCCESS;
}
}
public class MyAction extends ActionSupport implements SessionAware
{
private Map sessionMap;
public void setSession(Map map)
{
this.sessionMap = map;
}
public String login()
{
sessionMap.put(key, your_session_object);
return SUCCESS;
}
public String logout()
{
sessionMap.remove(key);
return SUCCESS;
}
}
The second alternative i.e. implementing SessionAware is preferred since it shields you from Servlet APIs.
You can use Scope Interceptor when you call logout, and with "end" type in your struts xml configuration, Interceptor set null to your session object:
<action name="scopea" class="com.mevipro.test.action.ScopeActionA">
<result name="success" type="dispatcher">/jsp/test.jsp</result>
<interceptor-ref name="basicStack"/>
<interceptor-ref name="scope">
<param name="key">funky</param>
<param name="session">person</param>
<param name="type">start</param>
</interceptor-ref>
</action>
<action name="scopeb" class="com.mevipro.test.action.ScopeActionB">
<result name="success" type="dispatcher">/jsp/test.jsp</result>
<interceptor-ref name="scope">
<param name="key">funky</param>
<param name="session">person</param>
<param name="type">end</param>
</interceptor-ref>
<interceptor-ref name="basicStack"/>
</action>
you must define "start" and "end" the start is when you initialise your object in session and the "end" for destroy your object
For more detail : https://struts.apache.org/docs/scope-interceptor.html
I am working on Struts2 Interceptors .
I have read that Struts2 Interceptors are just like Filters , which execute before the Action class is executed and one more time after processing the result ( Please correct me if i am wrong ) , that is two times
But when i ran the below code , the interceptors are executed only once .
Please correct me if i made any mistake .
Please see my code below :
This is My Struts.xml file
<struts>
<constant name="struts.devMode" value="true" />
<package name="test" extends="struts-default">
<interceptors>
<interceptor name="loginkiran" class="vaannila.MyLoginInterCeptor" />
</interceptors>
<action name="HelloWorld" class="vaannila.HelloWorld" method="kiran">
<interceptor-ref name="loginkiran" />
<result name="SUCCESS">/success.jsp</result>
</action>
</package>
</struts>
This is my Action class
public class HelloWorld
{
public HelloWorld() {
}
public String kiran() {
System.out.println("iNSIDE THE aCTION CLASS");
return "SUCCESS";
}
}
This is my Interceptor class
public class MyLoginInterCeptor implements Interceptor {
#Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("Destroying Interceptor");
}
#Override
public void init() {
}
#Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = (HttpServletRequest) ActionContext
.getContext().get(ServletActionContext.HTTP_REQUEST);
System.out.println("iNSIDE THE iNTERCEPTOR");
return invocation.invoke();
}
}
This is my JSP File :
<html>
<body>
<%
System.out.println("iNSIde THE jsp");
%>
</body>
</html>
The Output for the above code is this :
iNSIDE THE iNTERCEPTOR
iNSIDE THE aCTION CLASS
iNSIde THE jsp
Interceptors are not executed twice (nor are filters): interceptors (and filters) wrap the action (or servlet/etc.)
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("Before action invocation...");
return invocation.invoke();
System.out.println("After action invocation...");
}
in struts 2 execute method is not called by default.
I have HelloWorld.java as controller and HelloWorld.jsp this is my struts.xml
<struts>
<package name="example" namespace="/example" extends="struts-default">
<action name="add" class="example.HelloWorld" method="add">
<result name="SUCCESS" type="redirect">HelloWorld</result>
</action>
<action name="HelloWorld"
class="example.HelloWorld">
<result name="input">/example/HelloWorld.jsp</result>
</action>
</package>
package example;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
import java.util.List;
/**
* <code>Set welcome message.</code>
*/
public class HelloWorld extends ActionSupport {
private static final long serialVersionUID = 9149826260758390091L;
private Contacts Contacts;
private ContactManager linkController;
private List<Contacts> ContactsList;
public HelloWorld() {
linkController = new ContactManager();
}
#Override
public String execute() {
if (null != Contacts) {
linkController.add(getContacts());
}
this.ContactsList = linkController.list();
System.out.println(ContactsList);
System.out.println(ContactsList.size());
return SUCCESS;
}
public String add() {
System.out.println(getContacts());
getContacts().setBirthdate(new Date());
try {
linkController.add(getContacts());
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
public Contacts getContacts() {
return Contacts;
}
public void setContacts(Contacts Contacts) {
this.Contacts = Contacts;
}
public List<Contacts> getContactsList() {
return ContactsList;
}
public void setContactsList(List<Contacts> ContactsList) {
this.ContactsList = ContactsList;
}
}
You have only input result in struts.xml and returning success in execute().
<package name="example" namespace="/example" extends="struts-default">
<action name="add" class="example.HelloWorld" method="add">
<result name="SUCCESS" type="redirect">HelloWorld</result>
</action>
<action name="HelloWorld"
class="example.HelloWorld">
<result name="input">/example/HelloWorld.jsp</result>
<!-- FOLLOWING LINE IS MISSING -->
<result name="SUCCESS">/example/HelloWorld.jsp</result>
</action>
</package>
I Faced same issue and found solution for this.
Your validation.xml should handle the attributes which are in ActionClass only.
For each ActionClass should maintain unique Action-Validation file.
Dont mingle all actions in different J
<package name="example" namespace="/example" extends="struts-default">
<action name="add" class="example.HelloWorld" method="add">
<result name="SUCCESS" type="redirect">HelloWorld</result>
<result name="input" type="redirect">HelloWorld</result>
</action>
<action name="HelloWorld" class="example.HelloWorld">
<result name="input">/example/HelloWorld.jsp</result>
<result name="SUCCESS">/example/HelloWorld.jsp</result>
</action>`
Try this. This may help you.