初心者向けのJSPの例チュートリアルへようこそ。前回のいくつかの投稿では、Java Servletについて多くのことを書き、読者から非常に良い反応を得ました。そのため、JSPチュートリアルの新しいシリーズを開始しました。これはシリーズの最初の投稿です。
JSPの例チュートリアル
このJSPの例チュートリアルでは、JSPの基礎、Servletに比べたJSPの利点、JSPのライフサイクル、JSPのAPIインターフェースとクラス、そしてJSPファイルをWebアプリケーションのどこに配置するかについて説明します。また、JSPのコメント、スクリプトレット、ディレクティブ、式、宣言、およびJSPの属性についても簡単に説明します。これらのトピックのいくつかは非常に重要であり、将来の投稿で詳しく説明します。
JSPチュートリアル
- JSPとは何か、なぜJSPが必要なのか
- JSPのServletに対する利点
- JSPページのライフサイクル
- JSPのライフサイクルメソッド
- EclipseとTomcatを使用したシンプルなJSPの例
- WebアプリケーションWARファイル内のJSPファイルの場所
- JSP APIのインターフェースとクラス
- JspPageインターフェース
- HttpJspPageインターフェース
- JspWriter抽象クラス
- JspContext抽象クラス
- PageContext抽象クラス
- JspFactory抽象クラス
- JspEngineInfo抽象クラス
- ErrorDataクラス
- JspExceptionクラス
- JspTagExceptionクラス
- SkipPageExceptionクラス
-
JSPとは何か、そしてなぜJSPが必要なのでしょうか?
JSP(JavaServer Pages)は、動的なJavaウェブアプリケーションを作成するためのサーバーサイド技術です。JSPは、ユーザーのビューを簡単に作成するための機能を提供するため、サーブレット技術の拡張と考えることができます。JSPページはHTMLコードから構成され、動的なコンテンツのためにJavaコードを含めるオプションがあります。ウェブアプリケーションには多くのユーザースクリーンが含まれているため、JSPはウェブアプリケーションでよく使用されます。JSPでは、JavaコードとHTMLのギャップを埋めるために、JSPタグ、式言語、カスタムタグなどの追加機能が提供されています。これにより、理解しやすく、ウェブ開発者が迅速にJSPページを開発するのに役立ちます。
-
JSPのServletに対する利点は何ですか?
- ServletからもHTMLレスポンスを生成できますが、複雑なHTMLレスポンスを書く場合、Servletで書くことは非常に手間がかかりエラーの原因になります。JSPはこのような状況で役立ち、通常のHTMLページを書き、必要な箇所にのみJavaコードを含める柔軟性を提供します。
- JSPにはタグライブラリ、式言語、カスタムタグなどの追加機能があり、ユーザービューの開発を迅速化するのに役立ちます。
- JSPページはデプロイが容易であり、変更したページをサーバーに置き換えるだけで、コンテナがデプロイを処理します。Servletの場合、プロジェクト全体を再コンパイルしてデプロイする必要があります。実際には、ServletとJSPは相互補完的な役割を果たします。Servletはサーバーサイドのコントローラーとして使用し、モデルクラスとの通信に使用し、JSPはプレゼンテーション層に使用するべきです。
-
JSPページのライフサイクル
JSPのライフサイクルはコンテナによって管理されます。通常、サーブレットコンテナを含むウェブコンテナにはJSPコンテナも含まれており、JSPページを管理します。JSPページのライフサイクルフェーズは次のとおりです。
- 翻訳 – JSPページは通常のJavaクラスのようには見えません。実際には、JSPコンテナがJSPページを解析し、対応するサーブレットのソースコードを生成するために翻訳します。JSPファイルの名前がhome.jspであれば、通常はhome_jsp.javaという名前になります。
- コンパイル – 翻訳が成功した場合、コンテナは生成されたサーブレットのソースファイルをコンパイルしてクラスファイルを生成します。
- クラスのロード – JSPがサーブレットクラスとしてコンパイルされると、そのライフサイクルはサーブレットと似ており、メモリにロードされます。
- インスタンスの作成 – JSPクラスがメモリにロードされた後、コンテナによってオブジェクトがインスタンス化されます。
- 初期化 – JSPクラスは初期化され、通常のクラスからサーブレットに変換されます。初期化後、JSPクラスはServletConfigおよびServletContextオブジェクトにアクセスできるようになります。
- リクエスト処理 – クライアントのリクエストごとに、ServletRequestとServletResponseを使用してHTMLのレスポンスを処理および生成するための新しいスレッドが生成されます。
- 破棄 – JSPのライフサイクルの最後のフェーズであり、メモリからアンロードされます。
-
JSPのライフサイクルメソッド
JSPのライフサイクルメソッドは以下のとおりです:
- jspInit()はJspPageインターフェースで宣言されています。このメソッドはJSPのライフサイクル中に一度だけ呼び出され、設定パラメータを初期化します。
- _jspService(HttpServletRequest request, HttpServletResponse response)はHttpJspPageインターフェースで宣言されており、クライアントのリクエストを処理するための応答を行います。
- jspDestroy()はJspPageインターフェースで宣言されており、JSPをメモリからアンロードします。
-
エクリプスとトムキャットを使用したシンプルなJSPの例
We can use Eclipse IDE for building dynamic web project with JSPs and use Tomcat to run it. Please read [Java Web Applications](/community/tutorials/java-web-application-tutorial-for-beginners#first-web-app-servlet) tutorial to learn how can we easily create JSPs in Eclipse and run it in tomcat. A simple JSP example page example is: `home.jsp`
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>First JSP</title>
</head>
<%@ page import="java.util.Date" %>
<body>
<h3>Hi Pankaj</h3><br>
<strong>Current Time is</strong>: <%=new Date() %>
</body>
</html>
```
If you have a simple JSP that uses only JRE classes, we are not required to put it as WAR file. Just create a directory in the tomcat webapps folder and place your JSP file in the newly created directory. For example, if your JSP is located at apache-`tomcat/webapps/test/home.jsp`, then you can access it in browser with URL `https://localhost:8080/test/home.jsp`. If your host and port is different, then you need to make changes in URL accordingly.
We can place JSP files at any location in the WAR file, however if we put it inside the WEB-INF directory, we wont be able to access it directly from client. We can configure JSP just like servlets in web.xml, for example if I have a JSP example page like below inside WEB-INF directory: `test.jsp`
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Test JSP</title>
</head>
<body>
Test JSP Page inside WEB-INF folder.<br>
Init Param "test" value =<%=config.getInitParameter("test") %><br>
HashCode of this object=<%=this.hashCode() %>
</body>
</html>
```
And I configure it in web.xml configuration as:
```
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>FirstJSP</display-name>
<servlet>
<servlet-name>Test</servlet-name>
<jsp-file>/WEB-INF/test.jsp</jsp-file>
<init-param>
<param-name>test</param-name>
<param-value>Test Value</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/Test.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Test1</servlet-name>
<jsp-file>/WEB-INF/test.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Test1</servlet-name>
<url-pattern>/Test1.do</url-pattern>
</servlet-mapping>
</web-app>
```
Then I can access it with both the URLs https://localhost:8080/FirstJSP/Test.do and https://localhost:8080/FirstJSP/Test1.do Notice that container will create two instances in this case and both will have their own servlet config objects, you can confirm this by visiting these URLs in browser. For Test.do URI, you will get response like below.
```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =Test Value
HashCode of this object=1839060256
```
For Test1.do URI, you will get response like below.
```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =null
HashCode of this object=38139054
```
Notice the init param value in second case is null because it's not defined for the second servlet, also notice the hashcode is different. If you will make further requests, the hashcode value will not change because the requests are processed by spawning a new thread by the container. Did you noticed the use of **config** variable in above JSP example but there is no variable declared, it's because its one of the 9 implicit objects available in JSP page, read more about them at [**JSP Implicit Objects**](/community/tutorials/jsp-implicit-objects "JSP Implicit Objects with Examples").
All the core JSP interfaces and classes are defined in `javax.servlet.jsp` package. Expression Language API interfaces are classes are part of `javax.servlet.jsp.el` package. JSP Tag Libraries interfaces and classes are defined in `javax.servlet.jsp.tagext` package. Here we will look into interfaces and classes of Core JSP API.
-
JspPageインターフェース
JspPageインターフェースはServletインターフェースを拡張し、JSPページのライフサイクルメソッドであるjspInit()とjspDestroy()を宣言します。
-
HttpJspPageインターフェース
HttpJspPageインターフェースは、JSPページの実装クラスがHTTPプロトコルを使用する場合に満たす必要がある相互作用を記述します。このインターフェースは、JSPページのHTTPプロトコルに対するserviceメソッドをpublic void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExceptionとして宣言します。
-
JspWriter抽象クラス
サーブレットのPrintWriterと同様に、バッファリングサポートの追加機能を持っています。これはJSPページの暗黙の変数の1つであり、名前は「out」となります。このクラスはjava.io.Writerを拡張し、コンテナはこの抽象クラスの独自の実装を提供し、JSPページをサーブレットに変換する際に使用します。PageContext.getOut()メソッドを使用してオブジェクトを取得することができます。Apache TomcatのJspWriterの具象クラスは
org.apache.jasper.runtime.JspWriterImpl
です。 -
JspContext抽象クラス
JspContextはPageContextクラスの基本クラスとして機能し、サーブレット固有の情報を抽象化します。JspContextは出力のためのJspWriterを取得するメカニズム、属性との作業のためのメカニズム、およびさまざまなスコープ名前空間を管理するためのAPIを提供します。
-
PageContextの抽象クラス
PageContextは、ウェブアプリケーションでJSPが使用される場合に有用なコンテキスト情報を提供するためにJspContextを拡張します。PageContextのインスタンスは、JSPページに関連付けられたすべての名前空間へのアクセスを提供し、複数のページ属性へのアクセス、および実装の詳細以上のレイヤーを提供します。暗黙のオブジェクトは自動的にpageContextに追加されます。
-
JspFactory抽象クラス
JspFactoryは抽象クラスであり、JSP実装をサポートするためにJSPページが実行時に使用できるさまざまなインターフェースやクラスのインスタンスを作成するためのファクトリメソッドを定義しています。
-
JspEngineInfo抽象クラス
JspEngineInfoは抽象クラスであり、現在のJSPエンジンに関する情報を提供します。
-
ErrorData finalクラス
エラーページのエラーに関する情報を含みます。
-
JspExceptionクラス
JSPコンテナによって認識される汎用の例外であり、ServletExceptionに似ています。JSPページがJspExceptionをスローする場合は、エラーページメカニズムが使用されてユーザーにエラー情報が表示されます。
-
JspTagException クラス
タグハンドラによって使用される例外で、回復不可能なエラーを示します。
-
SkipPageException クラス
評価を停止する必要がある呼び出し元のページを示す例外です。シンプルなタグハンドラによってスローされ、ページの残り部分を評価しないことを示します。この例外は JSP ページで手動でスローしないでください。
Since JSP is built on top of HTML, we can write comments in JSP file like html comments as `<-- This is HTML Comment -->` These comments are sent to the client and we can look it with view source option of browsers. We can put comments in JSP files as: `<%-- This is JSP Comment--%>` This comment is suitable for developers to provide code level comments because these are not sent in the client response.
Scriptlet tags are the easiest way to put java code in a JSP page. A scriptlet tag starts with `<%` and ends with `%>`. Any code written inside the scriptlet tags go into the `_jspService()` method. For example:
```
<%
Date d = new Date();
System.out.println("Current Date="+d);
%>
```
Since most of the times we print dynamic data in JSP page using _out.print()_ method, there is a shortcut to do this through JSP Expressions. JSP Expression starts with `<%=` and ends with `%>`. `<% out.print("Pankaj"); %>` can be written using JSP Expression as `<%= "Pankaj" %>` Notice that anything between `<%= %>` is sent as parameter to `out.print()` method. Also notice that scriptlets can contain multiple java statements and always ends with semicolon (;) but expression doesn't end with semicolon.
JSP Directives are used to give special instructions to the container while JSP page is getting translated to servlet source code. JSP directives starts with `<%@` and ends with `%>` For example, in above JSP Example, I am using _page_ directive to to instruct container JSP translator to import the Date class.
JSP Declarations are used to declare member methods and variables of servlet class. JSP Declarations starts with `<%!` and ends with `%>`. For example we can create an int variable in JSP at class level as `<%! public static int count=0; %>`
Once JSP files are translated to Servlet source code, the source code (.java) and compiled classes both are place in **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp** directory. If the JSP files are inside other directories of application, the directory structure is maintained. For JSPs inside WEB-INF directory, its source and class files are inside **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp/WEB\_002dINF** directory. Here is the source code generated for above test.jsp page. `test_jsp.java`
```
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.32
* Generated at: 2013-08-21 03:40:59 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp.WEB_002dINF;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=US-ASCII");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">\n");
out.write("<html>\n");
out.write("<head>\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">\n");
out.write("<title>Test JSP</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write("Test JSP Page inside WEB-INF folder.<br>\n");
out.write("Init Param \"test\" value =");
out.print(config.getInitParameter("test") );
out.write("<br>\n");
out.write("HashCode of this object=");
out.print(this.hashCode() );
out.write("\n");
out.write("</body>\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
```
Notice following points in above servlet code;
- The package of class starts with org.apache.jsp and if JSPs are inside other folders, it includes directory hierarchy too. Usually we dont care about it.
- The generates servlet class is final and can't be extended.
- It extends `org.apache.jasper.runtime.HttpJspBase` that is similar to HttpServlet except that it's internal to Tomcat JSP Translator implementation. HttpJspBase extends HttpServlet and implements HttpJspPage interface.
- Notice the local variables at the start of \_jspService() method implementation, they are automatically added by JSP translator and available for use in service methods, i.e in scriptlets.As a java programmer, sometimes it helps to look into the generated source for debugging purposes.
We can define init parameters for the JSP page as shown in above example and we can retrieve them in JSP using **config** implicit object, we will look into implicit objects in JSP in more detail in future posts.
We can override JSP init method for creating resources to be used by JSP service() method using JSP Declaration tags, we can override jspInit() and jspDestroy() or any other methods also. However we should never override \_jspService() method because anything we write in JSP goes into service method.
Apart from standard servlet attributes with request, session and context scope, in JSP we have another scope for attributes, i.e Page Scope that we can get from pageContext object. We will look it's importance in custom tags tutorial. For normal JSP programming, we don't need to worry about page scope.
{
“error”: “Upstream error…”
}
Source:
https://www.digitalocean.com/community/tutorials/jsp-example-tutorial-for-beginners