2016-07-18 17 views
2

jsonをリクエストしてpdfファイルに応答するSpringコントローラを作成しました。CycleJSのPOSTリクエストからファイルを取得する方法

public ResponseEntity<byte[]> generateResp(...) 
    byte[] gMapRep = Files.readAllBytes(file.toPath()); 

      HttpHeaders httpHeaders = new HttpHeaders(); 
      httpHeaders.setContentType(MediaType.parseMediaType("application/pdf")); 

      httpHeaders.setContentDispositionFormData("content-disposition", "filename=report.pdf"); 
      httpHeaders.setCacheControl("must-relative, post-check=0, pre-check=0"); 

     return ResponseEntity 
       .ok() 
       .headers(httpHeaders) 
       .body(gMapRep); 

Postmanでうまく動作します。私はいくつかのパラメータを送る必要があるので、POSTメソッドではneseccaryです。しかし、どうすればCycleJSのpdfファイルをレスポンスから入手/ダウンロードできますか?私は、フロントエンドにしようとしている:

ここ
const buttonRequest$ = actions.buttonClick$ 
     .withLatestFrom(sources.arcgisDriver.onMapLoaded, 
      (ev, _)=> { 
       return { 
        url: myURL, 
        method: 'POST', 
        type: 'application/json', 
        send: data 
       } 
      }); 

    sources.HTTP 
     .filter(response => { 
      return !response.error && response.request.url.includes(myURL) 
     }) 
     .subscribe(resp => window.open("data:application/pdf;base64, " + resp.text, '', 'height=650,width=840')); 
+0

私は応答を取得し、window.open()で応答を購読しようとしましたが、動作しません。また、私はデータを追加しようとしました:application/pdf、+ response.text、それはpdfファイルを開きますが、ここではpdfファイルの解析にいくつかの問題があります。 –

+1

フロントエンドコードを投稿できますか?その説明からちょうど間違っていることを言うことは難しいです – paulpdaniels

+0

[* cycle/http *](https://github.com/cyclejs/cyclejs/tree/master/http)は[SuperAgent](https: /visionmedia.github.io/superagent/)はXHR(Ajax)です。 XHRを使用する必要がありますか?または、シンプルなHTTP POSTでシリアル化されたJSONデータを取得できますか? – bloodyKnuckles

答えて

3

Cycle.jsは(嘲笑)APIから値を取ってRxJS例を使用してクライアント側だし、ボタンクリック時に、サーバスクリプトにフォームを送信し、非表示のフォームを埋めますそれは、新しいブラウザウィンドウまたはタブに向けられているPDF文書を返します。

import Rx from 'rx'; 
import Cycle from '@cycle/core'; 
import {div, form, input, button, makeDOMDriver} from '@cycle/dom'; 

function makeFormDriver (formid, elemid) { 
    return function (post$) { 
    post$.subscribeOnNext(function (post) { 
     document.querySelector(elemid).value = post; 
     document.querySelector(formid).submit(); 
    }); 
    } 
} 

function main({DOM}) { 
    const buttonClick$ = DOM.select('button#pdf').events('click'); 
    const api$ = Rx.Observable.of('test.pdf'); // mocked API 
    const post$ = buttonClick$.withLatestFrom(api$, (bclick, file) => file); 

    const vdom$ = Rx.Observable.of(
    div([ 
     form('#pdfform', { 
     method: 'post', action: 'http://localhost:3000/file', 
     target: '_blank', style: 'display: none;' 
     }, [input(#filename', {type: 'hidden', name: 'filename'})]), 
     button('#pdf', 'PDF') 
    ]) 
); 

    return { 
    DOM: vdom$, 
    FORM: post$ 
    }; 
} 

Cycle.run(main, { 
    DOM: CycleDOM.makeDOMDriver('#app'), 
    FORM: makeFormDriver('#pdfform', '#filename') 
}); 

をそしてここクライアント側ですxstream例を使用して:へ

import xs from 'xstream'; 
import Cycle from '@cycle/xstream-run'; 
import express from 'express'; 
import bodyParser from 'body-parser'; 

let server = express(); 
server.use(bodyParser.urlencoded({ extended: false })) 

function makeDownloadDriver (effect) { 
    return function (postfile$) { 
    let file$ = postfile$.map(body => body.filename) 
    file$.addListener({ 
     next: effect, 
     error: function() {}, 
     complete: function() {} 
    }) 
    } 
} 

server.use(function (req, res) { 

    let postfile$ = xs.of(req) 
    .filter(req => 'POST' === req.method && '/file' === req.url) 
    .map(req => req.body); 

    function main (sources) { 
    return { 
     postfile: postfile$ 
    }; 
    } 

    Cycle.run(main, { 
    postfile: makeDownloadDriver(file => res.sendFile(file, {root: __dirname})), 
    }); 

}); 

server.listen(3000); 


そして、ここでのキックのため

import xs from 'xstream'; 
import Cycle from '@cycle/xstream-run'; 
import {div, form, input, button, makeDOMDriver} from '@cycle/dom'; 

function makeFormDriver (formId, elemId) { 
    const form = document.querySelector(formId); 
    const elem = document.querySelector(elemId); 
    return function (post$) { 
    post$.addListener({ 
     next: function (post) { 
     elem.value = post;  // populate form data 
     form.submit();   // submit form 
     }, 
     error: function() {}, 
     complete: function() {} 
    }); 
    } 
} 

function main(sources) { 
    const buttonclick$ = sources.DOM.select('#pdfbutton').events('click'); 
    const api$ = xs.of('test.pdf');       // mocked API 
    const post$ = buttonclick$.map(bclick => api$).flatten(); // ~ withLatestFrom 

    let vtree$ = xs.of(
    div('.pdf', [ 
     form('#pdfform', {attrs: { 
     method: 'post', action: '/file', 
     target: '_blank', style: 'display: none;'  // new tab and hide form 
     }}, [ 
     input('#filename', {attrs: {name: 'filename', type: 'input'}}), 
     ]), 
     button('#pdfbutton', 'view pdf') 
    ]) 
) 

    return { 
    DOM: vtree$, 
    FORM: post$ 
    }; 
} 

Cycle.run(main, { 
    DOM: makeDOMDriver('.app-container'), 
    FORM: makeFormDriver('#pdfform', '#filename') 
}); 
は、指定されたドキュメントをExpressを使用してPOST'edデータを受信し、返すサーバー側Cycle.jsxstream例ですページルータチェックアウトcycle-isomorphic-file-downloadと一緒にこれらの作業を一緒に参照してください。

関連する問題