과제를 풀던 도중 문제가 발생했다. 과제의 내용은 이렇다.
- 이전에 실습한 로그인 서블릿에 init-param 을 추가하여 변경
- 서블릿 초기 정보로 web.xml 에 adminID로 "admin", adminPwd 로 "12345"를 미리 지정한다.
- adminID 는 init() 메서드에서 불러오고, adminPwd 는 doget 에서 불러와서 로그인 프로세스 진행
내가 수정한 web.xml은 아래와 같다
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
- 중략 -
<servlet>
<servlet-name>query</servlet-name>
<servlet-class>com.edu.test.QueryServlet</servlet-class>
<init-param>
<param-name>adminID</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>adminPwd</param-name>
<param-value>12345</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>query</servlet-name>
<url-pattern>/query</url-pattern>
</servlet-mapping>
- 중략 -
</web-app>
서블릿 작업을 수행하기 위해 아래와 같이 코드를 수정했다.
package com.edu.test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class QueryServlet extends HttpServlet{
String adminID; //, adminPwd;
@Override
public void init(ServletConfig config) throws ServletException {
adminID = config.getInitParameter("adminID");
//adminPwd = config.getInitParameter("adminPwd");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//req.setCharacterEncoding("UTF-8");
String reqId = req.getParameter("id");
String reqPasswd = req.getParameter("pwd");
//String adminID = this.getInitParameter("adminID");
String adminPwd = this.getInitParameter("adminPwd");
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
if(reqId.equals(adminID) && reqPasswd.equals(adminPwd)) {
out.print("로그인 성공입니다");
}
else {
out.print("로그인 실패입니다");
}
out.close();
}
}
이전에는 init()에서만 id,pw를 받거나 doGet()에서만 id, pw를 받았을 때는 문제없이 작동이 잘 되었기 때문에
각 함수의 id와 pw를 받는 부분만 주석처리하여 작동하면 간단하게 잘 될 것이다.
아래의 html에서 실행시켜보자
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="query" method="get">
ID: <input type="text" name="id"><br>
PW: <input type="password" name="pwd"><br>
<input type="submit" value="send">
</form>
</body>
</html>
???
당연히 잘 작동할 것이라고 생각했는데 오류가 발생했다.
오류를 자세히 읽어보자
Cannot invoke "javax.servlet.ServletConfig.getInitParameter(String)"
config 객체에서 가지고 있는 get 문자열 함수가 호출이 안된단다
because the return value of "javax.servlet.GenericServlet.getServletConfig()" is null
GenericServlet에서 가지고있는 객체가 없기 때문에?
서블릿의 실행 순서를 보자
최초요청시에 객체를 생성해서 init()으로 넘겨서 service()가 실행된다.
아니 그럼 config 객체가 무조건 생기는거 아냐? 근데 왜 객체가 없대?
모르겠어서 교수님께 카톡을 드렸다.
그러니까 교수님 말씀은 재정의한 init()에서 super.init(config)로 HttpServlet에 객체를 넘겨주어야 한다고 하신다.
일단은 이해가 안됐지만 스스로 좀 더 공부해보고 다시 물어보기로 했다.
오라클에서 JAVA 클래스에 대해 잘 정리해 놓았으니 읽어보기로 했다.
docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html
docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html
Init()의 역할이 뭘까?
즉, 서블릿 컨테이너가 서블릿(객체)이 서비스에 배치되어 있다는 것을 알려주기 등록하기 위한 메소드이다.
그런데 우리가 궁금해하는 요점은 @override한 init() 과 doGet()에서 각각에서는 객체의 init-Param값을 받으나 왜 섞어쓰니깐 안되냐는 것이다.
모르겠다 추후 수정
21.05.04
1. @override한 init()만을 사용할 때는 처음 객체가 @override한 init()으로 들어가서 사용된 후 메소드가 작업이 끝나면서 받아온 객체 정보가 사라지게 된다.
2. doGet()으로 사용할 때는 HttpServlet에서 init() 메소드를 사용하기 때문에 그림처처럼 순서대로 등록된다.
따라서 둘을 섞어서 쓸 때는 객체를 처음 받아오는 함수가 @override된 init()이기 때문에 위 그림처럼 객체가 순서대로 등록이 되지 않는다.
고로 super.init()에 config 객체를 넘겨서 서비스 중인 객체를 등록하면 정상 동작 된다!!
'Servlet & JSP' 카테고리의 다른 글
JSP에서 Database(MySQL) 연결이 안될 때 : JDBC 연결이 안될 때 (0) | 2021.05.14 |
---|---|
Servlet & JSP에서 Session 사용법 (0) | 2021.05.07 |
Servlet & JSP에서 Cookie 사용법 (0) | 2021.05.07 |