Hi I've got a class that downloads a file. It all works successfully when the file exists, but if the file doesn't exist then it will download an empty file. I'm trying to trap the error on the client but I can't seem to get it to catch it.
I'm running SmartClient Version: v11.0p_2016-05-31/PowerEdition Deployment (built 2016-05-31)
Looking into it further it seems as I'm using the API RPCManager.doCustomResponse() then callbacks will not be fired as the browser doesn't receive notification. Is there a way to download a file that allows the client to know if there's been an error or not?
Below are my client, server and ds.xml files.
Client -
private void gridRecordClicked() {
Criteria criteria = new Criteria();
criteria.addCriteria(TableConstants.CAATTPOINTER_FILENAME,
_attachments.getSelectedRecord()
.getAttributeAsString(TableConstants.CAATTPOINTER_FILENAME));
criteria.addCriteria(DSXmlConstants.DS_LOGIN_ATTACHMENTLOCATION, _attachmentLocation);
criteria.addCriteria(TableConstants.CAATTPOINTER_FILETYPE,
_attachments.getSelectedRecord()
.getAttributeAsString(TableConstants.CAATTPOINTER_FILETYPE));
DataSource ds = _attachments.getDataSource();
DSRequest dsRequest = new DSRequest();
dsRequest.setOperationId("download");
dsRequest.setDownloadResult(true);
dsRequest.setDownloadToNewWindow(false);
dsRequest.setWillHandleError(true);
_attachments.getDataSource().fetchData(criteria, new DSCallback() {
public void execute(DSResponse response, Object rawData, DSRequest request) {
if (response.getStatus() < 0) {
SC.say("Error - " + response.getDataAsString());
} else {
// Normal processing here
}
}
}, dsRequest);
Server -
public void downloadFile(DSRequest dsRequest, RPCManager rpc)
{
String fileSeparator = System.getProperty("file.separator");
String fileType = dsRequest.getCriteriaValue(TableConstants.CAATTPOINTER_FILETYPE).toString();
String fileName = dsRequest.getCriteriaValue(TableConstants.CAATTPOINTER_FILENAME).toString();
String fileLocation = dsRequest.getCriteriaValue(DSXmlConstants.DS_LOGIN_ATTACHMENTLOCATION).toString();
String fileToDownload = fileLocation + fileSeparator + fileName;
DSResponse dsResponse = new DSResponse();
try {
rpc.doCustomResponse();
HttpServletResponse response = rpc.getContext().response;
String filename;
String agent = ValidateUser.getUserAgent();
if (agent != null && agent.contains("MSIE"))
{
filename = URLEncoder.encode(fileName, "UTF8");
response.setContentType("application/x-download");
response.setHeader("Content-Disposition","attachment;filename=" + filename);
}
else if ( agent != null && agent.contains("Mozilla"))
{
response.setCharacterEncoding("UTF-8");
filename = MimeUtility.encodeText(fileName, "UTF8", "B");
response.setContentType("application/force-download");
response.addHeader("Content-Disposition", "attachment; filename="" + filename + """);
}
int size = (int)fileToDownload.length();
ServletOutputStream out = response.getOutputStream();
try {
FileInputStream fileInputStream = new FileInputStream(fileToDownload);
byte[] by = new byte[32768];
int index = fileInputStream.read(by, 0, 32768);
while (index != -1) {
out.write(by, 0, index);
index = fileInputStream.read(by, 0, 32768);
}
out.flush();
} catch(Exception e) {
try {
_log.error("downloadFile: Can't find file >" + e);
rpc.sendFailure(dsRequest, e.getMessage());
} catch(Exception er) {
_log.error("downloadFile: Can't open file >" + er);
}
}
dsResponse.setStatus(DSResponse.STATUS_SUCCESS);
rpc.send(dsRequest, dsResponse);
} catch (Exception e) {
try {
rpc.sendFailure(dsRequest, e.getMessage());
} catch(Exception er) {
_log.error("downloadFile: error >" + er);
}
}
}
}
ds.xml -
<DataSource
ID="decisionsAttachments"
serverType="sql"
useAnsiJoins="true"
tableName="STATUS"
>
<fields>
<field name ="WORKID" type="text" hidden="true" tableName="CAAT"/>
<field name ="ATTSEQ" hidden="true" type="integer" tableName="CAAT"/>
<field name ="DESCRIPTION" type="text" Title="Description" tableName="CAAT"/>
<field name ="FILENAME" title="Filename" type="text" tableName="CAAT"/>
<field name ="FILETYPE" title="Type" type="text" tableName="CAAT"/>
<field name ="ATTTYPE" type="text" title="Attachment Type" tableName="CAAT"/>
<field name ="TIMEATTACHED" title="Time Attached" type="datetime" tableName="CAAT"/>
<field name ="ForFM " type="text" hidden="true" tableName="CAAT"/>
<field name ="EVENTID" type="text" hidden="true" tableName="ST"/>
<field name ="WORKID" type="text" hidden="true" tableName="ST"/>
</fields>
<operationBindings>
<operationBinding operationType="fetch">
<selectClause>
$defaultSelectClause
</selectClause>
<whereClause>
$defaultWhereClause AND CAAT.WORKID = ST.EVENTID AND CAAT.ForFM = 1
</whereClause>
<tableClause>
STATUS ST, CAATTPOINTER CAAT
</tableClause>
<orderClause>
TIMEATTACHED
</orderClause>
</operationBinding>
<operationBinding operationType="fetch" operationId="download"
serverMethod="downloadFile">
<serverObject lookupStyle="new"
className="com.company.app.server.customDataSource.DecisionsAttachmentsDMI" />
</operationBinding>
</operationBindings>
</DataSource>
Thanks
Andrew
I'm running SmartClient Version: v11.0p_2016-05-31/PowerEdition Deployment (built 2016-05-31)
Looking into it further it seems as I'm using the API RPCManager.doCustomResponse() then callbacks will not be fired as the browser doesn't receive notification. Is there a way to download a file that allows the client to know if there's been an error or not?
Below are my client, server and ds.xml files.
Client -
private void gridRecordClicked() {
Criteria criteria = new Criteria();
criteria.addCriteria(TableConstants.CAATTPOINTER_FILENAME,
_attachments.getSelectedRecord()
.getAttributeAsString(TableConstants.CAATTPOINTER_FILENAME));
criteria.addCriteria(DSXmlConstants.DS_LOGIN_ATTACHMENTLOCATION, _attachmentLocation);
criteria.addCriteria(TableConstants.CAATTPOINTER_FILETYPE,
_attachments.getSelectedRecord()
.getAttributeAsString(TableConstants.CAATTPOINTER_FILETYPE));
DataSource ds = _attachments.getDataSource();
DSRequest dsRequest = new DSRequest();
dsRequest.setOperationId("download");
dsRequest.setDownloadResult(true);
dsRequest.setDownloadToNewWindow(false);
dsRequest.setWillHandleError(true);
_attachments.getDataSource().fetchData(criteria, new DSCallback() {
public void execute(DSResponse response, Object rawData, DSRequest request) {
if (response.getStatus() < 0) {
SC.say("Error - " + response.getDataAsString());
} else {
// Normal processing here
}
}
}, dsRequest);
Server -
public void downloadFile(DSRequest dsRequest, RPCManager rpc)
{
String fileSeparator = System.getProperty("file.separator");
String fileType = dsRequest.getCriteriaValue(TableConstants.CAATTPOINTER_FILETYPE).toString();
String fileName = dsRequest.getCriteriaValue(TableConstants.CAATTPOINTER_FILENAME).toString();
String fileLocation = dsRequest.getCriteriaValue(DSXmlConstants.DS_LOGIN_ATTACHMENTLOCATION).toString();
String fileToDownload = fileLocation + fileSeparator + fileName;
DSResponse dsResponse = new DSResponse();
try {
rpc.doCustomResponse();
HttpServletResponse response = rpc.getContext().response;
String filename;
String agent = ValidateUser.getUserAgent();
if (agent != null && agent.contains("MSIE"))
{
filename = URLEncoder.encode(fileName, "UTF8");
response.setContentType("application/x-download");
response.setHeader("Content-Disposition","attachment;filename=" + filename);
}
else if ( agent != null && agent.contains("Mozilla"))
{
response.setCharacterEncoding("UTF-8");
filename = MimeUtility.encodeText(fileName, "UTF8", "B");
response.setContentType("application/force-download");
response.addHeader("Content-Disposition", "attachment; filename="" + filename + """);
}
int size = (int)fileToDownload.length();
ServletOutputStream out = response.getOutputStream();
try {
FileInputStream fileInputStream = new FileInputStream(fileToDownload);
byte[] by = new byte[32768];
int index = fileInputStream.read(by, 0, 32768);
while (index != -1) {
out.write(by, 0, index);
index = fileInputStream.read(by, 0, 32768);
}
out.flush();
} catch(Exception e) {
try {
_log.error("downloadFile: Can't find file >" + e);
rpc.sendFailure(dsRequest, e.getMessage());
} catch(Exception er) {
_log.error("downloadFile: Can't open file >" + er);
}
}
dsResponse.setStatus(DSResponse.STATUS_SUCCESS);
rpc.send(dsRequest, dsResponse);
} catch (Exception e) {
try {
rpc.sendFailure(dsRequest, e.getMessage());
} catch(Exception er) {
_log.error("downloadFile: error >" + er);
}
}
}
}
ds.xml -
<DataSource
ID="decisionsAttachments"
serverType="sql"
useAnsiJoins="true"
tableName="STATUS"
>
<fields>
<field name ="WORKID" type="text" hidden="true" tableName="CAAT"/>
<field name ="ATTSEQ" hidden="true" type="integer" tableName="CAAT"/>
<field name ="DESCRIPTION" type="text" Title="Description" tableName="CAAT"/>
<field name ="FILENAME" title="Filename" type="text" tableName="CAAT"/>
<field name ="FILETYPE" title="Type" type="text" tableName="CAAT"/>
<field name ="ATTTYPE" type="text" title="Attachment Type" tableName="CAAT"/>
<field name ="TIMEATTACHED" title="Time Attached" type="datetime" tableName="CAAT"/>
<field name ="ForFM " type="text" hidden="true" tableName="CAAT"/>
<field name ="EVENTID" type="text" hidden="true" tableName="ST"/>
<field name ="WORKID" type="text" hidden="true" tableName="ST"/>
</fields>
<operationBindings>
<operationBinding operationType="fetch">
<selectClause>
$defaultSelectClause
</selectClause>
<whereClause>
$defaultWhereClause AND CAAT.WORKID = ST.EVENTID AND CAAT.ForFM = 1
</whereClause>
<tableClause>
STATUS ST, CAATTPOINTER CAAT
</tableClause>
<orderClause>
TIMEATTACHED
</orderClause>
</operationBinding>
<operationBinding operationType="fetch" operationId="download"
serverMethod="downloadFile">
<serverObject lookupStyle="new"
className="com.company.app.server.customDataSource.DecisionsAttachmentsDMI" />
</operationBinding>
</operationBindings>
</DataSource>
Thanks
Andrew
Comment