I want to post a picture to my server(tomcat 7.0.40).
And the project is built on apache-struts2-2.2.1 and spring 3.6 and apache-commons-fileupload.
First, I do some html code.
<input type="file" name="xxx" id="ccc" />
OK,next. I make an action extends ActionSupport.
public XxxAction extends ActionSupport{
private java.io.File xxx;
public String execute() throws Exception{
......
}
//getter and setter below
}
And next,this action injected by spring config like:
<bean id="xxxAction" class="xxx.xxx.XxxAction" />
May be you have found I lost scope="prototype",but please ignore it, because the problem is not there.
Next, configured by struts2.xml like:
<package name="xxx" namespace="/xxx" extends="json-default">
<action name="upload" class="xxxAction">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/gif,image/jpg</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result>
<param name="root">toFrontJson</param>
</result>
</action>
</package>
OK,now submit a pic file to server.We assume the file can be received by action. But when the pic is large enough to passing for a moment, and half of passing I closed the web browser. It will get SocketTimeOut Exception. I find the server.xml in tomcat config folder, the connection timeout is settled to 20000. And the most important when I got this exception. Other request to this action cannot access. It will get:
cannot find aciton or result ......
I think the SocketTimeOut Excepiton must cause some things happen. It let the action instance disappear. So I add scope="prototype" in spring.xml. It works. Although when I interrupt fileupload operation, I got some other exception,but Other request is OK.
But I hope know what happened before I add scope="prototype", why other request cannot find action, and why I got SocketTimeOut Exception.
In apache-commons-fileupload? Or Struts 2?
The default scope used by Spring is singleton. So your code is failed because of synchronization IO operation on the file.
When you changed it to prototype then each action has its own instance of the action bean, so they are use its own field and don't stuck on each other.
Related
I use the Struts2 framework to create a webapp. I have an interceptor that should have different behaviour depending on which action is invoked. For example, a login interceptor that should always allow some actions to execute, but it should block other actions if the user is not yet logged in.
The way I solve this now is by manually checking the name (and/or namespace) of the action in the interceptor, and determine my behaviour based on that. The downside of this "hardcocded" logic is that it is hard to maintain if I edit my struts.xml file, and it is also not obvious what is going on for other developers.
I would like to know if these is some way to add 'metadata' INSIDE the struts.xml file (or other file?) to "mark" certain actions as being certain "type". For example, something like this:
Struts.xml
<action name="loginPage" types="login, user, viewpage" class="login.controller.LoginPage">
<result name="success">/login/jsp/Login.jsp</result>
</action>
And then in my interceptor class:
#Override
public String intercept(ActionInvocation invocation)
throws Exception
{
Set<String> actionTypes = invocation.getInvocationContext().getTypes();
if(actionTypes.contains("login")
{
doSomething();
}
else
{
doSomethingElse();
}
}
Is this possible, or is the hardcoded parsing of name(space) the only way?
Obviously you can't do that because the DTD won't allow you.
Another good example of the XY problem:
The XY problem is asking about your attempted solution rather than your actual problem.
That is, you are trying to solve problem X, and you think solution Y would work, but instead of asking about X when you run into trouble,
you ask about Y.
What you really need is to define a group of actions running free, and other groups running under login control.
For this, you can manually include the Interceptor in each single action (useful when using the Convention plugin, a waste of time otherwise), or configuring the actions logically in the struts.xml.
The <package> is your friend here: define two (or more) packages, one running with the default settings, the other running your custom Interceptor for each action of the package:
<package name="unsecure-package" namespace="/unsecure" extends="struts-default">
<action name="login" class="org.foo.bar.actions.LoginAction">
...
</action>
<action name="askHelp" class="org.foo.bar.actions.AskHelpAction">
...
</action>
</package>
<package name="secure-package" namespace="/secure" extends="struts-default">
<interceptors>
<interceptor name="authInterceptor"
class="org.foo.bar.interceptor.AuthInterceptor"/>
<interceptor-stack name="securedStack">
<interceptor-ref name="authInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="securedStack"/>
<action name="write" class="org.foo.bar.actions.WriteAction">
...
</action>
<action name="delete" class="org.foo.bar.actions.DeleteAction">
...
</action>
</package>
This way every time you or somebody else will add an Action in struts.xml, it will just need to drop it in the right package, and it will work automatically.
It's better to keep the Interceptor action-agnostic whenever possible ;)
I have a slight problem with forwarding using Struts.
Now when users accessing my page like this -> http://mypage/
they are automatically forwarded to /index.jsp.
But I'd also like to have index.jsp to be linked to name "sg".
So when they access page like this :
http://mypage/ > they will be forwarded to http://mypage/sg
which is http://mypage/index.jsp.
As I've already mentioned above I'm using Struts to handle all these action. The below example is what I have in my struts.xml file. But it's working rather partially. When I access the page as stated above I'm getting redirected to http://mypage/sg and it also gives me 404 - Not Found.
However when I try manually accessing the url (http://mypage/sg), it works perfectly.
<package name="index" namespace="/" extends="default">
<action name="">
<result>/sg</result>
</action>
<action name="/sg">
<result>/index.jsp</result>
</action>
</package>
When I access the page as stated above I'm getting redirected to http://mypage.com/sg and it also gives me 404 - Not Found.
Answer :
If you want to call another action as result of one action then you need to mention attribute type of result tag
<action name="">
<result type="redirect">/sg</result>
</action>
This will redirect to action sg.
The redirect result type:
The redirect result type calls the standard response.sendRedirect() method, causing the browser to create a new request to the given location.
Struts2 newbie here. I've got a JSP file that has an anchor linking to an Action called "authenticate". When I click on the anchor, I get an error message: java.lang.NoSuchMethodException: mypackage.DisplayStuff.authenticate()
java.lang.Class.getMethod(Unknown Source)
Here is my struts.xml
<package name="default" extends="struts-default" namespace="/">
<action name="display" method="authenticate"
class="mypackage.DisplayStuff">
<result name="error">Boo.jsp</result>
<result name="success">Yay.jsp</result>
</action>
</package>
And here is my action file:
package mypackage;
public class DisplayStuff {
public String authenticate() {
return "success";
}
}
And finally, in my JSP, I have this anchor:
click here
The interesting part, is if I rename my method to the default "execute" I don't get this error. Shouldn't I be able to call any method in my DisplayStuff action?
There are a few possibilities.
That the error message references a different package my first guess is that you haven't deployed the latest version of your code: struts.DisplayStuff.authenticate isn't how it's configured.
Second guess is an issue with a Struts 2 plugin (like "convention") mucking with your configuration.
Without more details, however, it's difficult to think much more about it.
This should be
click here
In struts-config I have action like this :
<action
path="/action/basket"
type="com.xxx.BasketAction"
name="basketForm"
scope="session"
unknown="false"
validate="false"
>
<forward
name="displayItems"
path="EshelfItems"
redirect="false"
/>
<forward
name="displayItems-redirect"
path="/action/basket.do?fn=display"
redirect="true"
/>
<forward
name="displayBasket"
path="/basket.jsp"
redirect="false"
/>
</action>
Where I can find the mapping for /action/basket.do?fn=display ?
According to http://struts.apache.org/1.x/faqs/works.html :
In the framework configuration file(s), you associate paths with the
controller components of your application, known as Action classes
(i.e. "login" ==> LoginAction class). This tells the ActionServlet
that for the incoming request 'http://myhost/myapp/login.do' it should
invoke your controller component, LoginAction.
Note the extension .do in this URL. The extension causes your
container (i.e. Tomcat) to call the ActionServlet, which sees the word
"login" as the thing you want to do. The configuration is referenced,
and your LoginAction is executed.
Check your BasketAction class where the fn=display request parameter is checked.
If you can't find the action class for a given mapping then debugging your
RequestProcessor's process method can be also useful.
Ya your question is not clear..
When you hit /action/basket.do?fn=display its going to use the following mapping in your struts config.
<action
path="/action/basket"
And then it will execute
com.xxx.BasketAction
and in that class if you want you can read the param fn=display and then do a forward and that will work as mapped in <forward>...</forward> mapping of your struts config
I'm working on a little project which uses Struts 1.3 and I encountered the following problem.
After some business logic takes place in an Action i want to forward the control to another Action which is mapped in struts-config.xml.
Usually this is the way I'm solving this:
struts-config.xml
<action path="/boardCreate" type="com.example.BoardCreateAction" name="BoardCreateForm" input="/board.jsp">
<forward name="success" path="/board.do" redirect="true" />
</action>
Java action class
return mapping.findForward("success");
This will take make a redirect to the board.do action which is also mapped there.
My problem is that I want to redirect the control to something like:
<forward name="success" path="/board.do?id=1" redirect="true" />
Notice the id=1 parameter. Is this any other way except rebuilding my own action forward for this? I can't find any documentation debating this matter. Thanks!
ActionRedirect redirect = new ActionRedirect(mapping.findForward("success"));
redirect.addParameter("id", theId);
return redirect;
See http://tool.oschina.net/uploads/apidocs/struts-1.3.10/org/apache/struts/action/ActionRedirect.html