私はラケットWebサーバ用のサーブレットを作って、サイトに写真をアップロードし、既にアップロードされたファイルを同じページ。私はPostgreSQLデータベースの中や外に直接写真をディスクやメモリ上の一時ファイルに保存するのではなく、ストリーミングしたいと思います。出来ますか?もしそうなら、それを行う最良の方法は何ですか?ステートレスなサーブレットでこれを行うことはできますか?どんな助けでも大歓迎です!Racket ServerとPostgreSQL - メモリやディスクに保存しないでBLOBをアップロード/ダウンロードする
3
A
答えて
4
する必要があります。私はPLaneTからdb
packageを(私はそれを書いたので)お勧めします。あなたはthe docsをオンラインで読むことができます。
PostgreSQLのテーブルには、画像コンテンツのフィールドがbytea
である必要があります。ラケット側ではバイト文字列として表されます。
サーブレットでは、イメージの内容がresponse/full
の構造体を返しているはずです。あなたはリターンコード、MIMEタイプなどを自分で扱わなければなりません。 (ドキュメントの例を参照してください)
1
科学の名前で、私は自分の質問に答えの半分を掲示しています。このページには、すでにデータベースにある画像が表示されます。アップロードページは開いたままの質問です。
Ryan Culpepperは、ここに掲載されている内容を超えた私的な対応で私を助けました。私は彼の助けを彼に感謝します。黒い魔法のように見えるすべてのものが彼から来て、すべての不器用なものは私のものです。コードを改善する方法に関するすべての提案に感謝します。
#lang racket
#|
================================================================================================================
We are assuming that the PostgreSQL database we are connecting to
has a table "person" with columns
"id", "firstname", "lastname" and "portrait".
The "portrait" column contains the OID of a BLOB
that stores the image file we want to display.
Suppose further that the table "person" has a legitimate entry with
id=22, firstname="John", lastname="Doe"
Then the page
http://127.0.0.1/page/22
should display greetings "Hello, John Doe!"
and show the portrait of the person below the greeting.
The portrait itself should be at
http://127.0.0.1/portrait/22.jpg
The program should be run via Racket -t "<filename>"
after defining the environment variables
"DB_USER", "DB_NAME", "DB_PORT", "DB_PASSWORD".
================================================================================================================
|#
(require
web-server/servlet
web-server/servlet-env
web-server/dispatch
web-server/stuffers/hmac-sha1
web-server/http
web-server/http/response-structs
(planet ryanc/db:1:4)
(planet ryanc/db:1:4/util/connect)
net/base64)
;---------------------------------------------------------------------------------------------------------------
; response
;---------------------------------------------------------------------------------------------------------------
(define (start given-request)
(site-dispatch given-request))
(define-values (site-dispatch given-request)
(dispatch-rules
[("page" (integer-arg)) show-page]
[("portrait" (string-arg)) show-portrait]))
(define (show-page given-request given-person-id)
(let* ([db-person_firstname_lastname
(query-maybe-row my-connection
"SELECT firstname, lastname FROM person WHERE id = $1"
given-person-id)]
[my-firstname (vector-ref db-person_firstname_lastname 0)]
[my-lastname (vector-ref db-person_firstname_lastname 1)])
(response/xexpr
`(html ([xmlns "http://www.w3.org/1999/xhtml"])
(head
(title "Page with a portrait"))
(body
(div ([id "greetings"])
,(string-append
"Hello, " my-firstname " " my-lastname "! "))
(img ( [src ,(string-append "/portrait/"
(number->string given-person-id) ".jpg")])))))))
(define (show-portrait given-request given-portrait-file)
(let* ([my-user-id (car (regexp-match #rx"^([0-9]+)"
given-portrait-file))]
[my-portrait-oid (query-value my-connection
"SELECT portrait FROM person WHERE id = $1"
(string->number my-user-id))]
[STREAMOUT_CHUNK_SIZE 1000]
[INV_READ #x00040000])
(response
200 ; code
#"Okay" ; message
(current-seconds) ; seconds
#"image/jpeg" ; mime type
empty ; headers
(lambda (given-output-stream) ; body generator
(start-transaction my-connection)
(define object-descriptor
(query-value my-connection
"SELECT LO_OPEN($1, $2)" my-portrait-oid INV_READ))
(define (stream-next-chunk)
(begin
(define my-next-chunk
(query-value my-connection
"SELECT LOREAD($1, $2)"
object-descriptor STREAMOUT_CHUNK_SIZE))
(if (> (bytes-length my-next-chunk) 0)
(begin
(write-bytes my-next-chunk given-output-stream)
(stream-next-chunk)
#t)
#f)))
(stream-next-chunk)
(commit-transaction my-connection)))))
;---------------------------------------------------------------------------------------------------------------
; database connection
;---------------------------------------------------------------------------------------------------------------
(define my-connection
(virtual-connection
(connection-pool
(lambda()
(eprintf "(Re)establishing database connection...\n")
(postgresql-connect
#:user (getenv "DB_USER")
#:database (getenv "DB_NAME")
#:port (string->number (getenv "DB_PORT"))
#:socket #f
#:password (getenv "DB_PASSWORD")
#:allow-cleartext-password? #f
#:ssl 'optional ; other choices: 'yes 'no
)))))
;---------------------------------------------------------------------------------------------------------------
; servlet parameters
;---------------------------------------------------------------------------------------------------------------
(serve/servlet start
#:command-line? #t ; #t to use serve/servlet in a start up script for a Web application, and don't want a browser opened or the DrRacket banner printed
#:connection-close? #f ; #t to close every connection after one request. (Otherwise, the client decides based on what HTTP version it uses.)
#:launch-browser? #f
#:quit? #f ; #t makes the URL "/quit" end the server
#:banner? #t ; #t to print an informative banner
#:listen-ip #f ; give an IP to accept connections from external machines
#:port 80 ; 443 is the default for SSL, 80 - for open connections
#:servlet-regexp #rx"" ; #rx"" captures top-level requests
#:stateless? #t
#:server-root-path ; where the server files are rooted, default=(the distribution root)
(build-path ".")
#:ssl? #f
#:log-file (build-path "server.log"))
関連する問題
- 1. blobをディスクにディスクに保存
- 2. blobからディスクにblobフィールドを保存する
- 3. Androidパーセル、メモリまたはディスクに保存されていますか?ディスクに保存する方法
- 4. ディスクへのメモリ内H2データベースの保存
- 5. ディスクにメモリ内のデータベースを保存する
- 6. カールのクッキーをディスクではなくメモリに保存する方法
- 7. HTML5ファイルをディスクに保存しないでアップロードする
- 8. DoctrineでファイルをBLOBとして保存
- 9. ディスクに書き込むまで、Python /ファイルデータをメモリに保存するには?
- 10. ディスク上のリストを増やしながら動的オブジェクトを保存する
- 11. Django - PostGresqlデータベースに保存しない
- 12. 大きなエクセルファイルをディスクに保存していない
- 13. blobをjavascriptでファイルに保存する
- 14. ディスクからsqlite3データベースを取得し、メモリにロードしてディスクに保存しますか?
- 15. 不適切なファイル名でasp.net(c#)のSQL ServerのBLOBを保存する
- 16. ディスクに物理ファイルを保存するのではなく、メモリにFileStreamを作成します。
- 17. ggplot2オブジェクトをggplotlyとして保存し、Linuxのディスクに保存します
- 18. ディスクに保存しないでzipファイルをダウンロードしてアップロードする方法
- 19. 可変データをディスクに保存する
- 20. ディスクにXMLファイルを保存する
- 21. イメージをディスクに保存する
- 22. WAVファイルをディスクに保存する
- 23. iisセッションデータをディスクに保存する
- 24. Yii2ファイルをOracle BLOBに保存する
- 25. BlobをIonicに保存する方法
- 26. blobファイルをmysqlデータベースに保存する
- 27. FlowDocumentをXPSドキュメントとしてディスクに保存する
- 28. m3u8ビデオを迅速なココアでディスクに保存する
- 29. SQLiteのデータをBLOBとして保存していますか?
- 30. MongoDBノードアプリケーションでBLOBとしてPDFを保存する方法