Skip to content

이호석 5주차 서블릿 카페(1) 학습일지

이호석 edited this page Jul 31, 2024 · 1 revision

✅ 1. Servlet의 이름을 지정하고, 하지않았을때의 차이점

  • 이름을 지정하지 않는다면 FQCN(Full Qualified Class Name)으로 이름이 설정됨

    // 이름을 지정하지 않으면
    @WebServlet("/users")
    public class SignupServlet extends HttpServlet {...}

    image

  • 이름을 지정한다면 해당 이름으로 매핑됨

    @WebServlet(value = "/users", name = "userServlet")
    public class SignupServlet extends HttpServlet {...}

    image



✅ 2. JSP 기본(내장) 객체 속성 4가지

image

톰캣을 시작하면 다음과 같은 로그를 확인할 수 있습니다.

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 이 기본적으로 선언되어있는것을 알 수 있습니다.

그리고 jstlel태그를 사용하면 자동으로 4가지 기본 내장 객체에서 값을 찾는데 다음과 같은 순서로 찾게 됩니다.

image



✅ step4: 로그인한 사용자 프로필 수정

image

  • 가능한 방법

    1. 수정 버튼을 현재 로그인한 사용자의 PK값인 id와 일치하면 보이도록 하는 방법
    2. 수정 버튼을 눌렀을때 서버에서 로그인한 사용자와 수정하려는 사용자가 일치하는지 판단하는 방법
  • 내가 생각한 단점

    1. 수정 버튼을 눌렀을때 GET /users/edit/{id}로 요청이 감, 다른 사용자의 id를 임의로 넣어서 수정 폼으로 이동할 수 있게됨
    2. 모든 버튼에 수정 버튼이 보이게 되니 사용자는 헷갈릴 수 있다고 판단됨
  • 결정

    1 + 2번의 방법을 같이 묶어서 하는편이 좋아보임 → 사용자는 어떤 버튼을 클릭해야 할지 가시적으로 보이면서, 서버 측에선 혹여나 들어오는 잘못된 요청을 막을 수 있기 때문입니다.

    image

👼 개인 활동을 기록합시다.

개인 활동 페이지

🧑‍🧑‍🧒‍🧒 그룹 활동을 기록합시다.

그룹 활동 페이지

🎤 미니 세미나

미니 세미나

🤔 기술 블로그 활동

기술 블로그 활동

📚 도서를 추천해주세요

추천 도서 목록

🎸 기타

기타 유용한 학습 링크

Clone this wiki locally