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

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

ただいまの
回答率

89.55%

MultipartFileで取得したファイルをDBに追加したい java postgres

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 4,579

Yoshi--

score 56

未解決のため、少し編集して
リマインドさせていただきます。

教えてください

Profile.java

//profileテーブルとマッピングさせる

package com.example.konkatsu.domain;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor    //デフォルトコンストラクタも必要な場合
@AllArgsConstructor   //すべてのフィールドを引数に持つコンストラクタを自動生成
@Entity    //エンティティ(一単位として扱われるデータのまとまり)であることを示す。指定したクラス名がテーブルとマッピングされる
@Table(name = "profile")  //接続するテーブルを指定
public class Profile {
    @Column(name = "user_id")
    @Id   //主キー
    //@GeneratedValue(strategy = GenerationType.IDENTITY)    //自動採番される
    private Integer id;
    private String name;
    private Integer genderId;
    private Date birthday;
    private Integer height;
    private Integer occupationId;
    private Integer income;
    private String text;
    private byte[] image;
    @ManyToOne(fetch = FetchType.LAZY)             //@ManyToOneで多対1の関係にする
    @JoinColumn(nullable = true, name = "user_id", insertable=false, updatable=false)   //外部キーのカラム名の指定
    private User user;

}

ProfileForm.java

//このクラスにプロフィール登録画面の<form>から送るパラメータをマッピングさせる


package com.example.konkatsu.web;

import java.io.Serializable;
import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;

import org.springframework.web.multipart.MultipartFile;

import lombok.Data;

@Data
public class ProfileForm implements Serializable{


    @Column(name = "user_id")
    @Id   //主キー
    //@GeneratedValue(strategy = GenerationType.IDENTITY)    //自動採番される
    private Integer id;


    //Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    //Integer userId = ((User)principal).getUserId();

    @NotNull
    private String name;
    @NotNull
    Integer genderId;
    @NotNull
    private Date birthday;
    @NotNull
    private Integer height;
    @NotNull
    private Integer occupationId;
    @NotNull
    private Integer income;
    @NotNull
    private String text;
    @NotNull
    private MultipartFile file;
    //ファイルアップロードをするにはMultipartFile
    //private byte[] image;



}

controller

//th:action="@{/createProfile}" postからの処理
    @PostMapping(path = "createProfile")   //URLが  konkatsu/createProfile となる
    public String create(@Validated ProfileForm form, BindingResult bindingResult, Model model,
            @AuthenticationPrincipal LoginUserDetails userDetails) throws IOException{   //@AuthenticationPrincipalをつけることでログイン中の[LoginDetails]オブジェクトを取得できる


        System.out.println(form.getId());
        System.out.println(form.getName());
        System.out.println(form.getGenderId());
        System.out.println(form.getBirthday());
        System.out.println(form.getHeight());
        System.out.println(form.getOccupationId());
        System.out.println(form.getIncome());
        System.out.println(form.getText());
        System.out.println(form.getFile());




        if (bindingResult.hasErrors()){    //入力チェックの結果を確認し、エラーがある場合は一覧画面表示に戻る
            System.out.println("エラー");
            return list(model);
        }


????????

    MultipartFile uploaded = form.getFile();
    byte[] image = uploaded.getBytes();   //アップロードファイルをbyte配列で取得




???????


        Profile profile = new Profile();
        BeanUtils.copyProperties(form, profile);//ProfileFormをProfileにコピーする
        profileService.create(profile, userDetails.getUser());   //ProfileをDBに追加する  (ログインユーザー情報も)
        //LoginUserDetailsオブジェクトに格納されているUser情報を取り出してProfileServiceに渡す
                                    //ログイン中の[LoginUserDetails]オブジェクトに格納されているUser情報を取り出して[ProfileService]に渡す
        return "/konkatsu/profileConfirm";

    }

フォームが画面からそれぞれのデータを送ると

コンソールに
39
佐藤太郎
1
1990-02-03
170
1
500
よろしく
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@23fff05

というように表示されるのですが
DBには
(39, 1, 佐藤太郎, 1990-02-03, 170, 1, 700, よろしく, null).
このように
imageがnullとなって追加されません

byte[]に変換する?

のでしょうか?

controllerの

???

???

の間に書けばよいのでしょうか??

この書き方は違うのでしょうか??少しでもよいので
助言お願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

BeanUtils.copyProperties(form, profile) にて、imageをコピーできていないからではないでしょうか。フィールド名と型が一致していなければコピーできません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/11 09:29

    ありがとうございます。

    キャンセル

0

問題はおそらく登録したい対象をバイナリデータとして適切に扱って無いという点だと思います。
登録先のテーブルのカラムがバイナリ型でバイナリとして登録するか、文字型で文字列として登録するかで扱いが変わります。
バイナリ型であればJDBCのバイナリデータのインターフェイスがあると思いますのでそれを使ってください(byte配列だったかstreamだったか...)。
文字型であればバイナリデータをBase64等で文字列にエンコードしてそのまま文字として登録、取り出すときは同じくデコードすることで永続化できます。
(片手間に書いてるので具体的なソースが無くてすみません...。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/10 19:05

    回答ありがとうございます!!!参考にさせていただきます!

    ちなみになのですが
    これで登録できたとして

    DBにある画像を画面上に出力するにはどんな手順をふんだらよいのでしょうか??

    お手数ですがよろしければお教えください


    キャンセル

  • 2017/07/10 20:13

    要件によってベストな方法や考えるべき事は変わると思いますが、大きく分けて
    1.画像ファイルを実体化する
    2.画像ファイルを実体化しない
    2通りがあると思います。2の場合さらに
    2-1.バイナリストリームとしてクライアント(ブラウザ)に返却する
    2-2.テキストとして返却してクライアント(ブラウザ)で"再生"する
    が代表的じゃないでしょうか(詳しい人ツッコミを)?
    1は例えば
    (1)httpでアクセスできる場所に同名のファイルをサーバ上に作る+DBの内容で中身を書き出す
    (2)imgタグでsrcに(1)の場所を指定する
    など考えられます。単純で作りやすいが作ったファイルの扱いが難しい。同時並行で同じファイルに書き出した場合どうするかとか、上書き許すのかとか、古いものそのままのこしておいて良いのかとか。考えることが多くインターネットで公開する場合普通やらない。
    2-1がオーソドックスなやり方だと思います(?)。imgタグのsrcで指定したURLのとび先をサーブレット(他のCGIでも良いが)にしてストリームを返却するというもの。一時ファイルが残らない上、プログラムを挟むので動的に加工する処理も入れやすいというメリットがある。画像だけでなくflashの動的生成とか結構この方法で作られてました(パターンが多すぎてActionScriptでは制御しきれないようなソシャゲのガチャ演出とか)。
    2-2はcanvasなどつかうものです。本体のhtmlと同時に返せば良いので2-1より扱いやすいといえば扱いやすいと思いますが、今の主流はどうなんでしょう(最近HTMLはご無沙汰なので...)?

    キャンセル

  • 2017/07/11 09:30

    kurokobaさん、わざわざありがとうございました!!参考にさせていただきます!!!!!!

    キャンセル

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

  • ただいまの回答率 89.55%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る