Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mvc step1 주드 미션 제출합니다 #342

Merged
merged 9 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew build sonar --info -x :study:build
run: ./gradlew clean build codeCoverageReport sonar --info -x :study:build
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,5 @@ Temporary Items

tomcat.*
tomcat.*/**

**/WEB-INF/classes/**
24 changes: 0 additions & 24 deletions app/src/main/java/com/techcourse/AppWebApplicationInitializer.java

This file was deleted.

33 changes: 16 additions & 17 deletions app/src/main/java/com/techcourse/Application.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.techcourse;

import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.stream.Stream;

public class Application {
Expand All @@ -16,22 +14,11 @@ public class Application {

public static void main(final String[] args) throws Exception {
final int port = defaultPortIfNull(args);

final var tomcat = new Tomcat();
tomcat.setConnector(createConnector(port));
final var docBase = new File("app/src/main/webapp/").getAbsolutePath();
tomcat.addWebapp("", docBase);
log.info("configuring app with basedir: {}", docBase);
final var tomcat = new TomcatStarter(port);
log.info("configuring app with basedir: {}", TomcatStarter.WEBAPP_DIR_LOCATION);

tomcat.start();
tomcat.getServer().await();
}

private static Connector createConnector(final int port) {
final var connector = new Connector();
connector.setPort(port);
connector.setProperty("bindOnInit", "false");
return connector;
stop(tomcat);
}

private static int defaultPortIfNull(final String[] args) {
Expand All @@ -40,4 +27,16 @@ private static int defaultPortIfNull(final String[] args) {
.map(Integer::parseInt)
.orElse(DEFAULT_PORT);
}

private static void stop(final TomcatStarter tomcat) {
try {
// make the application wait until we press any key.
System.in.read();
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
log.info("web server stop.");
tomcat.stop();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
package nextstep.mvc;
package com.techcourse;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import nextstep.mvc.controller.asis.Controller;
import nextstep.mvc.view.JspView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.view.JspView;

public class DispatcherServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class);

private HandlerMapping handlerMappings;
private ManualHandlerMapping manualHandlerMapping;

public void addHandlerMapping(final HandlerMapping handlerMapping) {
this.handlerMappings = handlerMapping;
public DispatcherServlet() {
}

@Override
public void init() {
this.handlerMappings.initialize();
manualHandlerMapping = new ManualHandlerMapping();
manualHandlerMapping.initialize();
}

@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
log.debug("Method : {}, Request URI : {}", request.getMethod(), request.getRequestURI());
final String requestURI = request.getRequestURI();
log.debug("Method : {}, Request URI : {}", request.getMethod(), requestURI);

try {
final var controller = (Controller) handlerMappings.getHandler(request);
final var controller = manualHandlerMapping.getHandler(requestURI);
final var viewName = controller.execute(request, response);
move(viewName, request, response);
} catch (Throwable e) {
Expand Down
33 changes: 33 additions & 0 deletions app/src/main/java/com/techcourse/DispatcherServletInitializer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.techcourse;

import jakarta.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.WebApplicationInitializer;

/**
* Base class for {@link WebApplicationInitializer}
* implementations that register a {@link DispatcherServlet} in the servlet context.
*/
public class DispatcherServletInitializer implements WebApplicationInitializer {

private static final Logger log = LoggerFactory.getLogger(DispatcherServletInitializer.class);

private static final String DEFAULT_SERVLET_NAME = "dispatcher";

@Override
public void onStartup(final ServletContext servletContext) {
final var dispatcherServlet = new DispatcherServlet();

final var registration = servletContext.addServlet(DEFAULT_SERVLET_NAME, dispatcherServlet);
if (registration == null) {
throw new IllegalStateException("Failed to register servlet with name '" + DEFAULT_SERVLET_NAME + "'. " +
"Check if there is another servlet registered under the same name.");
}

registration.setLoadOnStartup(1);
registration.addMapping("/");

log.info("Start AppWebApplication Initializer");
}
}
13 changes: 4 additions & 9 deletions app/src/main/java/com/techcourse/ManualHandlerMapping.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
package com.techcourse;

import com.techcourse.controller.*;
import jakarta.servlet.http.HttpServletRequest;
import nextstep.mvc.HandlerMapping;
import nextstep.mvc.controller.asis.Controller;
import nextstep.mvc.controller.asis.ForwardController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.asis.ForwardController;

import java.util.HashMap;
import java.util.Map;

public class ManualHandlerMapping implements HandlerMapping {
public class ManualHandlerMapping {

private static final Logger log = LoggerFactory.getLogger(ManualHandlerMapping.class);

private static final Map<String, Controller> controllers = new HashMap<>();

@Override
public void initialize() {
controllers.put("/", new ForwardController("/index.jsp"));
controllers.put("/login", new LoginController());
Expand All @@ -31,9 +28,7 @@ public void initialize() {
.forEach(path -> log.info("Path : {}, Controller : {}", path, controllers.get(path).getClass()));
}

@Override
public Controller getHandler(HttpServletRequest request) {
final String requestURI = request.getRequestURI();
public Controller getHandler(final String requestURI) {
log.debug("Request Mapping Uri : {}", requestURI);
return controllers.get(requestURI);
}
Expand Down
83 changes: 83 additions & 0 deletions app/src/main/java/com/techcourse/TomcatStarter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.techcourse;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.scan.StandardJarScanner;

import java.io.File;

public class TomcatStarter {

public static final String WEBAPP_DIR_LOCATION = "app/src/main/webapp/";

private final Tomcat tomcat;

public TomcatStarter(final int port) {
this(WEBAPP_DIR_LOCATION, port);
}

public TomcatStarter(final String webappDirLocation, final int port) {
this.tomcat = new Tomcat();
tomcat.setConnector(createConnector(port));

final var docBase = new File(webappDirLocation).getAbsolutePath();
final var context = (StandardContext) tomcat.addWebapp("", docBase);
skipJarScan(context);
skipClearReferences(context);
}

public void start() {
try {
tomcat.start();
} catch (LifecycleException e) {
throw new UncheckedServletException(e);
}
}

public void stop() {
try {
tomcat.stop();
tomcat.destroy();
} catch (LifecycleException e) {
throw new UncheckedServletException(e);
}
}

private Connector createConnector(final int port) {
final var connector = new Connector();
connector.setPort(port);
return connector;
}

private void skipJarScan(final Context context) {
final var jarScanner = (StandardJarScanner) context.getJarScanner();
jarScanner.setScanClassPath(false);
}

private void skipClearReferences(final StandardContext context) {
/**
* https://tomcat.apache.org/tomcat-10.1-doc/config/context.html
*
* setClearReferencesObjectStreamClassCaches 번역
* true인 경우 웹 응용 프로그램이 중지되면 Tomcat은 직렬화에 사용되는
* ObjectStreamClass 클래스에서 웹 응용 프로그램에 의해 로드된
* 클래스에 대한 SoftReference를 찾고 찾은 모든 SoftReference를 지웁니다.
* 이 기능은 리플렉션을 사용하여 SoftReference를 식별하므로 Java 9 이상에서
* 실행할 때 명령줄 옵션 -XaddExports:java.base/java.io=ALL-UNNAMED를 설정해야 합니다.
* 지정하지 않으면 기본값인 true가 사용됩니다.
*
* ObjectStreamClass와 관련된 메모리 누수는 Java 19 이상, Java 17.0.4 이상 및
* Java 11.0.16 이상에서 수정되었습니다.
* 수정 사항이 포함된 Java 버전에서 실행할 때 확인이 비활성화됩니다.
*
* Amazon Corretto-17.0.6은 경고 메시지가 나옴.
* 학습과 관련 없는 메시지가 나오지 않도록 관련 설정을 끈다.
*/
context.setClearReferencesObjectStreamClassCaches(false);
context.setClearReferencesRmiTargets(false);
context.setClearReferencesThreadLocals(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.techcourse;

public class UncheckedServletException extends RuntimeException {

public UncheckedServletException(Exception e) {
super(e);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.techcourse.repository.InMemoryUserRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import nextstep.mvc.controller.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -31,8 +31,7 @@ private String login(final HttpServletRequest request, final User user) {
final var session = request.getSession();
session.setAttribute(UserSession.SESSION_KEY, user);
return "redirect:/index.jsp";
} else {
return "redirect:/401.jsp";
}
return "redirect:/401.jsp";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import nextstep.mvc.controller.asis.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

public class LoginViewController implements Controller {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import nextstep.mvc.controller.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

public class LogoutController implements Controller {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.techcourse.repository.InMemoryUserRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import nextstep.mvc.controller.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

public class RegisterController implements Controller {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import nextstep.mvc.controller.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

public class RegisterViewController implements Controller {

Expand Down
27 changes: 27 additions & 0 deletions app/src/test/java/com/techcourse/domain/UserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.techcourse.domain;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class UserTest {

@Test
void 로그인_성공_테스트() {
User user = new User(1L, "gugu", "password", "[email protected]");

boolean checked = user.checkPassword("password");

assertThat(checked).isTrue();
}

@Test
void 로그인_실패_테스트() {
User user = new User(1L, "gugu", "password", "[email protected]");

boolean checked = user.checkPassword("wrong");

assertThat(checked).isFalse();
}
}
Loading