Servlet
Servletの特徴:Singleton且つMultithread
スレッドセーフではないため、インスタンス変数が使用禁止
処理順番
Listener → Filter → Wrapper → Servlet
Servletクラス関係図
Servletのライフサイクル
Servletサンプル
WEB-INF/web.xml
<servlet>
<description>This is demo.</description>
<description-name>DEMO</description-name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.test.servlet.MyServlet</servlet-class>
<load-on-startup>0</load-on-startup> <!-- 0:優先級最大 -->
<init-param>
<param-name>param1</param-name>
<param-value>abc</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
import javax.sql.DataSource;
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private DataSource testDS;
private ServletContext context;
private ServletConfig config;
public MyServlet() {
super();
}
public void init() throws ServletException {
System.out.println("Init");
}
public void init(ServletConfig config) throws ServletException {
this.config = config;
context = config.getServletContext();
super.init(config);
context.log(new Date().toString() + ":起動");
version = getInitParameter("version"); // 初期値取得
Context ctx = null;
try {
//★JNDIをキャッシュする
ctx = new InitialContext();
testDS = (DataSource)ctx.lookup("jdbc/testDS");
}
catch(NamingException ne) {
ne.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void destroy() {
context.log(new Date().toString() + ":停止");
super.destroy();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = getServletContext();
String xxx = context.getInitParameter("xxx"); // <context-param>で定義
// 初期値をすべて取得
Enumeration<String> inits = request.getInitParameterNames();
while(inits.hasMoreElements()) {
name = (String) enumeration.nextElement();
value = config.getInitParameter(name);
...
}
response.setContentType("text/html;charset=UTF-8");
// InputStream in = request.getInputStream(); // JSON文字列を取得
// ObjectInputStream objInStream = new ObjectInputStream(in);
// Object obj = objInStream.readObject();
...
String name = request.getParameter("name");
// チェックボックス・複数選択リストボックス
String[] names = request.getParameterValues("names");
HttpSession session = request.getSession();
session.setAttribute("name",name);
request.setAttribute("name", name);
//↓★アウトプットを圧縮する
OutputStream out = null;
String encoding = request.getHeader("Accept-Encoding");
if (encoding != null && encoding.indexOf("gzip") != -1) {
response.setHeader("Content-Encoding" , "gzip");
out = new GZIPOutputStream(response.getOutputStream());
} else if (encoding != null && encoding.indexOf("compress") != -1) {
response.setHeader("Content-Encoding" , "compress");
out = new ZIPOutputStream(response.getOutputStream());
} else {
out = response.getOutputStream();
}
//↑★アウトプットを圧縮する
request.getRequestDispatcher("show.jsp").forward(request, response);
return;
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public DataSource getTestDS() {
return testDS;
}
}
・RequestのServletInputStream getInputStream() 二進数データ ファイル保存
・RequestのBufferedReader getReader() 文字列データ 文字処理
★Servlet3.0の新機能
>新規Annotation
@WebServlet 非同期モードあり
@WebFilter(filterName="",urlPattern={"/"});
@WebListener
@WebInitParam
@MultipartConfig ファイルアップロード
@ServletSecurity ユーザ認証
name <servlet-name>
urlPatterns <url-pattern>,
loadOnStartup <load-on-startup>
initParam <init-param>
name <param-name>
value <param-value>
>web-fragment.xml web.xmlを複数に分割
>動的アプリケーション拡張 getServletRegistrationなど
>JSPモジュール化(jarファイル化)
★ServletOutputStream とPrintWriter
・ServletOutputStream 二進数
・PrintWriter 文字ストリームなので、変換が必要のため、効率が悪い
request.getRequestDispatcher("/header.html").include(request, response);
response.getOutputStream().println("<h1>XXX</h1>");
request.getRequestDispatcher("/footer.html").include(request, response);
★ステータスコードについて
response.sendError("503"); ×
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); 〇 定数を使うこと
★ServletConfigとServletContext
ServletConfig 各々Servletに対して
<servlet>
...
<init-param>
<param-name>name</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
ServletConfig config = getServletConfig(); // GenericServletから
String value = config.getInitParameter("name"); // 複数:getInitParameterNames
ServletContext すべてServletに対して
<context-param>
<param-name>name</param-name>
<param-value>XXX</param-value>
</context-param>
ServletContext context = getServletConfig().getServletContext();
或いは
ServletContext context = getServletContext();
String value = context.getInitParameter("name"); // 複数:getInitParameterNames
サンプル
@Override
public void init() throws ServletException {
ServletContext context = getServletContext();
context.setAttribute("times", 0);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = getServletContext();
int times = (Integer) context.getAttribute("times");
times++;
context.setAttribute("times", times);
}
★HttpServletRequestについて
request.getRemoteAddr();
request.getRemoteHost();
request.getQueryString()
request.getContextPath()
request.getMethod()
request.getRequestURL() // http://localhost:8080/project/xxx
request.getRequestURI() // /project/xxx
request.getRequestURI().substring(request.getContextPath().length()) // /xxx
Enumeration<String> enumeration = request.getHeaderNames();
while(enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String value = request.getHeader(name);
...
}
request.getHeader("user-agent"); // ブラウザ情報
Enumeration<String> langs = request.getHeaders("accept-language"); // 複数の値
while(langs.hasMoreElements()) {
String lang = langs.nextElement();
...
}
パラメータ取得
String username = request.getParameter("username");
// Checkbox
String[] hobbies = request.getParameterValues("hobby");
System.out.println( Arrays.toString(hobbies) );
//方法1
Enumeration<String> names = request.getParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
System.out.println(name + ":"
+ Arrays.toString(request.getParameterValues(name)));
}
//方法2
Map<String, String[]> paramterMap = request.getParameterMap();
Set<String> keys = paramterMap.keySet();
for(String key : keys){
System.out.println(key + ":" + Arrays.toString(paramterMap.get(key)));
}
★HttpServletRequestWrapper & HttpServletResponseWrapper
★Dynamic Servlet/Filter Registration
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
// Register Servlet
ServletRegistration sr = sc.addServlet("DynamicServlet",
"com.sample.DynamicServlet");
sr.setInitParameter("xxx", "yyy");
sr.addMapping("/dynamic");
// Register Filter
FilterRegistration fr = sc.addFilter("DynamicFilter",
"com.sample.DynamicFilter");
fr.setInitParameter("xxx", "yyy");
fr.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),
true, "DynamicServlet");
}
}