Eclipseで.warファイルを作成・配置する方法

ローカルのeclipseで作成したservletを開発環境、STG、本番環境にデプロイしたい場面があるとします。その場合に、どのような手順で.warファイルを作成、配置するのか、考えたいと思います。

.warファイルとは
javaの設定ファイル、jsp、html、jar形式のライブラリなどがまとめられているアーカイブ。これをtomcat配布すると、それを元にデプロイされる

1. eclipseでアプリケーションを開発する
ここではサンプルとして、TodoServletというアプリケーションを開発しているとします。

2. 画面左ペインProject Explorerのプロジェクトで右クリック
Project Explorerのプロジェクトフォルダで右クリックするとexport -> war fileと出てきます。

3. war fileをexport
export -> war fileを選択すると、ポップアップがひらくので、destinationでwar fileのexport先を指定し、展開します。

すると、指定したディレクトリに ${projectName}.warfile というファイルが生成されます。

このwarファイルをtomcatのwebappに配置すれば完了です。

servletでselectしてredirect

Connection conn = null;
		ResultSet rs = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			conn = DriverManager.getConnection("jdbc:mysql://localhost/sampledb","root","");

			Statement stmt = conn.createStatement();
			String sql = "select * from userinfo where status = 2";
			rs = stmt.executeQuery(sql);
			stmt.close();

			String view = rs.getString("userid");
			// String view = "https://www.google.com";
			response.sendRedirect(view);
		} catch(Exception e) {
			  e.printStackTrace();
		}
		finally {			
			
		}

なんか上手くいきませんね。executeQuery以降が駄目っぽいです。

servletからmysqlにinsert

servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		// response.getWriter().append("Served at: ").append(request.getContextPath());
		
		// import java.sql.*;
//		Connection db_con = null;
//		PreparedStatement db_st = null;
//		ResultSet db_data = null;
		
		Connection conn = null;
		ResultSet rs = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			conn = DriverManager.getConnection("jdbc:mysql://localhost/sampledb","root","");

			Statement stmt = conn.createStatement();
			String sql = "insert into userinfo(userid, status) values ('hoge', 1)";
			int num = stmt.executeUpdate(sql);
			stmt.close();
		} catch(Exception e) {
			  e.printStackTrace();
		}
		finally {
			
		}
		
		
		
	}

mysql> select * from userinfo;
+———+——–+
| userid | status |
+———+——–+
| aaaa123 | 0 |
| asdf123 | 1 |
| hoge | 1 |
| xyzx123 | 2 |
+———+——–+
4 rows in set (0.01 sec)

なるほど♪

eclipseでmysqlに接続(3時間かかったーーーーー)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//		response.getWriter().append("Served at: ").append(request.getContextPath());
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		try {
		  Class.forName("com.mysql.jdbc.Driver").newInstance();
		  conn = DriverManager.getConnection("jdbc:mysql://localhost/sampledb?user=root&password=");
		  stmt = conn.createStatement();
		  rs = stmt.executeQuery("SELECT userid,status FROM userinfo");
		  
		  response.setContentType("text/plain");
		  while (rs.next()) {
		    response.getWriter().write("userid=" + rs.getString("userid") + ", ");
		    response.getWriter().write("status=" + rs.getString("status") + "\n");
		  }
		} catch(Exception e) {
		  e.printStackTrace();
		} finally {
		  if (rs != null ) { try {rs.close(); } catch (SQLException e) {e.printStackTrace();} }
		  if (stmt != null ) { try {stmt.close(); } catch (SQLException e) {e.printStackTrace();} }
		  if (conn != null ) { try {conn.close(); } catch (SQLException e) {e.printStackTrace();} }
		}
		
	}

見よ、涙の結晶を!! これだけで3時間くらいかかった。

疲れたので、あまり喜べない。。。
とりあえず、tomcat + servlet + jspで mysql、redirectまでは解った!!! 
すげーーーーーーーーーーーーーーーー
mysql connectorは鬼門だった。。
さあ~ ansible 行ってみよう♪♪♪♪♪ 

Loading class `com.mysql.jdbc.Driver’. This is deprecated.

Loading class `com.mysql.jdbc.Driver’. This is deprecated.

以下に変更

Class.forName("com.mysql.cj.jdbc.Driver").newInstance();

Loading class `com.mysql.jdbc.Driver’. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
java.sql.SQLException:

connectorがどうもおかしいっぽい。
なんか違うなーと思ったらconnector/jか! 間際らしい。

mysql-connector

eclipseのlibにmysql-connectorを配置する

servletを作成する。mysqltestとしよう。

add to build pathとする

とりあえずwindows10 のmysqlにテーブルとレコードを無理矢理つくります。
mysql> create database sampledb
-> ;
Query OK, 1 row affected (0.13 sec)

mysql> use sampledb
Database changed
mysql> create table userinfo(
-> userid varchar(10) primary_key,
-> status Int
-> );
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘primary_key,
status Int
)’ at line 2
mysql> create table userinfo(
-> userid varchar(10) primary key,
-> status int
-> );
Query OK, 0 rows affected (1.04 sec)

mysql> insert into userinfo (userid, status) values (“aaaa123”, 0),(“asdf123”, 1),(“xyzx123”,2);
Query OK, 3 rows affected (0.17 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> select * from userinfo;
+———+——–+
| userid | status |
+———+——–+
| aaaa123 | 0 |
| asdf123 | 1 |
| xyzx123 | 2 |
+———+——–+
3 rows in set (0.00 sec)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//		response.getWriter().append("Served at: ").append(request.getContextPath());
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		try {
		  Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
		  conn = DriverManager.getConnection("jdbc:mysql:C:/mysql-56/data/sampledb?user=root&password=");
		  stmt = conn.createStatement();
		  rs = stmt.executeQuery("SELECT userid,status FROM userinfo");
		  
		  response.setContentType("text/plain");
		  while (rs.next()) {
		    response.getWriter().write("userid=" + rs.getString("userid") + ", ");
		    response.getWriter().write("status=" + rs.getString("status") + "\n");
		  }
		} catch(Exception e) {
		  e.printStackTrace();
		} finally {
		  if (rs != null ) { try {rs.close(); } catch (SQLException e) {e.printStackTrace();} }
		  if (stmt != null ) { try {stmt.close(); } catch (SQLException e) {e.printStackTrace();} }
		  if (conn != null ) { try {conn.close(); } catch (SQLException e) {e.printStackTrace();} }
		}
		
	}

Loading class `com.mysql.jdbc.Driver’. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
java.sql.SQLException: No suitable driver found for jdbc:mysql:C:/mysql-56/data/sampledb?user=root&password=
at java.sql.DriverManager.getConnection(Unknown Source)

やりたいことはわかった。

servletのリダイレクト処理

doGetなどは関係ないが、とにかく、response.sendRedirect(url);でリダイレクトができる。

package todo.controller;

import java.io.IOException;

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


/**
 * Servlet implementation class HelloServlet
 */
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
    	request.setAttribute("foo", "hogehoge");

		String view = "/WEB-INF/view/index.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(view);

		dispatcher.forward(request, response);
	}
	

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String value = request.getParameter("hoge");
		System.out.println(value);
		String url = "http://www.google.com";
		response.sendRedirect(url);
//		doGet(request, response);
	}

}

jspは省略
postを受け取って、redirect

OKOK。次はmysql接続

eclipseのファイルをvagrantのtomcat8.5にデプロイする

コマンドラインでtomcatを起動しておきます。
[vagrant@localhost tomcat]$ sudo /opt/tomcat/apache-tomcat-8.5.33/bin/shutdown.sh

elipseの対象パッケージからwar.fileをexportする。

war.fileをtomcatのwebapp配下に配置します。※ここはgitでいいでしょうね。
数秒するとwarから自動的にフォルダが生成されます。

eclipseからvagrantにデプロイできました。素晴らしい!

eclipseで利用するtomcatのバージョンとvagrantにインストールするtomcatのバージョンは合わせておく必要があります。さて、ではmysqlとの接続をやっていきたいですね。

サーブレットからjspに値を渡す

HelloServlet.java

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		// response.getWriter().append("Served at: ").append(request.getContextPath());
		request.setAttribute("word", "this is jsp..");
		
		String view = "/WEB-INF/view/index.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(view); 
		
		dispatcher.forward(request, response);
	}
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello, Java World!</title>
</head>
<body>
	<%= request.getAttribute("word") %>
</body>
</html>

遂にここまできたか。。

servletのメリット

一度実行されたServletは、1つのスレッドとして実行環境のメモリ上に常駐しますので、2回目以降の実行においては、新たなプロセスを生成せずに、すでにあるものを実行できるため、応答速度に優れている。

なるほど。

複数のクライアントから同時にリクエストがあっても、片方を待たせることなく並行して処理を行うことができるため、やはり応答速度に優れている。

ほう。

デメリット
-> Servletに対応したインターネット・サービス・プロバイダ(ISP)がほとんどない
これは大きいね。

->Java技術者そのものの不足
これも同意