How to define the annotation for action with image result? - java

I was ok to define it in struts.xml config.
<action name="getImage" class="my.action.GetImageAction">
<result name="success" type="stream">
<param name="contentType">image/jpeg</param>
<param name="inputName">imageStream</param>
<param name="bufferSize">1024</param>
</result>
</action>
And I am now trying to define it by annotation on the class with namesapce, result path, and I have no idea how to do it. Please help :)
I have tried
#Namespace("/my/namespace")
#ResultPath("/")
#Result(name = "success", type = "imageResult")
public class GetImageAction extends ActionSupport {
.....
#Override
#Action("/getImage")
public String execute() throws Exception {
.....
And I got an error
HTTP Status 404 - No result defined for action

As the error says the results have to be defined at the Action.
The definition would look like this
#Action(value = "getImage", results = { #Result(
name = "success",
type = "stream",
params = {"contentType", "application/pdf" }) })
In the example you see the type too and how to define the contentType.
And the stream will be returned by the "getFileInputStream"-method:
public InputStream getFileInputStream() {
return fileInputStream;
}
the "getContentDisposition"-Method has to be available in the Action-class
public String getContentDisposition() {
return "attachment; filename=" + getFilename() + ".pdf";
}

Related

Struts 2 Download File is 0 bytes

I'm having an issue downloading a file using Struts2. I've done a pile of research and found a bunch of similar questions, but none of the answers have helped me out.
Here is what I currently have
JSP
<s:url id="fileDownload" namespace="/jsp" action="download"></s:url>
Download file - <s:a href="%{fileDownload}">MyFile.pdf</s:a>
Action
private InputStream inputStream;
private String fileName;
public String execute() throws Exception {
File fileToDownload = new File("C:My Documents/MyFile.pdf");
fileName = fileToDownload.getName();
inputStream = new FileInputStream(fileToDownload);
return SUCCESS;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public InputStream getInputStream() {
return inputStream;
}
Struts.xml
<action name="download" class="com.my.path.to.action.class">
<result name="success" type="stream">
<param name="contentDisposition">attachment;filename=${fileName}</param>
<param name="contentType">application/pdf</param>
<param name="inputName">inputStream</param>
<param name="bufferSize">4096</param>
</result>
</action>
When I click on the link, it will download a file that's named correctly, but it has no data in it. If anyone has any ideas as to what I'm doing wrong, I would love a suggestion as I'm sure it's just something dumb.
I found my answer. You must define the content length in struts. To do this I did the following:
Struts.xml
<param name="contentLength">${contentLength}</param>
Action
private long contentLength;
public long getContentLength() {
return contentLength;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
in execute()
contentLength = fileToDownload.length();

Adding #RequiredStringValidator causing result not to be found

I have an Apache Struts web application. All of my actions are defined in my struts.xml file. I am trying to add support to my action classes to have validation annotations added to my project.
To try and get this working I added the struts2-convention-plugin.jar and also commons-lang.jar.
I then added an annotation on top of my action method.
jsp
<s:form id="tradingOutageFrm" action="addTradingOutageDo.action"
validate="true" theme="simple">
struts.xml
<action name="addTradingOutageDo" class="com.myproject.action.TradingOutageAction"
method="addDo">
<result name="success" type="tiles">page.tradingOutageAdd</result>
</action>
My action class
public class TradingOutageAction extends ActionSupport {
#RequiredStringValidator(type = ValidatorType.SIMPLE,
fieldName = "storeNo",
message = "Please enter a store.")
public String addDo() throws Exception {
try{
Map<String, Object> session = ActionContext.getContext().getSession();
String userId = session.get("userid").toString();
tradingOutage.setStoreNo(storeNo);
tradingOutage.setStoreServer(storeServer);
tradingOutageDAO.insertOutage(userId, startDate, startTime,
endDate, endTime, tradingOutage);
addActionMessage(MessageConstants.RECORD_INSERTED);
}catch(Exception e){
addActionError(MessageConstants.UPDATE_FAILED + " " + e.getMessage());
}
return SUCCESS;
}
Without the annotation everything works fine but with the annotation I get a
No result defined for action com.myproject.action.TradingOutageAction and result input.
Can anyone help me with what might be wrong here.

Declatring Struts 2 actions as annotation

I found a code for a class in the internet which using Spring and Struts2.
I only know how to declare actions in the XML file, so in that class I found this :
#ParentPackage(value = "showcase")
public class Languages extends ActionSupport {
//deleted code
#Action(value = "/languages", results = {
#Result(type = "json", name = "success", params = {
"root", "languages"
})})
public String execute() throws Exception {
if (term != null && term.length() > 1) {
ArrayList<String> tmp = new ArrayList<String>();
for (String staticLanguage : staticLanguages) {
if (StringUtils.contains(staticLanguage.toLowerCase(), term.toLowerCase())) {
tmp.add(staticLanguage);
}
}
languages = tmp.toArray(new String[tmp.size()]);
}
return SUCCESS;
}
//deleted code
So what is the equivalent for this using the XML file for Struts2?
It's not equivalent, but is mapped to the same URL.
<package name="mypackage" namespace="/" extends="showcase">
<action name="languages" class=com.struts.Languages">
<result type="json">
<param name="root">languages</param>
</result>
</action>
</package>

Struts 2 - HTTP Status 500 - Can not find a java.io.InputStream with the name

This is similar problem to:
Question A
Question B
yet I can't apply solutions in my case. Maybe someone can spot error in my code.
I want to generate Excel file in my Struts2 app and let user download it, but I get an error:
"HTTP Status 500 - Can not find a java.io.InputStream with the name"
With debugger I have confirmed that proper input stream with file content is created and method returns 'Success', so it seems that Struts is not picking up this stream.
In struts.xml I have:
<action name="exportReferences" class="manageRefAction" method="exportReferences">
<result name="success" type="stream">
<param name="contentType">application/vnd.ms-excel;charset=utf-8</param>
<param name="contentDisposition">contentDisposition</param>
<param name="inputName">excelStream</param>
<param name="bufferSize">1024</param>
</result>
(...)
</action>
Then in ManageRefAction class I have:
private InputStream excelStream;
public InputStream getExcelStream() {
return this.excelStream;
}
public String exportReferences() {
List<ReferenceData> referenceXLSList = null;
String exportFilename = null;
String filename = "";
String retrunStr = process();
Map session = (Map) ActionContext.getContext().get("session");
if (retrunStr.equalsIgnoreCase(ActionSupport.LOGIN)) {
setLog("2");
return LOGIN;
} else {
//Export only data with user's locale
ArrayList userLocale = (ArrayList) session.get("userLocale");
List<ArrayList> list = Arrays.asList(userLocale);
try {
referenceXLSList = referenceDataService.fetchReferenceDataXls();
// Data filtering
for (Iterator<ReferenceData> iterator = referenceXLSList.iterator(); iterator.hasNext(); ) {
ReferenceData ref = iterator.next();
String l = ref.getLocal().toLowerCase();
if (!userLocale.contains(l)) {
iterator.remove();
}
}
if (referenceXLSList.isEmpty()) {
return INPUT;
}
ServletContext servletContext = ServletActionContext.getServletContext();
String exportFolderPath = servletContext.getRealPath("/files" + "/xls");
File folder = new File(exportFolderPath);
// Creation of the folder if it is not existing
if (!folder.exists())
folder.mkdirs();
exportFilename = PLConstants.REF_SHEET_NAME + PLConstants.XLS_FILE_EXTENSION;
filename = exportFolderPath + "/" + exportFilename;
File file = new File(filename);
file.createNewFile();
ExcelWriter writer = new ExcelWriter();
Workbook wb = writer.writeRefData(filename, exportFilename, referenceXLSList);
setContentDisposition("attachment; filename=" + exportFilename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
wb.write(baos);
this.excelStream = new ByteArrayInputStream(baos.toByteArray());
return SUCCESS;
} catch (Throwable e) {
e.printStackTrace();
logger.info("Exception while exporting partner references", e);
return INPUT;
}
}
}
Try this, contentDisposition is String value not getting in struts.xml.
so,it's throwing an exception.use this syntax ${contentDisposition} in param
<action name="exportReferences" class="manageRefAction" method="exportReferences">
<result name="success" type="stream">
<param name="contentType">application/vnd.ms-excel;charset=utf-8</param>
<param name="contentDisposition">${contentDisposition}</param>
<param name="inputName">excelStream</param>
<param name="bufferSize">1024</param>
</result>
(...)
</action>

using struts 2 action for a simple ajax request

I am trying to make a simple request using AJAX . But the whole thing is not working. Below is the code I wrote
jsp/javascript :
$("#my_"+rowNum).load("getdata.action?id="+123,function(data) {
alert("i am inside "+data);
});
Struts Action :
public class MyAction extends BaseAction {
public String execute() {
try {
inputStream = new ByteArrayInputStream("ABC 123 556".getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e) {
//handle exception
}
return SUCCESS;
}
}​
struts.xml :
<action name="getdata" class="com.amtd.advisoradmin.action.MyAction">
<result type="stream">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
I feel the configuration is correct, but I don't get the alert I printed in my jsp after the control returns from the Action class. Am I missing something ?
PS : ABC 123 556 is the data I need to get in the alerts.
I would suggest you to have a private variable for inputStream type InputStream and public getter and setter for it in your Action class, which is missing.
Thanks

Categories