MVC 프로젝트

Walter Mitty·2023년 1월 31일
0
post-custom-banner


  • 디렉토리는 변함없지만 보기 편하게 src/main/java처럼 /resource로 볼 수 있다.

스프링과 관련없는 파일들 옮기기

  • 마이바티스와 관련된 설정파일 resources에 넣어준다.
  • log4j 파일들도!
    • 섞여있는게 싫다면 나눠도 된다.

스프링과 관련된 설정파일들

  • 요즘은 xml을 쓰지 않으니, java class로 설정해보자.
  • xml쓸 수도 있으니 xml 먼저해보자..
  • web.xml도 WEB-INF에 만들어주자
    • 아래는 기본 코드
<?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">

필요한 라이브러리

  • pom.xml에 넣어주기
    스프링 컨텍스트
    롬복
    잭슨
    .
    .
    .
    .
<dependencies>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.2.22.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.24</version>
			<scope>provided</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.14.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc11 -->
		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc11</artifactId>
			<version>21.7.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.2.22.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
		<dependency>
			<groupId>com.zaxxer</groupId>
			<artifactId>HikariCP</artifactId>
			<version>5.0.1</version>
		</dependency>
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.6.6</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>1.6.6</version>
			<!-- <scope>runtime</scope> -->
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.6.6</version>
			<!-- <scope>runtime</scope> -->
		</dependency>
		<!-- SQL구문이 log로 출력 : DriverSpy클래스  -->
		<dependency>
			<groupId>org.bgee.log4jdbc-log4j2</groupId>
			<artifactId>log4jdbc-log4j2-jdbc4</artifactId>
			<version>1.16</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis</artifactId>
		    <version>3.5.11</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis-spring</artifactId>
		    <version>2.0.6</version>
		</dependency>
	</dependencies>

  • 톰캣 이후!
    원래 ContainerTest 클래스를 만들어 테스트소스를 적어 그걸로 실행했는데,
    DispatcherServlet을 선언하면서 스프링 컨테이너를 자동으로 구동해준다.

    이 작업을 대신 해주는 거라고 생각할 수 있다!

/mvc/a 요청이 들어오면

url-pattern을 보고 selvlet 이름을 찾고, 그 이름과 매핑되어있는 클래스를 찾는다 = DispatcherServlet

  • DispatcherServlet 타입의 객체가 있는지 확인해서 있으면 사용, 없으면 만들러간다.
    • 만들러 갈 때 init-param으로 등록한 param의 xml을 읽어서 필요한 객체를 만든다.
  • 최초의 요청이 들어왔을 때(톰캣이 시작 됐을 때) 객체의 여부를 확인하게된다.
    • 요청한 사용자 입장에서는 응답결과가 늦을 수 있다.
      • 최초 요청 전에 만들어주자! <load-on-startup> max값이 1이고, 톰캣서버가 켜지자마자 DispatcherServlet타입의 객체를 미리 만들어 두겠다. 라는 뜻이다.

  • Initializing이 되고, HikariPool도 잘 생성되는지 봐야한다.
    • 즉, DispatcherServlet 클래스를 잘 찾아가는지, 설정 xml파일은 잘 찾아가는지 확인 해야한다.
  • DispatcherServlet은 스프링프레임워크가 지원해준다.

--

스프링컨테이너가 하던 역할

  • DB와 어떻게 연결
  • Service와 Repo의 연결
    .
    .
    .
    여기서 Controller도 추가해줘야 한다!

매번 myApplicationContext에서 커넥션 풀 만들고~ 이러기엔 너무 무거우니까,
mySerlvetContext를 만들어서

--

Component 계열의 어노테이션의 특징: 컴포넌트 스캔을 위해 사용됨 = 스프링 빈으로 관리됨
@Controller

  • 톰캣을 구동하면 잘 찾아가는 걸 볼 수 있다


  • 컨트롤러 코드가 굉장히 간결해진 걸 볼 수 있다.
    • 컨트롤러 메서드가 유연해짐
      (그 전에는 메서드 이름이 execute, 반환타입은 String이었음!)

@ResponseBody가 없다면?
a...을 찾아!

  • Circular view path [a....]: would dispatch back to the current handler URL [/mvc/a....] again.
  • Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.): @ResponseBody는 뷰와 관련이 있구나!
    여기서 뷰어는 jsp같은 걸 말한다.

  • a.jsp를 만들고
  • 메서드 반환타입이 String이고 이동될 jsp 이름을 적어주면 그 jsp 페이지로 이동이 되는 것이다.
    • 포스트맨에서 쿼리를 날리면 a.jsp 내용이 반환되는 것을 확인할 수 있다.

  • 반환타입이 void 임에도 계속 c를 찾고있다.
    • 알아서 자동으로 /mvc/c를 찾는다.
    • ditpatcher되고 있다.
  • 에러 고치기! view resolver를 셋업하라고? ㅇㅋ.
<bean id="viewResolver"
 class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 		<property name="prefix" value="/WEB-INF/views/"></property>
 		<property name="suffix" value=".jsp"></property>
 	</bean>
  • prefix: 접두어
  • suffix: 접미어

  • c.jsp를 만들고 요청을 보내면, 반환타입이 없어도 위와 같이 c.jsp 내용이 나오는걸 알 수 있다. 따라서 c.jsp페이지로 이동한다고 생각하면 된다.

  • Postman에서 d url을 요청해보면, a.jsp 내용이 담기고 콘솔에는 입력한 파라미터 값이 잘 담기는 걸 볼 수 있다.
  • 에러가 나면 아래처럼 라이브러리가 잘 있는지 확인해본다

  • 요청시에 파라미터로, 아니면 타입이 정해진 변수로 보내도 무방!

  • 요청전달 데이터는 a이지만 파라미터 이름은 "one"이다. @RequestParam이 매핑을 해준다.
  • "one"은 전달하지 않고 "two"만 전달해보면 400 응답 결과를 볼 수 있다.
  • 콘솔에선 WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'one' is not present]
    • "one"이라는 요청 파라미터가 필수이다.
    • 만약 필수가 아니라는걸 알려주면 어떨까?
      • @RequestParam(name = "one", required = false) 를 해주면 된다! 그럼 "one"은 기본값인 null이 나온다.
      • 그럼 만약 기본값이 null이 아니길 바란다면?
        • @RequestParam(name = "one", required = false, defaultValue = "hi") 처럼 defaultValue 를 설정해주면 된다.

  • 옛날에는 String 타입으로만 반환이 되어서 형변환이 필요했는데 이젠 스프링 컨트롤러에서 알아서 컨버트 해준다.
    • 만약 num값을 안넘겨주면 오류가 난다.
    • 따라서 defalutValue를 선언해준다.
      • defalutValue를 줄 때는 String 타입으로 해야한다.
      • 0으로 잘 나온다.

  • 파라미터 개수가 너무 많으면 아예 Vo타입으로도 가능하다.
    • Customer 타입의 객체를 만들어주는건 Handler Adapter이다.
    • 아무것도 전달하지 않는다면?
      • 객체는 만들어지지만 값은 담기지 않는다.

  • String 배열 잘 되는 걸 볼 수 있다.
    • List라면 어떨까?
      • List도 OK!

  • /mvc/a를 요청했을 때 DispatcherServlet이 일단 요청을 받음
  • 요청을 처리해줄 HandlerMapping에게 request를 넘기고 DispatcherServlet은 제어만 한다.
  • HandlerMapping은 해당 url에 맞는 요청용 컨트롤러인 Controller를 찾아서 요철을 처리해줄 메서드까지 찾아낸다.
  • 컨트롤러를 어떤걸, 메서드는 어떤걸 쓸지 찾아내서 DispatcherServlet로 보낸다.
  • DispatcherServlet은 Handler Adapter를 통해 컨트롤러의 메서드를 호출한다.
  • 리턴타입에 맞게 처리를 하는데, Stirng a() / return "a"라면 view name인 "a"를 가지고 DispatcherServlet에 반환
  • DispatcherServlet은 또 View Resolver의 도움을 받아서 view이름을 찾아낸다. 예) a.jsp
  • DispatcherServlet은 forwarding 방식으로 view로 이동을 하게된다.

mvc/f 가들어오면

    1. /mvc/f를 요청했을 때 DispatcherServlet이 일단 요청을 받음
  • 요청을 처리해줄 HandlerMapping에게 request를 넘기고 DispatcherServlet은 제어만 한다.
  • HandlerMapping은 해당 url에 맞는 요청용 컨트롤러인 Controller를 찾아서 요철을 처리해줄 메서드까지 찾아낸다.
    1. 컨트롤러에서 요구되는 파라미터는 (String a, String b)이지만, 요청 전달 데이터는 "one" , "two"이다.
    • 파라미터와 요청 전달 데이터 이름이 다름
      • @RequestParam을 붙여 매핑이 되게 만든다.

따라서 DispatcherServlet은 요청만 받는 주체고, 헬퍼 클래스가 요청을 처리한다.
이게 안되면 특정 스펙에 계속 규격화 된다.

대표 헬퍼 클래스로는

  • Handler Mapping
  • Handler Adapter
  • View Resolver
post-custom-banner

0개의 댓글