これは何
DockerとWebアプリ作成の勉強のため,この本の第3章をDockerコンテナの上で実装してみた際のメモ.
ファイル構成
$ tree .
.
├── Dockerfile
└── testbbs
└── WEB-INF
├── classes
├── src
│ ├── Message.java
│ ├── PostBBS.java
│ └── ShowBBS.java
└── web.xml
4 directories, 5 files
Dockerfile
Dockerfile
FROM tomcat:8.5.54-jdk11-adoptopenjdk-hotspot
WORKDIR /usr/local/tomcat/webapps/
RUN mkdir -p ./testbbs
COPY ./testbbs ./testbbs/
RUN javac -classpath $CATALINA_HOME/lib/servlet-api.jar -d ./testbbs/WEB-INF/classes ./testbbs/WEB-INF/src/*.java
Javaファイル
参考にしてる本と同じ.
Message.java
import java.util.*;
public class Message {
public static ArrayList<Message> messageList = new ArrayList<Message>();
String title;
String handle;
String message;
Date date;
Message (String title, String handle, String message) {
this.title = title;
this.handle = handle;
this.message = message;
this.date = new Date();
}
}
PostBBS.java
import java.io.*;
import javax.servlet.http.*;
public class PostBBS extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws UnsupportedEncodingException, IOException {
request.setCharacterEncoding("UTF-8");
Message newMessage = new Message(request.getParameter("title"),
request.getParameter("handle"),
request.getParameter("message"));
Message.messageList.add(0, newMessage);
response.sendRedirect("/testbbs/ShowBBS");
}
}
ShowBBS.java
import java.io.*;
import javax.servlet.http.*;
public class ShowBBS extends HttpServlet {
private String espaceHTML (String src) {
return src.replace ("&", "&").replace("<", "<")
.replace (">", ">").replace ("\"", """)
.replace ("'", "'");
}
@Override
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>テスト掲示板</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>テスト掲示板</h1>");
out.println("<form action='/testbbs/PostBBS' method='post'>");
out.println("タイトル:<input type='text' name='title' size='60'>");
out.println("<br />");
out.println("ハンドル名:<input type='text' name='handle'>");
out.println("<br />");
out.println("<textarea name='message' rows='4' cols='60'></textarea>");
out.println("<br />");
out.println("<input type='submit' />");
out.println("</form>");
out.println("<hr />");
for (Message message: Message.messageList) {
out.println("<p> 『" + espaceHTML(message.title) + "』 ");
out.println(espaceHTML(message.handle) + " さん ");
out.println(espaceHTML(message.date.toString()) + "</p>");
out.println("<p>");
out.println(espaceHTML(message.message).replace("\r\n", "<br />"));
out.println("</p><hr />");
}
out.println("</body>");
out.println("</html>");
}
}
web.xmlファイル
これも本と同じ.
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/nx/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>ShowBBS</servlet-name>
<servlet-class>ShowBBS</servlet-class>
</servlet>
<servlet>
<servlet-name>PostBBS</servlet-name>
<servlet-class>PostBBS</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ShowBBS</servlet-name>
<url-pattern>/ShowBBS</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PostBBS</servlet-name>
<url-pattern>/PostBBS</url-pattern>
</servlet-mapping>
</web-app>
ビルドして実行
$ docker build -t henacat .
Sending build context to Docker daemon 11.78kB
Step 1/6 : FROM tomcat:8.5.54-jdk11-adoptopenjdk-hotspot
---> 66317f378ae0
Step 2/6 : RUN apt-get update && apt-get install -y wget
---> Using cache
---> 871dd39a71cc
Step 3/6 : WORKDIR /usr/local/tomcat/webapps/
---> Using cache
---> 19d29e246ff6
Step 4/6 : RUN mkdir -p ./testbbs
---> Using cache
---> c2765cdc59e3
Step 5/6 : COPY ./testbbs ./testbbs/
---> Using cache
---> dbd09272e03b
Step 6/6 : RUN javac -classpath $CATALINA_HOME/lib/servlet-api.jar -d ./testbbs/WEB-INF/classes ./testbbs/WEB-INF/src/*.java
---> Using cache
---> 41e02fb5b101
Successfully built 41e02fb5b101
Successfully tagged henacat:latest
$ docker run -d -p 8080:8080 -it henacat
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
249799090cb1 henacat "catalina.sh run" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp elegant_ishizaka
http://localhost:8080/testbbs/ShowBBS にアクセスすると,ちゃんと掲示板が表示される.
ハマったこと
最初に使ったDockerイメージはtomcat:10.0.0-jdk11-adoptopenjdk-hotspot だったが,これだとコンパイルが通らなかった.
どうもサーブレットのためのパッケージが見つからないらしい.
クラスパスを間違えたかなと思い色々変えてみたがコンパイルエラーは直らず,tomcatの問題かと思いドキュメントを見にいくと,tomcat-10からどうもパッケージ名が変わったらしい.
tomcat-8 では,javax.servlet.httpだったのが,tomcat-10では,jakarta.servlet.httpとなっており,そりゃパッケージ見つからんってエラー吐かれるよなと.
と言うわけで,本と同じtomcat-8のDockerイメージを用いることで無事解決.