感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

Ajax × サーブレットのサンプルを作成。悲しいことに、500の謎のエラーが・・・

スポンサーリンク

サーブレットを作って、Tomcatを起動。
さてブラウザから見てみようとすると、こんなエラーが出た。

HTTPステータス 500 -
The server encountered an internal error () that prevented it from fulfilling this request.
javax.servlet.ServletException: サーブレット default のServlet.init()が例外を投げました
	org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
	org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	java.lang.Thread.run(Thread.java:662)
java.lang.ClassCastException: org.apache.naming.resources.ProxyDirContext cannot be cast to org.apache.naming.resources.ProxyDirContext
	org.apache.catalina.servlets.DefaultServlet.init(DefaultServlet.java:305)
	javax.servlet.GenericServlet.init(GenericServlet.java:212)
	org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
	org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	java.lang.Thread.run(Thread.java:662)

どうやらこれは、WEB-INF以下のlibにjarファイルが含まれていたことが原因だった。
内部で競合するらしい。
libファイルごと削除したら見えるようになった。
libファイルを消して、Tomcatを再起動。同じエラーは起きなくなった。
JSPを見ようとして同じようなエラーに遭遇する人がいるみたいですね。
参考にしたのは以下のサイト。
http://tunes.sakura.ne.jp/tipi/?Tomcat%2F%A5%A8%A5%E9%A1%BC%2Fjar%20not%20loaded.%20See%20Servlet%20Spec%202.3%2C%20section%209.7.2.%20Offending%20classhttps://issues.apache.org/bugzilla/show_bug.cgi?id=45785

というか、最近めっきりエラーの原因を探すのに英語サイトが参考になることが多いです。
日本語の掲示板的なところだと、経験者が初心者を見下す割に、ろくな情報も置いていないし、見ててムカつくので検索でヒットしてもほとんど見ません。
エラーの原因を探す時は英語でググった方が絶対いい。間違いなく。

で、Ajax & Javaを読みながら、AjaxサーブレットにHTTPを投げて、レスポンスを表示しようとここ数日もがいてやっとできた。
超簡単なサンプルなのに、Eclipseとか使わずにやると環境設定で苦労しますね。
ただ、本に書いてあるサンプルに微妙に罠があったので、ちょっと直して実行。
うまくいったときは感動した。

本の丸コピーではないので、軽くソースを載せる。

var req;

function convertToDecimal() {
	var key = document.getElementById("key");
	var keypressed = document.getElementById("keypressed");
	keypressed.value = key.value;
	//ここ本だとちょっと違うから注意。
	var url = "/ch03-CharacterDecoder/response?key=" + escape(key.value);
	if (window.XMLHttpRequest) {
		req = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		req = new ActiveXObject("Microsoft.XMLHTTP");
	}
	req.open("Get", url, true);
	req.onreadystatechange = callback;
	req.send(null);
}

function callback() {
	if (req.readyState == 4) {
		if (req.status == 200) {
			var decimal = document.getElementById('decimal');
			decimal.value = req.responseText;
		}
	}
	clear();
}

function clear() {
	var key = document.getElementById("key");
	key.value="";
}

function focusIn() {
	document.getElementById("key").focus();
}

index.html

<html>
<head>
	<link rel="stylesheet" type="text/css" href="style.css">
	<script language="JavaScript" src="ajax.js"></script>
	<title>Ajax On Java </title>
</head>
<body onload="focusIn();">
	<h1> AJAX CHARACTER DECODER </h1>
	<h2> Press a key to find its value. </h2>
	<table>
		<tr>
			<td>
				なにか入力してください ->
				<input type="text" id="key" name="key"
					onkeyup="convertToDecimal();">
			</td>
		</tr>
	</table>
	<br />
	<table>
		<tr>
			<td colspan="5" style="border-bottom:solid black 1px;"
				Key Pressed:
				<input type="text" readonly id="keypressed">
			</td>
		</tr>
		<tr>
			<td> Decimal </td>
		<tr>
			<td><input type="text" readyonly id="decimal"></td>
		</tr>
	</table>
</body>
</html>
package com.oreilly.ajax.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AjaxResponseServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest req, HttpServletResponse res)
						throws ServletException, IOException {

		String key = req.getParameter("key");
		if (key != null) {
			int keychar = key.charAt(0);
			String decimalString = Integer.toString(keychar);
			res.setContentType("text/xml");
			res.setHeader("Cache-Control", "no-cache");
			res.getWriter().write(decimalString);
		} else {
			res.setContentType("text/xml");
			res.setHeader("Cache-Control", "no-cache");
			res.getWriter().write("?");
		}
	}
}

読んだ本

Ajax&JavaーJavaプログラマのためのAjaxプライマー

Ajax&JavaーJavaプログラマのためのAjaxプライマー


Ajaxの基礎を学んで、次にWebアプリを作ろうとするときに読む本だと思う。

感謝のプログラミング

今回で感謝のプログラミングは【268時間目】
10000時間まで、あと【9732時間】