Tweetページの準備

ファイル構成

MyTweet/
├── src/main/java/
│        ├── model/
│        │      ├── TestUser.java
│        │      └── User.java
│        └── page/
│            ├── login/
│            │      ├── LoginAuth.java
│            │      └── LoginIndex.java
│            ├── tweet/
│            │      ├── TweetPost.java
│            │      └── TweetIndex.java
│            └── user/
│                     └── UserIndex.java
└── src/main/webapp/
    ├── css/
    │         └── default.css
    ├── images/
    ├── svg/
    └── views/
        ├── login/
        │     └── index.jsp
        ├── tweet/
        │     └── index.jsp
        └── user/
              └── index.jsp

静的コンテンツの配置

CSSや画像ファイルなどの静的コンテンツファイルをダウンロードして、コンテンツディレクトリに配置します。

GitHub

MyTweet/src/main/webapp/

トップページ

投稿フォームと投稿一覧のトップページを作成します。

サーブレット作成

WebServletアノテーション設定

「TweetIndex」サーブレットを作成し、WebServletアノテーションを設定します。

@WebServlet(name = "TweetIndex", urlPatterns = { "/" })
public class LoginAuth extends HttpServlet 
   ...
}
  • サーブレット名:TweetIndex
  • URLパターン:/
@WebServlet(name = "TweetIndex", urlPatterns = { "/" })
public class TweetIndex extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private String jsp = "/views/tweet/index.jsp";

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher(jsp).forward(request, response); 
	}

}

JSP

「views/tweet/index.jsp」を作成します。

views/tweet/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ja">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tweet</title>
<link
	href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
	rel="stylesheet">
<link rel="stylesheet" href="./css/default.css">
</head>

<body>
	<div class="container-fluid">

		<div class="row">
			<header class="col-md-3">
				<nav id="side-menu">
					<ul>
						<li class="d-flex p-2"><a href=""><span class="icon icon-home"></span> <span class="">ホーム</span></a></li>
					</ul>
				</nav>
			</header>

			<main class="col-md-6">
				<h2 class="h2 mt-3">ツイート</h2>
				<div class="row">
					<form action="tweet/add" method="post">
						<textarea name="message" class="form-control" placeholder="いまどうしてる?"></textarea>
						<div class="mt-3 mb-3 text-center">
							<button class="btn btn-primary rounded-pill w-25">つぶやく</button>
						</div>
					</form>
				</div>

				<div class="row">
					<div class="tweet d-flex">
						<div class="tweet-img">
							<img src="./images/me.png">
						</div>

						<div class="tweet-body">
							<div class="tweet-user">
								<span class="fw-bold">@Tokyo Taro</span>
								<span class="ms-1 text-secondary">30分前</span>
							</div>
							<div class="tweet-text mt-2 mb-2">東京駅にいます!</div>
						</div>
					</div>
				</div>
			</main>

			<aside id="sub-contents" class="col-md-3 mt-3">
			</aside>
		</div>
	</div>

	<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>

</html>

データ送信処理

文字コード指定

Javaで日本語などのマルチバイト文字を利用すると、リクエスト&レスポンスで文字化けしてしまいます。リクエストやレスポンス処理で文字コード「UTF-8」の設定が必要です。

本来の文字

こんにちは

文字化け

ã‚ã‚ãã

リクエスト文字コード指定

リクエストの文字コード指定は setCharacterEncoding() を利用します。

request.setCharacterEncoding("UTF-8");

レスポンス文字コード指定

レスポンスの文字コード指定は setCharacterEncoding() を利用します。

response.setContentType("text/html; charset=UTF-8");

サーブレット作成

WebServletアノテーション設定

「TweetIndex」サーブレットを作成し、WebServletアノテーションを設定します。

@WebServlet(name = "TweetPost", urlPatterns = { "/tweet/add" })
public class LoginAuth extends HttpServlet 
   ...
}
  • サーブレット名:TweetPost
  • URLパターン:/tweet/add

POST送信処理

POSTデータ「message」を取得して、コンソールで表示します。また、投稿後はトップページにリダイレクトしておきます。

tweet.TweetPost.java
public class TweetPost extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");

		// POSTデータ取得
		String message = request.getParameter("message");
		System.out.println(message);

		// トップページにリダイレクト
		response.sendRedirect(request.getContextPath() + "/");
	}

}

データ送信確認

フォームでデータ送信して、コンソール表示を確認しましょう。

結果

よろしく!

トップページ修正

ログイン制御

トップページは、ユーザホーム同様にセッションからユーザを取得します。

tweet.TweetIndex.java
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			User user = (User) request.getSession().getAttribute("auth_user");
			if (user.id > 0) {
				request.setAttribute("user", user);
				request.getRequestDispatcher(jsp).forward(request, response);
			}
		} catch (Exception e) {
			response.sendRedirect(request.getContextPath() + "/login/");
		}
	}

JSPの修正

JavaBeansの設定

「views/tweet/index.jsp」で、Userデータにアクセスできるよう、UserBeansを設定します。

views/tweet/index.jsp
<jsp:useBean id="user" class="model.User" scope="request" />

ユーザデータバインド

任意の場所にユーザ名を表示し、投稿データの「user_id」は「hidden」で送信するようにします。


					<form action="tweet/add" method="post">
						<!-- ユーザ名の設定 -->
						<p><%= user.name %>さん</p>
						<textarea name="message" class="form-control" placeholder="いまどうしてる?"></textarea>
						<div class="mt-3 mb-3 text-center">
							<button class="btn btn-primary rounded-pill w-25">つぶやく</button>
						</div>
						<!-- user_id の設定 -->
						<input type="hidden" name="user_id" value="<%= user.id %>">
					</form>

ユーザ名表示確認

ユーザ名が表示されるか確認します。

ユーザID送信の確認

「TweetPost」サーブレットで、「user_id」を取得します。

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");

		String message = request.getParameter("message");
		Integer userId = Integer.parseInt(request.getParameter("user_id"));
		System.out.println(message);
		System.out.println(userId);

		response.sendRedirect(request.getContextPath() + "/");
	}

「user_id」確認

フォームで送信して「user_id」が送信されたかコンソールで確認します。

結果
よろしく!
1

認証のリダイレクト先変更

「LoginAuth」サーブレットの認証処理で、リダイレクト先をトップページの「/」に変更します。

login.LoginAuth.java
		if (authUser != null && authUser.id > 0) {
			session.setAttribute("auth_user", authUser);
			session.setAttribute("email", "");
			session.setAttribute("errors", "");
			uri = request.getContextPath() + "/";
		} else {
			session.setAttribute("email", email);
			session.setAttribute("errors", "Emailまたはパスワードが間違っています。");
			uri = request.getContextPath() + "/login/";
		}

ログアウトリンク

「views/tweet/index.jsp」にログアウトリンクを追加し、ログアウトを確認します。

views/tweet/index.jsp
			<header class="col-md-3">
				<nav id="side-menu">
					<ul>
						<li class="d-flex p-2"><a href=""><span class="icon icon-home"></span><span class="">ホーム</span></a></li>
						<li class="d-flex p-2"><a href="user/logout"><span class="icon"></span><span class="">ログアウト</span></a></li>
					</ul>
				</nav>
			</header>

ソース

tweet.TweetIndex.java
package page.tweet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.User;

@WebServlet(name = "TweetIndex", urlPatterns = { "/" })
public class TweetIndex extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private String jsp = "/views/tweet/index.jsp";

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			User user = (User) request.getSession().getAttribute("auth_user");
			if (user.id > 0) {
				request.setAttribute("user", user);
				request.getRequestDispatcher(jsp).forward(request, response);
			}
		} catch (Exception e) {
			response.sendRedirect(request.getContextPath() + "/login/");
		}
	}

}

tweet.TweetPost.java
package page.tweet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "TweetPost", urlPatterns = { "/tweet/add" })
public class TweetPost extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");

		String message = request.getParameter("message");
		Integer userId = Integer.parseInt(request.getParameter("user_id"));
		System.out.println(message);
		System.out.println(userId);

		response.sendRedirect(request.getContextPath() + "/");
	}

}
views/tweet/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<jsp:useBean id="user" class="model.User" scope="request" />

<!DOCTYPE html>
<html lang="ja">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tweet</title>
<link
	href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
	rel="stylesheet">
<link rel="stylesheet" href="./css/default.css">
</head>

<body>
	<div class="container-fluid">

		<div class="row">
			<header class="col-md-3">
				<nav id="side-menu">
					<ul>
						<li class="d-flex p-2"><a href=""><span class="icon icon-home"></span><span class="">ホーム</span></a></li>
						<li class="d-flex p-2"><a href="user/logout"><span class="icon"></span><span class="">ログアウト</span></a></li>
					</ul>
				</nav>
			</header>

			<main class="col-md-6">
				<h2 class="h2 mt-3">ツイート</h2>
				<div class="row">
					<form action="tweet/add" method="post">
						<p><%= user.name %>さん</p>
						<textarea name="message" class="form-control" placeholder="いまどうしてる?"></textarea>
						<div class="mt-3 mb-3 text-center">
							<button class="btn btn-primary rounded-pill w-25">つぶやく</button>
						</div>
						<input type="hidden" name="user_id" value="<%= user.id %>">
					</form>
				</div>

				<div class="row">
					<div class="tweet d-flex">
						<div class="tweet-img">
							<img src="./images/me.png">
						</div>

						<div class="tweet-body">
							<div class="tweet-user">
								<span class="fw-bold">@Tokyo Taro</span>
								<span class="ms-1 text-secondary">30分前</span>
							</div>
							<div class="tweet-text mt-2 mb-2">東京駅にいます!</div>
						</div>
					</div>
				</div>
			</main>

			<aside id="sub-contents" class="col-md-3 mt-3">
			</aside>
		</div>
	</div>

	<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>

</html>

TomcatでつくるWebアプリ