Different result param name in XML with different property name in Action - struts2

The below code works well to download a file.
Here name of the param is inputName in xml and property in Action is fileInputStream.I don't know how it works with different name in xml and Action.
XML :
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">fileInputStream</param>
<param name="contentDisposition">attachment;filename="fileABC.txt"</param>
<param name="bufferSize">1024</param>
</result>
Action :
private InputStream fileInputStream;
public InputStream getFileInputStream() {
return fileInputStream;
}
public String execute() throws Exception {
fileInputStream = new FileInputStream(new File("C:\\downloadfile.txt"));
return "success";
}

Param name inputName indicate name of your stream object.
See this Doc refrence:
inputName - the name of the InputStream property from the chained action
(default = inputStream).
param name inputName is not related to your variable name in action class, instead its value is related to your variable present in your action class.

Related

How to configure dynamic "input" results in Struts2

Suppose I configure a "per method" validation into my action, using the Struts2 validation framework (in my example with annotations, but also with xml it is the same).
Suppose I have three public exposed methods in my action:
public class MyAction extends ActionSupport {
#Override
public String execute() throws Exception {
//some code here...
}
#Validations(
customValidators = {#CustomValidator(type="myCostomValidator", fieldName="myFieldName", shortCircuit=true, message="")}
)
public String info() {
//some code here...
}
#Validations(
customValidators = {#CustomValidator(type="myCostomValidator", fieldName="anotherFieldName", shortCircuit=true, message="")},
visitorFields = {#VisitorFieldValidator(context="update_context", fieldName="anObjectField", message="", shortCircuit=true)}
)
public String update() {
//some code here...
}
//getters, setters and other...
}
Now, each of the three methods can be invoked and has a different validation. If the validation fails the framework set the result "input" that must be configured into the struts.xml:
<action name="myAction_*" method="{1}" class="com.test.gui.action.test.MyAction">
<result name="success">result1.jsp</result>
<result name="edit">result2.jsp</result>
<result name="input">result3.jsp</result>
</action>
How can I have different "input" results for each action method? For example, I'd like to reach one page if the validation fails for the info() method and another page if the validation fails for the update() method.
Thank you.
I've found this solution: the use of #InputConfig annotation.
With this annotation you can set a 'per method' result name for validation errors. So in the struts.xml you can configure for each result name the page that you want to reach.
Examples:
#InputConfig(resultName="input_update")
public String update() {
// perform action
return SUCCESS;
}
and in struts.xml: <result name="input_update">jsp/input_update.jsp</result>
or:
#InputConfig(methodName="inputMethod")
public String update() {
// perform action
return SUCCESS;
}
public String inputMethod() {
// perform some data filling
return INPUT;
}
struts.xml: <result name="input">jsp/myInput.jsp</result>
See documentation at struts.apache.org/docs/inputconfig-annotation.html
It can also be set the input result name in the struts.xml by setting a parameter for the 'workflow' interceptor, but it affects all methods in the action:
<interceptor-ref name="workflow">
<param name="inputResultName">custom_input_result</param>
</interceptor-ref>
see doc here struts.apache.org/docs/default-workflow-interceptor.html
You don't have to modify returned result name. You are using wildcard mapping for your action, so use it for JSP file name as well.
<action name="myAction_*" method="{1}" class="com.test.gui.action.test.MyAction">
<result name="success">success.jsp</result>
<result name="input">result_{1}.jsp</result>
</action>

retrieve action message on multiple action classes in struts2

I am developing one java project using struts2 and hibernate
i have one super action class name it as ProjAction where in that project management every event will come across the main Super Class.
i have one child action class name it as saveDataAction after saving the data it goes to the super action class and gives the result.
So upto to the Super action class i can able to display the action message using the store interceptor in struts2 config file for its respective action class results. i have used the operationMode as 'AUTOMATIC'
NOW to avoid the refresh issue i have one action class name it as ProjRedirectAction. So in this action class i am not able to show/retrieve the action message after saving the data
can anyone tell me how to access the action message in ProjRedirectAction class using store interceptor. or else is there any way to show the action message to multiple action classes of struts2.
public class SuperAction extends ActionSupport {
public String getData() {
//implementation for showing the data in the jsp page
//the result is always redirect to some default.jsp
return SUCCESS;
}
//private method which accessed by its child class for redirecting to superclass
public String nextCall() {
//few implementation done after that it calls the getData() method
return getData();
}
}
//Child Class implementaion for ex saving records in db
public class ChildAction extends SuperAction {
public String saveData() {
//saving data to db and then calling the return nextCall method of superACtion class
return nextCall();
}
}
//earlier i had this implementation, the reason being adding one more action class in my project is to avoid refresh issue(on refresh the same value was inserting to DB) so i have added one more action class with name RedirectAction
//RedirectACtion class implementation
public class RedirectAction {
public String execute() {
//this method is having same implementation as the method getData() of SuperAction class includes
return SUCCESS;
}
}
//struts.xml config
<package name="default" extends="struts-default" namespace="/">
//SuperACtion class result
<action name="*Super" method="{1}" class="com.action.SuperAction">
<interceptor-ref name="store">
<param name="operationMode">AUTOMATIC</param>
</interceptor-ref>
<result name="SUCCESS" type="redirectAction">executeRedirect</result>
</action>
//ChildACtion class result
<action name="*Child" method="{1}" class="com.action.ChildAction">
<interceptor-ref name="store">
<param name="operationMode">AUTOMATIC</param>
</interceptor-ref>
<result name="SUCCESS" type="redirectAction">executeRedirect</result>
</action>
//RedirectACtion class result
<action name="*Redirect" method="{1}" class="com.action.RedirectAction">
<interceptor-ref name="store">
<param name="operationMode">AUTOMATIC</param>
</interceptor-ref>
<result name="SUCCESS" type="tiles">Default.jsp</result>
</action>
this issue i am not finding any solution , any help is really appriciated
thank you

Strut2 - Get Property value in next Action

I am using <s:form action="someAction">
my struts.xml contains
<action name="someAction"
class="com.test.testaction.getValue"
method="getValuedemo">
<result name="success" type="redirectAction">demo</result>
</action>
while my Action contains
public class getValue extends ActionSupport{
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getValuedemo() {
userName = "tmpUser";
}
}
My question is how to get userName property in demo.action????? Please help
You can pass userName as a parameter
<action name="someAction" class="com.test.testaction.getValue" method="getValuedemo">
<result name="success" type="redirectAction">
<param name="actionName">demo</param>
<param name="userName">${userName}</param>
</result>
</action>
Also add userName getter/setter in the demo action
Values associated with a specific action are per-request. If you set values in an action and then redirect, those values will be lost. If getValue is just redirecting to demo, what is the purpose of the getValue action? Why not just have the userName getter and setter on DemoAction?
Please revise your question to provide more details on what you are trying to do.
Additionally, your action name does not adhere to Java naming conventions for a class, which should start with a capital letter. Additionally, you might want to come up with a better name for the action than GetValue.
First use the chain result type...
<result name="success" type="chain">demo.action</result>
Then read about interceptors so you can avoid using chain, redirect, redirectAction.

Programatically get controller address of ASP.NET MVC application

Say I want to send an email from my MVC application containing a link back to an item.
So I want something in my controller like:
string link = "www.mysite/mycontroller/itemdetails/23";
can I retrieve this programatically so it works on whatever server/configuration i happen stick it on?
eg
string link = GetCurrentActionRoute() + "23";
public ActionResult Index()
{
string link = Url.Action(
(string)RouteData.Values["action"],
(string)RouteData.Values["controller"],
new { id = "23" },
Request.Url.Scheme
);
// TODO: do something with the generated link
return View();
}
I use the extension methods below from my Controller classes to generate links to various actions.
Examples:
string link = this.Action("Play");
string fullLink = this.FullUrlAction("Play", new { id = 1 });
Methods:
/// <summary>
/// Helper Extensions to the Controller class.
/// </summary>
public static class ControllerExtensions
{
/// <summary>
/// Get an action link for a controller.
/// </summary>
/// <param name="controller">Controller instance.</param>
/// <param name="action">Action to provide the link for.</param>
/// <returns>Link Url for the Action.</returns>
public static string Action(this Controller controller, string action)
{
RouteValueDictionary rvd = new RouteValueDictionary
{
{ "controller", controller.GetType().Name },
{ "action", action }
};
return RouteTable.Routes.GetVirtualPath(controller.ControllerContext.RequestContext, rvd).VirtualPath;
}
/// <summary>
/// Get an action link for a controller.
/// </summary>
/// <param name="controller">Controller instance.</param>
/// <param name="action">Action Name.</param>
/// <param name="parameters">Action Parameters.</param>
/// <returns>Link Url for the action with parameters.</returns>
public static string Action(this Controller controller, string action, object parameters)
{
string controllerName = controller.GetType().Name;
if (controllerName.EndsWith("Controller"))
{
controllerName = controllerName.Substring(0, controllerName.Length - 10);
}
return controller.Action(controllerName, action, parameters);
}
/// <summary>
/// Get an action link for a controller.
/// </summary>
/// <param name="controller">Controller instance.</param>
/// <param name="targetController">Target controller for action.</param>
/// <param name="action">Action Name.</param>
/// <param name="parameters">Action Parameters.</param>
/// <returns>Link Url for the action on the given controller.</returns>
public static string Action(this Controller controller, string targetController, string action, object parameters)
{
RouteValueDictionary rvd = new RouteValueDictionary(parameters)
{
{ "controller", targetController },
{ "action", action }
};
return RouteTable.Routes.GetVirtualPath(controller.ControllerContext.RequestContext, rvd).VirtualPath;
}
/// <summary>
/// Get a fully qualified action link for a controller.
/// </summary>
/// <param name="controller">Controller instance.</param>
/// <param name="action">Action Name.</param>
/// <param name="parameters">Action Parameters.</param>
/// <param name="requestUrl">Current request URI.</param>
/// <returns>Fully qualified Link Url.</returns>
public static string FullUrlAction(this Controller controller, string action, object parameters, Uri requestUrl)
{
string controllerName = controller.GetType().Name;
if (controllerName.EndsWith("Controller"))
{
controllerName = controllerName.Substring(0, controllerName.Length - 10);
}
return controller.FullUrlAction(controllerName, action, parameters, requestUrl);
}
/// <summary>
/// Get a fully qualified action link for a controller.
/// </summary>
/// <param name="controller">Controller instance.</param>
/// <param name="targetController">Target controller for action.</param>
/// <param name="action">Action Name.</param>
/// <param name="parameters">Action Parameters.</param>
/// <param name="requestUrl">Current request URI.</param>
/// <returns>Fully Qualified Link Url.</returns>
public static string FullUrlAction(this Controller controller, string targetController, string action, object parameters, Uri requestUrl)
{
string testUrl = VirtualPathUtility.ToAbsolute(controller.Action(targetController, action, parameters));
return new Uri(requestUrl, testUrl).ToString();
}
}
If the link will point to the same location as that of the application ,you may consider using the Url.Action(...) and its overloads.
Eg.
string actionRoute = Url.Action("action method name","controller name");
If you want to get the complete path, you can use :
string domainRoute = HttpContext.Request.Url.AbsolutePath;
and then concatenate the id with that.

How to render an action link with an image?

I know to use Html.ActionLink() to render textual <a href..."> links to actions.
How do I render a link to an action that has an underlying image as the link?
<img src="asdfasdf"/>
Here is code for the ImageLink HtmlHelper extension I use.
/*
* Image Link HTML helper
*/
/// <summary>
/// return image link
/// </summary>
/// <param name="helper"></param>
/// <param name="imageUrl">URL for image</param>
/// <param name="controller">target controller name</param>
/// <param name="action">target action name</param>
/// <param name="linkText">anchor text</param>
public static string ImageLink(this HtmlHelper helper, string imageUrl, string controller, string action, string linkText)
{
return ImageLink(helper, null, controller, action, linkText, imageUrl, null, null, null, null);
}
/// <summary>
/// return image link
/// </summary>
/// <param name="helper"></param>
/// <param name="imageUrl">URL for image</param>
/// <param name="controller">target controller name</param>
/// <param name="action">target action name</param>
/// <param name="linkText">anchor text</param>
/// <param name="htmlAttributes">anchor attributes</param>
public static string ImageLink(this HtmlHelper helper, string imageUrl, string controller, string action, string linkText, object htmlAttributes)
{
return ImageLink(helper, null, controller, action, linkText, imageUrl, null, null, new RouteValueDictionary(htmlAttributes), null);
}
/// <summary>
/// return image link
/// </summary>
/// <param name="helper"></param>
/// <param name="imageUrl">URL for image</param>
/// <param name="controller">target controller name</param>
/// <param name="action">target action name</param>
/// <param name="linkText">anchor text</param>
/// <param name="htmlAttributes">anchor attributes</param>
/// <param name="routeValues">route values</param>
public static string ImageLink(this HtmlHelper helper, string imageUrl, string controller, string action, string linkText, object htmlAttributes, object routeValues)
{
return ImageLink(helper, null, controller, action, linkText, imageUrl, null, null, new RouteValueDictionary(htmlAttributes), new RouteValueDictionary(routeValues));
}
/// <summary>
/// return image link
/// </summary>
/// <param name="helper"></param>
/// <param name="id">Id of link control</param>
/// <param name="controller">target controller name</param>
/// <param name="action">target action name</param>
/// <param name="strOthers">other URL parts like querystring, etc</param>
/// <param name="strImageURL">URL for image</param>
/// <param name="alternateText">Alternate Text for the image</param>
/// <param name="strStyle">style of the image like border properties, etc</param>
/// <returns></returns>
public static string ImageLink(this HtmlHelper helper, string id, string controller, string action, string linkText, string strImageURL, string alternateText, string strStyle)
{
return ImageLink(helper, id, controller, action, linkText, strImageURL, alternateText, strStyle, null, null);
}
/// <summary>
/// return image link
/// </summary>
/// <param name="helper"></param>
/// <param name="id">Id of link control</param>
/// <param name="controller">target controller name</param>
/// <param name="action">target action name</param>
/// <param name="linkText">anchor text</param>
/// <param name="strImageURL">URL for image</param>
/// <param name="alternateText">Alternate Text for the image</param>
/// <param name="strStyle">style of the image like border properties, etc</param>
/// <param name="htmlAttributes">html attribues for link</param>
/// <returns></returns>
public static string ImageLink(this HtmlHelper helper, string id, string controller, string action, string linkText, string strImageURL, string alternateText, string strStyle, IDictionary<string, object> htmlAttributes, RouteValueDictionary routeValues)
{
// Build the img tag
TagBuilder image = new TagBuilder("img");
image.MergeAttribute("src", strImageURL);
image.MergeAttribute("alt", alternateText);
image.MergeAttribute("valign", "middle");
image.MergeAttribute("border", "none");
TagBuilder span = new TagBuilder("span");
// Create tag builder
var anchor = new TagBuilder("a");
var url = new UrlHelper(helper.ViewContext.RequestContext).Action(action, controller, routeValues);
// Create valid id
anchor.GenerateId(id);
// Add attributes
//anchor.MergeAttribute("href", "/" + controller + "/" + action); //form target URL
anchor.MergeAttribute("href", url);
anchor.MergeAttribute("class", "actionImage");
if (htmlAttributes != null)
anchor.MergeAttributes(new RouteValueDictionary(htmlAttributes));
// place the img tag inside the anchor tag.
if (String.IsNullOrEmpty(linkText))
{
anchor.InnerHtml = image.ToString(TagRenderMode.Normal);
}
else
{
span.InnerHtml = linkText;
anchor.InnerHtml = image.ToString(TagRenderMode.Normal) + " " + span.ToString(TagRenderMode.Normal);
}
// Render tag
return anchor.ToString(TagRenderMode.Normal); //to add </a> as end tag
}
Here is a post about creating strongly typed ActionImage extensions. Should get you started if you don't like those horrible error-prone magic strings.
<%=Html.ActionLink(
Html.Image("~/Images/bigwave.jpg"),
new {controller="Hurr", action="Durr"})) %>
Check here for how to create the Image method
Alternately, just write it in:
<%=Html.ActionLink(
"<img src=\"asdfasdf\"/>",
new {controller="Hurr", action="Durr"}) %>
Two options I can think of, I'll give you the suggested one first:
One: Give the anchor an a unique ID and use CSS to style the link appropriately. This will also give you the ability to easily apply a rollover image using :hover.
<%=Html.ActionLink(" ", "action", "controller", null, new { #class="sample" })%>
<style type="text/css">
a.sample { background-image: url(http://sstatic.net/so/img/replies-off.png); }
a.sample:hover { background-image: url(http://sstatic.net/so/img/logo.png); }
</style>
Two: Create your own HtmlHelper that either doesn't escape the linkText parameter like ActionLink does or takes an image URL.
If you are on ASP.Net MVC 1.0 you can get the futures library and do this:
<%= Html.SubmitImage("controlName", "~/ImagePath/ImageName.jpg") %>
You just need to add this library: Microsoft.Web.Mvc download the dll here
This is also supposed to be part of ASP.Net MVC 2.0 at some point.
I have tested the ImageLink helpers and suggest that they should be made to return MvcHtmlString instead of string to prevent the Razor engine from encoding the actual image URLs.
So I changed all the signatures of the ImageLink functions to return 'MvcHtmlString' instead of plain 'string' and changed the last line of the last version of 'ImageLink' to:
return MvcHtmlString.Create( anchor.ToString(TagRenderMode.Normal)); //to add </a> as end tag

Resources