Spring Boot

스프링 내장 톰캣 연결방법 및 서블릿

해달's code 2024. 12. 1. 00:06

Dependency

// embedded tomcat
    implementation 'org.apache.tomcat.embed:tomcat-embed-core:8.5.42'
    implementation 'org.apache.tomcat.embed:tomcat-embed-jasper:8.5.42'

 

톰캣 포트연결

public class WebApplicationServerLauncher {

	//log명령어 사용
    private static final Logger logger = LoggerFactory.getLogger(WebApplicationServerLauncher.class);

    public static void main(String[] args) throws Exception {
        // 내장 톰캣
        String webappDirLocation = "webapp/";
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);

        tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
        logger.info("configuring app with basedir: {}", new File("./" + webappDirLocation).getAbsolutePath());

//        // 컨텍스트 생성
//        Context ctx = tomcat.addContext("/", new File(webappDirLocation).getAbsolutePath());
//        logger.info("Configuring app with basedir: {}", new File(webappDirLocation).getAbsolutePath());
//
//        // 서블릿 명시적 등록
//        Tomcat.addServlet(ctx, "calculatorServlet", new CalculatorServlet());
//        ctx.addServletMappingDecoded("/calculate", "calculatorServlet");

        tomcat.start();
        tomcat.getServer().await();
    }
}
private static final Logger logger = LoggerFactory.getLogger(WebApplicationServerLauncher.class);

해당부분에서 LoggerFactory 싱글톤 패턴으로 .class의 이름을 가진 Logger 객체를 반환하게 하는 역할이다.

결과창에 WebApplicationServerLauncher - 로그매세지~~~ 형식으로 출력된다.

 

addwebapp : 톰캣에 웹 애플리케이션 등록하는 명령어 무조건 절대경로를 줘야 톰캣이 인식함

addwebapp(context path, 톰캣 디렉터리 절대 경로);

addwebapp을 사용하지 않을시 주석처리된 부분으로 서블릿을 명시 해줘야  사용가능하다 아니면 .xml파일 작성

 

첫번째 매개변수

context path를 "/"로 설정시 루트값 기본인 http://localhost:8080로 접근

"/app"과 같이 설정을 해주었다면 http://localhost:8080/app으로 접근해야함

두번째 매개변수

new File(webappDirLocation)은 "webapp/" 디렉토리를 File 객체로 만들고, .getAbsolutePath()는 이 디렉토리의 절대 경로를 반환합니다.

ex) 현재 작업 디렉토리가 /home/user/project라면, 결과는 "/home/user/project/webapp".

 

 

로그 메시지 템플릿에서 {}은 new File("./" + webappDirLocation).getAbsolutePath()의 결과로 대체됩니다.

"./"는 현재 작업 디렉토리를 나타냅니다.

 

 

 

오류 1가지

문제상황 : .addwebapp 명령어가 작동하지 않음 404 에러 발생

문제원인 예상

1.톰캣이 표준 디렉터리 구조를 따르는데 현재 webapp/WEB-INF/classes 파일 경로가 존재하지 않음

2.서블릿이 3.0 이상부터 @WebServlet 어노테이션을 사용가능함

3.어노테이션을 사용하지 않을 시 webapp/WEB-INF/ Web.xml 이라는 서블릿 설정파일을 따름

 

Web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">
    <servlet>
        <servlet-name>CalculatorServlet</servlet-name>
        <servlet-class>org.example.CalculatorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CalculatorServlet</servlet-name>
        <url-pattern>/calculate</url-pattern>
    </servlet-mapping>
</web-app>

 

문제해결 : webapp/WEB-INF/classes해당 디렉토리를 직접 생성해준 뒤 프로젝트 구조에서 모듈-경로-출력경로를 해당 디렉터리 경로로 지정 후 작동

기존 경로인 out 경로로 갑자기 바뀌는 경우가 생김 무조건 출력경로를 매번 바꿔줘야함

 

톰캣 기본 디렉터리 경로

src/
└── main/
    ├── java/               # Java 소스 파일
    │   └── org/example/    # 패키지
    │       └── CalculatorServlet.java
    ├── resources/          # 리소스 파일
    ├── webapp/             # 웹 애플리케이션 디렉토리>디렉토리 이름은 변경 가능
    │   ├── WEB-INF/
    │   │   ├── web.xml     # 서블릿 설정 파일
    │   │   ├── classes/    # 컴파일된 클래스 파일
    │   │   └── lib/        # 외부 JAR 라이브러리(JAR 파일)
    │   ├── index.html      # 정적 HTML파일
    |	├── css/            # 정적 CSS 파일
    |	└── js/             # 정적 JavaScript 파일

 

서블릿 파일 구현 CalculatorServlet 파일

@WebServlet("/calculate")
public class CalculatorServlet implements Servlet {
    private static final Logger log = LoggerFactory.getLogger(CalculatorServlet.class);
    private ServletConfig servletConfig;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        log.info("init");
        this.servletConfig = servletConfig;

    }

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        log.info("service");
        int operand1 = Integer.parseInt(request.getParameter("operand1"));
        String operator = request.getParameter("operator");
        int operand2 = Integer.parseInt(request.getParameter("operand2"));

        int result = Calculator.calculate(new PositiveNumber(operand1), operator, new PositiveNumber(operand2));

        PrintWriter writer = response.getWriter();
        writer.println(result);
    }

    @Override
    public ServletConfig getServletConfig() {
        return this.servletConfig;
    }

    @Override
    public String getServletInfo() {
        return "";
    }

    @Override
    public void destroy() {

    }
}