質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Framework

Frameworkは、アプリケーションソフトを開発する際に、一般的な機能をより簡単に、より早く完了させる事を目的とした、ソフトウェアやライブラリのセットを指します。開発にフレームワークを使用する事で、追加で必要となる機能だけを開発するだけで済む為、開発効率の向上が見込めます。

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Play Framework

Play Frameworkは、現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Q&A

1回答

2129閲覧

Scala(Play Framework)でJSONパラメータをつけたPOSTリクエストを送る

Nawta

総合スコア4

Framework

Frameworkは、アプリケーションソフトを開発する際に、一般的な機能をより簡単に、より早く完了させる事を目的とした、ソフトウェアやライブラリのセットを指します。開発にフレームワークを使用する事で、追加で必要となる機能だけを開発するだけで済む為、開発効率の向上が見込めます。

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Play Framework

Play Frameworkは、現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

0グッド

0クリップ

投稿2020/07/14 07:19

https://hexx.github.io/scala_text/introduction-of-web-application-4th-day.html

このサイトを真似して、ScalaでWebアプリケーションを試しに動かそうとしているのですが、GETリクエストを送って表示まではできるもののPOSTリクエストからDBへの登録がどうもできません。
現在送っているリクエストは以下のようなものです。何個か試しましたがどうもうまく行きません。エラーが表示されないのと、ログの残し方も試してみてうまくいかなかった(理解が足りてなくてうまく実装できてないかも?)ので途方に暮れています。どこかおかしな点はありますでしょうか。

curl -X POST -H "Content-Type: application/json" -d '{"post": "have a good night!"}' localhost:9000/posts curl -X POST -d 'post:"have a good night!"' localhost:9000/posts  curl -X POST -d '{post:"have a good night!"}' localhost:9000/posts  curl -X POST -d '{post:["have a good night!"]}' localhost:9000/posts  curl -d '{post:["have a good night!"]}' localhost:9000/posts  curl -d '{post:["have a good night!"]}' localhost:9000/posts  curl -d '{post:["have a good night!"]}' localhost:9000/posts

上記のようなリクエストを送ると、

routes

1GET /posts controllers.PostsController.get() 2POST /posts controllers.PostsController.post()

から

PostsController

1package controllers 2 3import java.time.OffsetDateTime 4import javax.inject.Inject 5import play.api.mvc.Action 6import play.api.mvc.Controller 7import play.api.data.Form 8import play.api.data.Forms._ 9import play.api.i18n.I18nSupport 10import play.api.i18n.Messages 11import play.api.i18n.MessagesApi 12import play.api.libs.json.Json 13 14//case class PostRequest(body: String) 15//これを定義していると、エラーが出る。多分、postの中で引数として用いているから二重宣言になる? 16 17class PostsController @Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport { 18 19 private[this] val form = Form( 20 mapping( 21 "post" -> text(minLength = 1, maxLength = 10) 22 )(PostRequest.apply)(PostRequest.unapply)) 23 24 def get = Action { implicit request => 25 Ok( 26 Json.toJson( 27 Response(Meta(200), Some(Json.obj("posts" -> Json.toJson(PostRepository.findAll)))))) 28 } 29 30 def post = Action { implicit request => 31 form.bindFromRequest.fold( 32 error => { 33 val errorMessage = Messages(error.errors("post")(0).message) 34 BadRequest(Json.toJson(Response(Meta(400, Some(errorMessage))))) 35 }, 36 postRequest => { 37 val post = Post(postRequest.body, OffsetDateTime.now) 38 PostRepository.add(post) 39 Ok(Json.toJson(Response(Meta(200)))) 40 } 41 ) 42 } 43} 44

のコントローラーに飛び、postメソッドを通じてDBにデータが追加されるようにします。

PostRepositoryの中身は以下のようなものです。

PostRepository

1package controllers 2 3import scalikejdbc._ 4import scalikejdbc.jsr310._ 5 6object PostRepository { 7 8 def findAll: Seq[Post] = DB readOnly { implicit session => 9 sql"SELECT id, body, date FROM posts" 10 .map { rs => 11 Post(rs.long("id"), rs.string("body"), rs.offsetDateTime("date")) 12 } 13 .list() 14 .apply() 15 } 16 17 def add(post: Post): Unit = DB localTx { implicit session => 18 sql"INSERT INTO posts (body, date) VALUES (${post.body}, ${post.date})".update().apply() 19 } 20} 21

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

POSTしたリクエストのボディが期待したものと違うのではないでしょうか。
(実装自体は問題ないとおもわれます。)

curl -X POST -v http://localhost:9000/posts \ -H "content-type: application/json" \ -d '{"post": "anything"}'

もしくは

curl -X POST -v http://localhost:9000/posts \ -H "content-type: application/x-www-form-urlencoded" \ -d 'post=anything'

とすれば 200 で登録可能となりそうです。
(リクエスト例は post の文字列をダブルクォートで囲っておらず、
かつ contents-type 指定がないので curl に json と認識されてないと思われます。)

PostController の以下の部分が key: post の value を受け取るようになっているので、
その組み合わせで解釈できるフォーマットでリクエストを送るとよさそうです。

scala

1 private[this] val form = Form( 2 mapping( 3 "post" -> text(minLength = 1, maxLength = 10) 4 )(PostRequest.apply)(PostRequest.unapply))

捕捉:

これを定義していると、エラーが出る。

これはたぶん以前のサンプルコードの TextboardController 内でも
同じクラス PostRequest を定義しているからではないでしょうか
form.bindFromRequest.fold の中は match 式で case class をマッチさせているので、
どこかで事前に定義が必要になります。

投稿2020/08/08 12:08

kiino

総合スコア539

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問