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

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

ただいまの
回答率

90.51%

  • Java

    15779questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Spring Boot

    720questions

    Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

  • Thymeleaf

    192questions

    Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

ページング、次のページで400 bad request

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,091

Yoshi--

score 50

コントローラー

package com.example.konkatsu.web;

import java.io.IOException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.example.konkatsu.domain.Profile;
import com.example.konkatsu.service.LoginUserDetails;
import com.example.konkatsu.service.ProfileService;


@Controller
//「URL」の接頭辞をkonkatsuに設定(このクラスで呼ばれたpostなどは/konkatsu/(path)となる)
@RequestMapping("konkatsu")

public class KonkatsuController {
    @Autowired
    ProfileService profileService;

    @ModelAttribute  //@ModelAttributeを付けたメソッド内でProfileFormを初期化
    //@ModelAttributeがついたメソッドは、@PostMappingでマッピングされたメソッドの前に実行され
      //「返り値」は自動で「Model」に追加される(この例だと「list」や「create」メソッドが呼ばれる前に「model.addAttribute(new ProfileForm())」相当の処理が行われる)
     ProfileForm setUpForm() {
            return new ProfileForm();
     }


    @GetMapping   //pathの指定がない場合は URL は/konkatsu
    public String myPage(@AuthenticationPrincipal LoginUserDetails userDetails) {
        return "konkatsu/myPage";
    }


    @GetMapping(path = "profileForm")   //URL は/konkatsu/profileFormとなる
    String list(Model model){  //SpringMVCでは画面に値を渡す為にModelオブジェクトを使用
        List<Profile> profile = profileService.findAll();
        model.addAttribute("profile", profile);  //第一引数はThymeleafで取り出す時に使う名前、第二引数はThymeleafに渡したいオブジェクトを指定
        return "konkatsu/profileForm";   //遷移する画面の名前
    }


    //th:action="@{/konkatsu/createProfile}" の処理
    @PostMapping(path = "createProfile")   //URLが  /konkatsu/createProfile となる
    public String create(@Validated ProfileForm form, BindingResult bindingResult, Model model,
            // 送信されたフォームの入力チェックを行う為に@Validatedアノテーションを付ける。
            // これによりProfileFormに設定したBean Validationアノテーションが評価され、結果が隣の引数のBindingResultに格納される
            @AuthenticationPrincipal LoginUserDetails userDetails) throws IOException{
        //@AuthenticationPrincipalをつけることでログイン中の[LoginUserDetails]オブジェクトを取得できる

        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);
        }


        Profile profile = new Profile();
        profile.setId(form.getId());
        profile.setName(form.getName());
        profile.setGenderId(form.getGenderId());
        profile.setBirthday(form.getBirthday());
        profile.setHeight(form.getHeight());
        profile.setOccupationId(form.getOccupationId());
        profile.setIncome(form.getIncome());
        profile.setText(form.getText());
        MultipartFile uploaded = form.getFile();
        byte[] image = uploaded.getBytes();   //アップロードファイルをbyte配列で取得
        profile.setImage(image);

        BeanUtils.copyProperties(form, profile);//ProfileFormをProfileにコピーする
        profileService.create(profile, userDetails.getUser());   //ProfileをDBに追加する  (ログインユーザー情報も)

        return "/konkatsu/profileConfirm";

    }


    @GetMapping(path = "usersList")   //pathの指定がない場合は URL は/konkatsu
    //htmlからidとして送られた値を@RequestParamにて取得SpringMVCでは画面に値を渡す為にModelオブジェクトを使用
    String usersList(@RequestParam Integer genderId, @PageableDefault (size=3) Pageable pageable, Model model){
        Page<Profile> profiles = profileService.findUsers(genderId, pageable);

        //<ProfileForView>に<Profile>の値を代入処理を繰り返し
        List<ProfileForView> profilesForView = new ArrayList<ProfileForView>();
        for(Profile profile: profiles){
            ProfileForView profileForView = new ProfileForView(profile);
            profilesForView.add(profileForView);
        }


        model.addAttribute("page", profiles);
        model.addAttribute("url", "/konkatsu/usersList");
        model.addAttribute("profiles", profilesForView);
        return "konkatsu/profileList";   //遷移する画面の名前
    }



    @GetMapping(path = "myProfile")   //pathの指定がない場合は URL は/konkatsu
    String MyList(@RequestParam Integer id, Model model){  //SpringMVCでは画面に値を渡す為にModelオブジェクトを使用
        Profile profile = profileService.findProfile(id);

        //第一引数はThymeleafで取り出す時に使う名前、第二引数はThymeleafに渡したいオブジェクトProfileForViewを指定
        model.addAttribute("profile", new ProfileForView(profile));
        return "konkatsu/myProfile";   //遷移する画面の名前
    }

    //View用のクラス
    public class ProfileForView {
        public Integer id;
        public String name;
        public Integer genderId;
        public String gender;
        public Date birthday;
        public Integer height;
        public String occupationName;
        public Integer income;
        public String text;
        public String mail;
        public String image;

        //profileの値を代入
        public ProfileForView(Profile profile){
            this.id = profile.getId();
            this.name = profile.getName();
            this.genderId = profile.getGenderId();
            this.gender = profile.getGender().getGender();
            this.birthday = profile.getBirthday();
            this.height = profile.getHeight();
            this.occupationName = profile.getOccupation().getOccupationName();
            this.income = profile.getIncome();
            this.text = profile.getText();
            this.mail = profile.getUser().getMail();
            //画像ファイルをBASE64形式でエンコード
            this.image = Base64.getEncoder().encodeToString(profile.getImage());
        }
    }
}

profileList.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>婚活サイト</title>
<link rel="stylesheet"
    href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
    th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />
<link rel="stylesheet"
    href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
    th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.min.css}" />
</head>

<body th:with="user=${#authentication.principal.user}">
    <!-- authenticationで認証ユーザー情報にアクセスできる 、principalプロパティでUserDetailsオブジェクトにアクセスできるので、user.mailでログインユーザー名が分かる-->

    <h2>
        <span th:text="${user.mail}">メアド</span> さん、ログイン中
    </h2>


    <table class="table table-striped table-bordered table-condensed">
        <h2>登録ユーザー</h2>
        <tr>
            <th>写真</th>
            <th>名前</th>
            <th>性別</th>
            <th>誕生日</th>
            <th>身長(cm)</th>
            <th>職業</th>
            <th>年収(万円)</th>
            <th>自己紹介</th>
            <th>メールアドレス</th>
        </tr>

        <tr th:each="profile : ${profiles}">
            <!-- エンコードした画像の表示 -->
            <td><img th:src="${'data:image/png;base64,' + profile.image}" width="250" height="150" /></td>
            <td th:text="${profile.name}">山田</td>
            <td th:text="${profile.gender}"></td>
            <td th:text="${profile.birthday}">誕生日</td>
            <td th:text="${profile.height}">170</td>
            <td th:text="${profile.occupationName}">職業</td>
            <td th:text="${profile.income}">年収</td>
            <!-- 「profile」オブジェクトがもつ「user」の「mail」を表示 -->
            <td th:text="${profile.mail}">メール</td>
            <td th:text="${profile.text}">自己紹介</td>
        </tr>
    </table>

    <div th:fragment='paginationbar'>
        <ul>
            <li th:class="${page.first} ? 'disabled':''" style="display: inline">
                <span th:if="${page.first}">←先頭</span>
                <a th:if="${not page.first}" th:href="@{${url}(page=0)}">←先頭</a>
            </li>

            <!-- #numbers.sequenceは引数に指定した2つの数値の範囲で配列を生成 -->
            <li th:each='i : ${#numbers.sequence(0, page.totalPages-1)}'
                th:class="(${i}==${page.number})? 'active' : ''"
                style="display: inline">
                <span th:if='${i}==${page.number}' th:text='${i+1}'>1</span>
                <a th:if='${i}!=${page.number}' th:href="@{'/konkatsu/usersList'(page=${i})}">
                    <span th:text='${i+1}'>1</span>
                </a>
            </li>
            <li th:class="${page.last} ? 'disabled':''" style="display: inline">
                <span th:if="${page.last}">末尾➝</span>
                <a th:if="${not page.last}" th:href="@{${url}(page=(${page.totalPages}-1))}">末尾➝</a>
            </li>
        </ul>
    </div>

    <form th:action="@{/konkatsu/myProfile}" method="get">
        <input type="hidden" name="id" th:value="${user.userId}" />
        <button type="submit" class="btn btn-lg btn-primary btn-block">Myページへ</button>
    </form>
</body>
</html>

*名前やアドレスなどは全て架空のものです

イメージ説明

こんな感じで表示されるのですが

次のページにいこうと
2
を押すと

イメージ説明

が表示されてしまいます

URLはhttp://localhost:8080/konkatsu/userList?page=1

が表示されています。

genderIDをパラメータで送るとすると
hiddenで送れば良いのでしょうか?
どこに書けば良いのでしょうか??

<form  th:action="@{/konkatsu/usersList}" method="get">
    <input type="hidden" name="genderId" th:value="${profile.genderId}" />
    <button type="submit" class="btn btn-lg btn-primary btn-block">登録ユーザー一覧を見る</button>
    </form>

参考になる資料などがあれば
教えていただきたいです。

よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • ahodana

    2017/07/21 12:30

    エラーは 404 ではなく、400 bad request

    キャンセル

  • Yoshi--

    2017/07/21 12:31

    失礼いたしました、修正いたしました

    キャンセル

回答 1

checkベストアンサー

0

@RequestParamuの設定で

required=false

とすればそのエラーはでなくなるはずです。

未設定時は 必須になります

また、

(page=2)を(page=2,genderId=0)とすることでパラメーターに追加できます

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/21 12:45

    ありがとうございます!

    しかし次はこんなエラーとなってしまいました。

    There was an unexpected error (type=Internal Server Error, status=500).
    Exception evaluating SpringEL expression: "#numbers.sequence(0, page.totalPages-1)"

    キャンセル

  • 2017/07/21 12:52


    表示されるようになりました!
    助かりました。
    本当にありがとうございます!!!!!!!!

    キャンセル

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

  • Java

    15779questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Spring Boot

    720questions

    Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

  • Thymeleaf

    192questions

    Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。