JSP/Servletで複数ページあるサイトを効率的に作成しよう

JSP&Servlet

JSP/Servletを用いて複数ページで構成されるサイトを作成しよう。

関連項目

◎標準アクションタグ<jsp:include>
◎Filter

作業手順

○まずは見た目となるHtml&cssをVScodeなどのサイト作成を行いやすい環境で作成する。 今回はこの記事で作成したサイトを雛形として使っていく

○エクリプスにて新規動的Webプロジェクトよりsamplesiteを作成する
○お手本サイトから画像をダウンロードする。この画像は圧縮してあるので展開して6枚の画像をコピーする
○webappの直下にimagesフォルダを作成して、6枚の画像をペーストして貼り付ける

○webappの直下にcssフォルダを作成して、main.cssを作成する。内容は以下

body{
  color:#333;
}
.container{
  width:960px;
  margin:0 auto;
}
header{
  height:250px;
  background-image:url(../images/header_bg.png);
  background-size:cover;
}
header h1{
  font-size:80px;
  text-align: center;
  line-height: 250px;
}
nav ul{
  padding:5px 30px;
  background:#666;
  /*親要素にdisplay:flex*/
  display: flex;
  /*並べる方向*/
  /* flex-direction: column; */
  /*配置*/
  justify-content:flex-end;
}

nav ul li a{
  display: block;
  padding:5px 10px;
  border-radius: 5px;
  background:#999;
  color:white;
  text-decoration: none;
  margin:5px 10px;
  border:1px solid #333;
}
/*属性セレクタ*/
div[role="main"]{
  background:#eee;
  padding:30px 30px 70px;
}
h2{
  text-align: center;
  font-size:30px;
  margin-top:30px;
}
/*隣接セレクタ(h2の次にあるp)*/
h2 + p{
  text-align: center;
  margin-bottom:20px;
}

#infoBox{
   display: flex;
}

#infoBox .info{
  position:relative;
  border-radius:5px;
  border:1px solid #333;
  margin:20px 10px;
  background:white;
  min-width:220px;
  /*幅を指定したい場合*/
  /* flex-basis:30%; */
  /*縦方向の配置*/
  /* align-self:center; */
}

#infoBox .info h3{
  padding:5px 20px;
  background:#666;
  color:#eee;
}

#infoBox .info p{
  padding:10px 20px 30px;
}

#infoBox .info p a{
  position:absolute;
  bottom:10px;
  right:15px;
}
#blogBox{
  display: flex;
  /*要素が端までいったら折り返す*/
  flex-wrap:wrap;
  justify-content:space-between;
}
.blogItem{
  position: relative;
  display: flex;
  /*縦方向の配置*/
  align-items: flex-start;
  /*flexitemの幅指定*/
  flex-basis:43%;
  border:1px solid #333;
  border-radius:5px;
  padding:16px 16px 30px;
  margin:10px;
  background:white;
}
/*直下の子要素指定*/
.blogItem > a{
  position: absolute;
  bottom:10px;
  right:20px;
}

/*偶数番目のblogItem*/
.blogItem:nth-child(even){
  /*配置を行方向逆順*/
  flex-direction: row-reverse;
}

.blogItem img{
  width:130px;
}
.blogItem:nth-child(odd) img{
  margin-right:10px;
}
.blogItem:nth-child(even) img{
  margin-left:10px;
}
footer{
  text-align: center;
  padding:10px 0;
  background:#666;
  color:white;
}

○WEB-INFの直下にviewフォルダを作成して、Home.jspを作成する。内容は以下。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">   
    <title>FlexboxLesson</title>
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
    <link rel="stylesheet" href="css/main.css"/>
  </head>
  <body>
    <div class="container">
      <header>
        <h1>Header</h1>
      </header>
      <nav>
        <ul>
          <li><a href="">Home</a></li>
          <li><a href="">Menu1</a></li>
          <li><a href="">Menu2</a></li>
          <li><a href="">Menu3</a></li>
          <li><a href="">Menu4</a></li>
        </ul>
      </nav>
      <div role="main">
        <section id="information">
          <h2>Information</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="infoBox">
            <section class="info">
              <h3>info1</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info2</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info3</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute <a href="">more...</a></p>
            </section>
          </div>
        </section>
        <section id="blog">
          <h2>Blog</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="blogBox">
            <div class="blogItem">
              <img src="images/atom.png" alt="atom">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/html.png" alt="html">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/java.png" alt="java">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/vs.png" alt="vs">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur </p>
              <a href="">more...</a>
            </div>
          </div>
        </section>
      </div>
      <footer>
        ©Joytas.net
      </footer>
    </div>
  </body>
</html>

○新規サーブレットからcontroller.Home.javaを作成する。内容は以下

package controller;

import java.io.IOException;

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

@WebServlet("/Home")
public class Home extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("WEB-INF/view/Home.jsp").forward(request, response);
	}
}

○サーブレットから実行してみよう。サイトが復元されればOKだ。

ポイント解説

このようにメインとなるページをvscodeなどの使い慣れたエディタでHtml/cssを作成し、それをエクリプスに持ってくるところからスタートする。

下層ページ作成

今回はnavにあるHome,Memu1,Menu2,Menu3,Menu4の計5枚のページがあるサイトを作成していく。

共通部分の部品化

各ページで共通となる部分を部品化させて、includeで読み込みようにしていくことが大切だ。こうすることでサイトに修正があった場合作業がとても楽に行える。

○footer.jsp
WEB-INF/viewフォルダに新規jspファイルからfooter.jspを作成して以下のように記述する

     
<%@ page language="java" pageEncoding="UTF-8"%>
<footer>
©Joytas.net
</footer>

○Home.jspの修正
Home.jspのフッター部分をfooter.jspをインクルードするよう以下のように修正する。(71行目)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">   
    <title>FlexboxLesson</title>
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
    <link rel="stylesheet" href="css/main.css"/>
  </head>
  <body>
    <div class="container">
      <header>
        <h1>Header</h1>
      </header>
      <nav>
        <ul>
          <li><a href="">Home</a></li>
          <li><a href="">Menu1</a></li>
          <li><a href="">Menu2</a></li>
          <li><a href="">Menu3</a></li>
          <li><a href="">Menu4</a></li>
        </ul>
      </nav>
      <div role="main">
        <section id="information">
          <h2>Information</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="infoBox">
            <section class="info">
              <h3>info1</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info2</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info3</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute <a href="">more...</a></p>
            </section>
          </div>
        </section>
        <section id="blog">
          <h2>Blog</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="blogBox">
            <div class="blogItem">
              <img src="images/atom.png" alt="atom">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/html.png" alt="html">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/java.png" alt="java">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/vs.png" alt="vs">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur </p>
              <a href="">more...</a>
            </div>
          </div>
        </section>
      </div>
      <jsp:include page="footer.jsp"/>
    </div>
  </body>
</html>

ポイント

今回のフッターは各ページ共通なのでfooter.jspとして括りだした。
このjspファイルを標準アクションタグである
<jsp:include page=”読み込み元となるjspファイルからの相対パス” />
を用いてincludeしている。パスの指定が読み込み元となるjspファイルからの相対パスでしていするのがポイントだ。今回2枚のファイルは同じ階層にあるのでそのままfooter.jspでOKだ。また閉じタグを
/>
のようにxmlファイルのルールにしたがって書かなければならないので注意する。(この/を省略してしまうとエラーになる。)

head.jsp

各ページで共通となる部分をどんどん括りだしていこう。
新規jspファイルでhead.jspを以下のように作成する。

<%@ page language="java" pageEncoding="UTF-8"%>
  <head>
    <meta charset="utf-8">   
    <title>FlexboxLesson</title>
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.18.1/build/cssreset/cssreset-min.css">
    <link rel="stylesheet" href="css/main.css"/>
  </head>

続いて、Main.jspのheadの部分を置き換える。ついでにh1もHomeに変えておこう。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
  <jsp:include page="head.jsp" />
  <body>
    <div class="container">
      <header>
        <h1>Home</h1>
      </header>
      <nav>
        <ul>
          <li><a href="">Home</a></li>
          <li><a href="">Menu1</a></li>
          <li><a href="">Menu2</a></li>
          <li><a href="">Menu3</a></li>
          <li><a href="">Menu4</a></li>
        </ul>
      </nav>
      <div role="main">
        <section id="information">
          <h2>Information</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="infoBox">
            <section class="info">
              <h3>info1</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info2</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info3</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute <a href="">more...</a></p>
            </section>
          </div>
        </section>
        <section id="blog">
          <h2>Blog</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="blogBox">
            <div class="blogItem">
              <img src="images/atom.png" alt="atom">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/html.png" alt="html">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/java.png" alt="java">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/vs.png" alt="vs">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur </p>
              <a href="">more...</a>
            </div>
          </div>
        </section>
      </div>
      <jsp:include page="footer.jsp" />
      
    </div>
  </body>
</html>

nav.jsp

同じようにnavタグの部分を括りだす。後ほど実際に遷移できるようにするため、空だったherf属性も指定しておく。nav.jspを以下のように作成。

<%@ page language="java" pageEncoding="UTF-8"%>
      <nav>
        <ul>
          <li><a href="Home">Home</a></li>
          <li><a href="Menu1">Menu1</a></li>
          <li><a href="Menu2">Menu2</a></li>
          <li><a href="Menu3">Menu3</a></li>
          <li><a href="Menu4">Menu4</a></li>
        </ul>
      </nav>

Home.jspを以下のように変更

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
  <jsp:include page="head.jsp" />
  <body>
    <div class="container">
      <header>
        <h1>Home</h1>
      </header>
      <jsp:include page="nav.jsp" />
      <div role="main">
        <section id="information">
          <h2>Information</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="infoBox">
            <section class="info">
              <h3>info1</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info2</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur<a href="">more...</a></p>
            </section>
            <section class="info">
              <h3>info3</h3>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute <a href="">more...</a></p>
            </section>
          </div>
        </section>
        <section id="blog">
          <h2>Blog</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
          <div id="blogBox">
            <div class="blogItem">
              <img src="images/atom.png" alt="atom">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/html.png" alt="html">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/java.png" alt="java">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,</p>
              <a href="">more...</a>
            </div>
            <div class="blogItem">
              <img src="images/vs.png" alt="vs">
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur adipisicing elit,dolor sit amet, consectetur </p>
              <a href="">more...</a>
            </div>
          </div>
        </section>
      </div>
      <jsp:include page="footer.jsp" />
      
    </div>
  </body>
</html>

Menu1ページの作成

共通部分の部品化ができたのでページを作成していこう。まずはMenu1ページを作成する。

controller.Meun1.java

新規サーブレットからcontroller.Menu1.javaを以下のように作成する。

package controller;

import java.io.IOException;

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

@WebServlet("/Menu1")
public class Menu1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("WEB-INF/view/Menu1.jsp").forward(request, response);
	}

}

Menu1.jspの作成

Home.jspを複製し、名前をMenu1.jspに変更。
以下のようにコンテンツ部分を作成する(今回この部分は細かくは作成しない)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
  <jsp:include page="head.jsp" />
  <body>
    <div class="container">
      <header>
        <h1>Menu1</h1>
      </header>
      <jsp:include page="nav.jsp" />
      <div role="main">
      	Menu1
      </div>
      <jsp:include page="footer.jsp" />
    </div>
  </body>
</html>

Homeから起動して、メニューからMenu1をクリックしてみよう。ページが遷移することが確認できる。

現在ページの表示

これでHomeとMenu1は行ったり来たりできるようになったのだが、こういったメニューを作る際には現在ページが何処なのかを表示しておくとユーザービリティがよい。その仕組をいれていこう。

controller.Home.javaの変更

package controller;

import java.io.IOException;

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

@WebServlet("/Home")
public class Home extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//サーブレットパスを取得し、リクエストスコープに保存
		request.setAttribute("path", request.getServletPath());
		request.getRequestDispatcher("WEB-INF/view/Home.jsp").forward(request, response);
	}
}

nav.jspの変更

以下のように変更する。

<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path=(String)request.getAttribute("path");
%>
      <nav>
        <ul>
          <li><a href="Home" class="<%=path.equals("/Home")? "active":""%>">Home</a></li>
          <li><a href="Menu1" class="<%=path.equals("/Menu1")? "active":""%>">Menu1</a></li>
          <li><a href="Menu2" class="<%=path.equals("/Menu2")? "active":""%>">Menu2</a></li>
          <li><a href="Menu3" class="<%=path.equals("/Menu3")? "active":""%>">Menu3</a></li>
          <li><a href="Menu4" class="<%=path.equals("/Menu4")? "active":""%>">Menu4</a></li>
        </ul>
      </nav>

Homeから実行してみよう。一見変わりが無いようだが、ソースをみると現在ページのクラスのactiveが付与されているのがわかる。

main.cssの変更

41-43行目に追記する。

body{
  color:#333;
}
.container{
  width:960px;
  margin:0 auto;
}
header{
  height:250px;
  background-image:url(../images/header_bg.png);
  background-size:cover;
}
header h1{
  font-size:80px;
  text-align: center;
  line-height: 250px;
}
nav ul{
  padding:5px 30px;
  background:#666;
  /*親要素にdisplay:flex*/
  display: flex;
  /*並べる方向*/
  /* flex-direction: column; */
  /*配置*/
  justify-content:flex-end;
}


nav ul li a{
  display: block;
  padding:5px 10px;
  border-radius: 5px;
  background:#999;
  color:white;
  text-decoration: none;
  margin:5px 10px;
  border:1px solid #333;
}

nav ul li a.active{
	text-decoration: underline;
}
/*属性セレクタ*/
div[role="main"]{
  background:#eee;
  padding:30px 30px 70px;
}
h2{
  text-align: center;
  font-size:30px;
  margin-top:30px;
}
/*隣接セレクタ(h2の次にあるp)*/
h2 + p{
  text-align: center;
  margin-bottom:20px;
}

#infoBox{
   display: flex;
}

#infoBox .info{
  position:relative;
  border-radius:5px;
  border:1px solid #333;
  margin:20px 10px;
  background:white;
  min-width:220px;
  /*幅を指定したい場合*/
  /* flex-basis:30%; */
  /*縦方向の配置*/
  /* align-self:center; */
}

#infoBox .info h3{
  padding:5px 20px;
  background:#666;
  color:#eee;
}

#infoBox .info p{
  padding:10px 20px 30px;
}

#infoBox .info p a{
  position:absolute;
  bottom:10px;
  right:15px;
}
#blogBox{
  display: flex;
  /*要素が端までいったら折り返す*/
  flex-wrap:wrap;
  justify-content:space-between;
}
.blogItem{
  position: relative;
  display: flex;
  /*縦方向の配置*/
  align-items: flex-start;
  /*flexitemの幅指定*/
  flex-basis:43%;
  border:1px solid #333;
  border-radius:5px;
  padding:16px 16px 30px;
  margin:10px;
  background:white;
}
/*直下の子要素指定*/
.blogItem > a{
  position: absolute;
  bottom:10px;
  right:20px;
}

/*偶数番目のblogItem*/
.blogItem:nth-child(even){
  /*配置を行方向逆順*/
  flex-direction: row-reverse;
}

.blogItem img{
  width:130px;
}
.blogItem:nth-child(odd) img{
  margin-right:10px;
}
.blogItem:nth-child(even) img{
  margin-left:10px;
}
footer{
  text-align: center;
  padding:10px 0;
  background:#666;
  color:white;
}

これで現在ページを識別できるようになった!

Filterの利用

controller.Menu1.javaにも以下のように追記する方法も考えられるが同じ処理を複数書くのはDRYの原則に反する。

package controller;

import java.io.IOException;

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

@WebServlet("/Menu1")
public class Menu1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//サーブレットパスを取得し、リクエストスコープに保存
		request.setAttribute("path", request.getServletPath());
		request.getRequestDispatcher("WEB-INF/view/Menu1.jsp").forward(request, response);
	}

}

filter.GetServltPath.java

新規フィルターからfilter.GetServletPath.javaを以下のように作成する

package filter;

import java.io.IOException;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebFilter("/*")
public class GetServletPath extends HttpFilter {
       
	public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
		request.setAttribute("path",request.getServletPath());
		chain.doFilter(request, response);
	}
}

これですべてのリクエストに対してリクエストスコープにServletPathを詰めることができるようになった。controller.Home.javaから先程追加した部分を削除しよう。

package controller;

import java.io.IOException;

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

@WebServlet("/Home")
public class Home extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("WEB-INF/view/Home.jsp").forward(request, response);
	}
}

残りのページの作成

HomeとMenu1ができたのでMenu2~Menu4を作成しよう。

controller.Menu2.java

package controller;

import java.io.IOException;

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

@WebServlet("/Menu2")
public class Menu2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("WEB-INF/view/Menu2.jsp").forward(request, response);

	}

}

Menu2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
  <jsp:include page="head.jsp" />
  <body>
    <div class="container">
      <header>
        <h1>Menu2</h1>
      </header>
      <jsp:include page="nav.jsp" />
      <div role="main">
      	Menu2
      </div>
      <jsp:include page="footer.jsp" />
    </div>
  </body>
</html>

以下同じようにMenu3,Menu4も作成する。

動作確認

ページを作成できたら実際にページを遷移してみよう。現在ページにアンダーラインが引かれれば成功だ。
複数ページがあるサイトをJSP/Servletを使って作る際の参考にしてもらいたい。

追記

以下のようにnav.jspの部分の繰り返し部分をJavaを使って記述するのも大変よい工夫だ。

<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path=(String)request.getAttribute("path");
String[] menus={"Home","Menu1","Menu2","Menu3","Menu4"};
%>
      <nav>
        <ul>
          <% for(String menu : menus){ %>
          <li><a href="<%=menu %>" class="<%=path.equals("/"+menu)? "active":""%>"><%=menu %></a></li>
          <% } %>
        </ul>
      </nav>

コメント

タイトルとURLをコピーしました