Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Catch errors on client when downloading a file.

    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
    Last edited by andrew.toon; 2 Aug 2016, 06:00.

    #2
    Once the browser has been set up to expect a file, there is no way to do normal error handling; the only thing you could do is send back a valid file where the contents of the file have the error message (for example, a stock image that just has the text "image not available").

    Normally, if you are using SmartClient's built-in support for binary fields and you have loaded the records that contain the binary field client-side, you can simply do a null check on the filename field to see if there is no file stored with the record.

    If this is not your situation, an alternate approach is to simply do a non-download request first to check whether there is a file present, then continue with the download request if that's successful.

    Comment

    Working...
    X