-
Notifications
You must be signed in to change notification settings - Fork 0
이호석 5주차 서블릿 카페(1) 학습일지
이호석 edited this page Jul 31, 2024
·
1 revision
-
이름을 지정하지 않는다면
FQCN(Full Qualified Class Name)
으로 이름이 설정됨// 이름을 지정하지 않으면 @WebServlet("/users") public class SignupServlet extends HttpServlet {...}
-
이름을 지정한다면 해당 이름으로 매핑됨
@WebServlet(value = "/users", name = "userServlet") public class SignupServlet extends HttpServlet {...}
톰캣을 시작하면 다음과 같은 로그를 확인할 수 있습니다.
23-Jul-2024 17:13:02.075 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /Users/woowatech20/Library/Caches/JetBrains/IntelliJIdea2024.1/tomcat/6d395365-0190-46ab-ae15-c6a64c9c4cc1
위 경로는 톰캣이 컴파일한 파일들을 저장하는 공간인데 여기에서 jsp가 컴파일된 결과를 확인할 수 있습니다. 정확한 경로는 다음과 같습니다.
/Users/woowatech20/Library/Caches/JetBrains/IntelliJIdea2024.1/tomcat/6d395365-0190-46ab-ae15-c6a64c9c4cc1/work/Catalina/localhost/ROOT/org/apache/jsp/WEB_002dINF/views
랜덤값/work/Catalina/하위 폴더는 실제 jsp가 로딩됐을때 생성됩니다. index.jsp → index_jsp.java로 변경되는데 실제 파일을 열어보면 다음과 같습니다.
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/10.1.26
* Generated at: 2024-07-23 08:54:23 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.views;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports,
org.apache.jasper.runtime.JspSourceDirectives {
private static final jakarta.servlet.jsp.JspFactory _jspxFactory =
jakarta.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.LinkedHashSet<>(4);
_jspx_imports_packages.add("jakarta.servlet");
_jspx_imports_packages.add("jakarta.servlet.http");
_jspx_imports_packages.add("jakarta.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile jakarta.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public boolean getErrorOnELNotFound() {
return false;
}
public jakarta.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
throws java.io.IOException, jakarta.servlet.ServletException {
if (!jakarta.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET, POST or HEAD. Jasper also permits OPTIONS");
return;
}
}
final jakarta.servlet.jsp.PageContext pageContext;
jakarta.servlet.http.HttpSession session = null;
final jakarta.servlet.ServletContext application;
final jakarta.servlet.ServletConfig config;
jakarta.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
jakarta.servlet.jsp.JspWriter _jspx_out = null;
jakarta.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=UTF-8");
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>\n");
out.write("<html lang=\"kr\">\n");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "snippet/meta-header.jsp", out, false);
out.write("\n");
out.write("\n");
out.write("<body>\n");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "snippet/navigation.jsp", out, false);
out.write('\n');
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "snippet/header.jsp", out, false);
out.write("\n");
out.write("\n");
out.write("<div class=\"container\" id=\"main\">\n");
out.write(" <div class=\"col-md-12 col-sm-12 col-lg-10 col-lg-offset-1\">\n");
out.write(" <div class=\"panel panel-default qna-list\">\n");
out.write(" <ul class=\"list\">\n");
out.write(" <li>\n");
out.write(" <div class=\"wrap\">\n");
out.write(" <div class=\"main\">\n");
out.write(" <strong class=\"subject\">\n");
out.write(" <a href=\"../../qna/show.jsp\">국내에서 Ruby on Rails와 Play가 활성화되기 힘든 이유는 뭘까?</a>\n");
out.write(" </strong>\n");
out.write(" <div class=\"auth-info\">\n");
out.write(" <i class=\"icon-add-comment\"></i>\n");
out.write(" <span class=\"time\">2016-01-15 18:47</span>\n");
out.write(" <a href=\"user/profile.jsp\" class=\"author\">자바지기</a>\n");
out.write(" </div>\n");
out.write(" <div class=\"reply\" title=\"댓글\">\n");
out.write(" <i class=\"icon-reply\"></i>\n");
out.write(" <span class=\"point\">8</span>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </li>\n");
out.write(" <li>\n");
out.write(" <div class=\"wrap\">\n");
out.write(" <div class=\"main\">\n");
out.write(" <strong class=\"subject\">\n");
out.write(" <a href=\"../../qna/show.jsp\">runtime 에 reflect 발동 주체 객체가 뭔지 알 방법이 있을까요?</a>\n");
out.write(" </strong>\n");
out.write(" <div class=\"auth-info\">\n");
out.write(" <i class=\"icon-add-comment\"></i>\n");
out.write(" <span class=\"time\">2016-01-05 18:47</span>\n");
out.write(" <a href=\"user/profile.jsp\" class=\"author\">김문수</a>\n");
out.write(" </div>\n");
out.write(" <div class=\"reply\" title=\"댓글\">\n");
out.write(" <i class=\"icon-reply\"></i>\n");
out.write(" <span class=\"point\">12</span>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </li>\n");
out.write(" </ul>\n");
out.write(" <div class=\"row\">\n");
out.write(" <div class=\"col-md-3\"></div>\n");
out.write(" <div class=\"col-md-6 text-center\">\n");
out.write(" <ul class=\"pagination center-block\" style=\"display:inline-block;\">\n");
out.write(" <li><a href=\"#\">«</a></li>\n");
out.write(" <li><a href=\"#\">1</a></li>\n");
out.write(" <li><a href=\"#\">2</a></li>\n");
out.write(" <li><a href=\"#\">3</a></li>\n");
out.write(" <li><a href=\"#\">4</a></li>\n");
out.write(" <li><a href=\"#\">5</a></li>\n");
out.write(" <li><a href=\"#\">»</a></li>\n");
out.write(" </ul>\n");
out.write(" </div>\n");
out.write(" <div class=\"col-md-3 qna-write\">\n");
out.write(" <a href=\"../../qna/form.jsp\" class=\"btn btn-primary pull-right\" role=\"button\">질문하기</a>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write("</div>\n");
out.write("\n");
out.write("<!--login modal-->\n");
out.write("<!--\n");
out.write("<div id=\"loginModal\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">\n");
out.write(" <div class=\"modal-dialog\">\n");
out.write(" <div class=\"modal-content\">\n");
out.write(" <div class=\"modal-header\">\n");
out.write(" <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n");
out.write(" <h2 class=\"text-center\"><img src=\"https://lh5.googleusercontent.com/-b0-k99FZlyE/AAAAAAAAAAI/AAAAAAAAAAA/eu7opA4byxI/photo.jpg?sz=100\" class=\"img-circle\"><br>Login</h2>\n");
out.write(" </div>\n");
out.write(" <div class=\"modal-body\">\n");
out.write(" <form class=\"form col-md-12 center-block\">\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <label for=\"userId\">사용자 아이디</label>\n");
out.write(" <input class=\"form-control\" name=\"userId\" placeholder=\"User ID\">\n");
out.write(" </div>\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <label for=\"password\">비밀번호</label>\n");
out.write(" <input type=\"password\" class=\"form-control\" name=\"password\" placeholder=\"Password\">\n");
out.write(" </div>\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <button class=\"btn btn-primary btn-lg btn-block\">로그인</button>\n");
out.write(" <span class=\"pull-right\"><a href=\"#registerModal\" role=\"button\" data-toggle=\"modal\">회원가입</a></span>\n");
out.write(" </div>\n");
out.write(" </form>\n");
out.write(" </div>\n");
out.write(" <div class=\"modal-footer\">\n");
out.write(" <div class=\"col-md-12\">\n");
out.write(" <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">Cancel</button>\n");
out.write(" </div> \n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write("</div>\n");
out.write("-->\n");
out.write("\n");
out.write("<!--register modal-->\n");
out.write("<!--\n");
out.write("<div id=\"registerModal\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">\n");
out.write(" <div class=\"modal-dialog\">\n");
out.write(" <div class=\"modal-content\">\n");
out.write(" <div class=\"modal-header\">\n");
out.write(" <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n");
out.write(" <h2 class=\"text-center\"><img src=\"https://lh5.googleusercontent.com/-b0-k99FZlyE/AAAAAAAAAAI/AAAAAAAAAAA/eu7opA4byxI/photo.jpg?sz=100\" class=\"img-circle\"><br>회원가입</h2>\n");
out.write(" </div>\n");
out.write(" <div class=\"modal-body\">\n");
out.write(" <form class=\"form col-md-12 center-block\">\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <label for=\"userId\">사용자 아이디</label>\n");
out.write(" <input class=\"form-control\" id=\"userId\" name=\"userId\" placeholder=\"User ID\">\n");
out.write(" </div>\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <label for=\"password\">비밀번호</label>\n");
out.write(" <input type=\"password\" class=\"form-control\" id=\"password\" name=\"password\" placeholder=\"Password\">\n");
out.write(" </div>\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <label for=\"name\">이름</label>\n");
out.write(" <input class=\"form-control\" id=\"name\" name=\"name\" placeholder=\"Name\">\n");
out.write(" </div>\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <label for=\"email\">이메일</label>\n");
out.write(" <input type=\"email\" class=\"form-control\" id=\"email\" name=\"email\" placeholder=\"Email\">\n");
out.write(" </div>\n");
out.write(" <div class=\"form-group\">\n");
out.write(" <button class=\"btn btn-primary btn-lg btn-block\">회원가입</button>\n");
out.write(" </div>\n");
out.write(" </form>\n");
out.write(" </div>\n");
out.write(" <div class=\"modal-footer\">\n");
out.write(" <div class=\"col-md-12\">\n");
out.write(" <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">Cancel</button>\n");
out.write(" </div> \n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write(" </div>\n");
out.write("</div>\n");
out.write("-->\n");
out.write("\n");
out.write("<!-- script references -->\n");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "snippet/script.jsp", out, false);
out.write("\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof jakarta.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
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);
}
}
}
위 _jspService를 살펴보면, pageContext
, request
, session
, application
이 기본적으로 선언되어있는것을 알 수 있습니다.
그리고 jstl
의 el
태그를 사용하면 자동으로 4가지 기본 내장 객체에서 값을 찾는데 다음과 같은 순서로 찾게 됩니다.
-
가능한 방법
- 수정 버튼을 현재 로그인한 사용자의 PK값인 id와 일치하면 보이도록 하는 방법
- 수정 버튼을 눌렀을때 서버에서 로그인한 사용자와 수정하려는 사용자가 일치하는지 판단하는 방법
-
내가 생각한 단점
- 수정 버튼을 눌렀을때
GET /users/edit/{id}
로 요청이 감, 다른 사용자의 id를 임의로 넣어서 수정 폼으로 이동할 수 있게됨 - 모든 버튼에 수정 버튼이 보이게 되니 사용자는 헷갈릴 수 있다고 판단됨
- 수정 버튼을 눌렀을때
-
결정
1 + 2번의 방법을 같이 묶어서 하는편이 좋아보임 → 사용자는 어떤 버튼을 클릭해야 할지 가시적으로 보이면서, 서버 측에선 혹여나 들어오는 잘못된 요청을 막을 수 있기 때문입니다.