스프링 재활훈련 (1)

나한테 무슨 일이 일어났나?

포트폴리오를 마지막으로 만진지 2달이 넘어간다. 심지어 만들때는 좀 더 편하게 만드려고 스프링 부트로 만들어서 기본 스프링 관련은 잊은지 오래다. 이참에 처음부터 다시 복습해보자.

뭘 해야하나?

일단 스프링으로 프로젝트를 생성하고 기본 창을 띄우는 것부터 익히자.
그 과정에서 디스패쳐 서블릿, 루트 컨텍스트, web xml, pom xml 등에 대한 개념을 익힐 수 있을거다.

프로젝트 생성

프로젝트를 처음 만들때 New-Others-Maven-Maven Project.
Simple에 체크-아티팩트와 war 패키징 선택 후에 피니쉬. 근데 패키징은 뭔지 잘 모르겠다.
이렇게 끝내면 프로젝트가 생성이 되는데 프로젝트 폴더 안에 web.xml이 없어서 오류가 발생한다. src-main-webapp으로 들어가서 WEB-INF 폴더를 만들어주고 그 안에 web.xml 파일을 만들어주자.

스프링 레거시를 생성하면 이런 귀찮은 수순을 안밟아도 된다고 하는데 sts4에서는 지원하지 않으니 sts3 애드온을 설치해야 한댄다.
근데 sts3 애드온을 설치해도 메뉴에는 뜨지 않고 sts3.9 버전을 받아도 자바 오류로 인해서 뜨지 않는 상황.
그러면 이건 나중으로 보류해두고 옛날에 했던 방식 그대로 맨땅에 헤딩을 해보자.

의존성 추가

pom.xml에서 <dependencies> 태그를 넣고 spring-webmvc 추가. 스프링을 쓰려면 있어야 되는 것 같다. 일단 스프링의 뼈대 같으니 넣자.
그리고 javax.servlet-api도 추가. 서블릿 관련인것 같은데 뭐였는지 까먹었다. 그래서 한번 빼봤더니 서버 실행중에 Dispatcher Servlet 클래스가 없다는 오류가 발생했다. 이건 서블릿 자체를 담당하는 것 같다.
javax.servlet.jsp-api도 추가해준다. 위 서블릿 의존성의 jsp 버전인건가?
jstl 의존도 추가해준다. 이건 jsp 태그 라이브러리다. 이거만 기억나네... 암튼 jsp 쓸거면 넣자.
그리고 중요한 것들. 실행중에 이상이 생기면 오류를 잡아줄 기능이 있어야 한다. 그런걸 로그라고 했던거 같은데 암튼 그 로그를 담당하는게 slf4j-api와 logback-classic이 있다. 왜 두개 다 들어있지 라고 생각해서 하나하나 지워봤다.
일단 지금 목표는 서버를 키고 컨트롤러가 jsp파일을 읽고 보내주는 거다.
logback을 지우고 slf4j만 남겨봤다. 아무것도 안뜬다. 물론 실행 상에 이상은 없다. 이번엔 slf4j를 지우고 logback만 남겼다. 그랬더니 로그가 제대로 뜬다. 뭔가 해서 둘다 넣은채로 로그를 봤더니 slf4j가 지워졌던 로그와 동일하다.

그렇다면 컨트롤러만 사용하는 것에서는 logback만이 작동하는 것인가?

확실하진 않지만 일단 그렇게 생각하고 넘어가자. slf4j의 용도는 나중에 확인하자.

build 태그

또 <dependencies> 아래에 <build> 태그를 넣어주고 maven compiler plugin을 추가. 왜 필요한진 모르겠다. 그래서 한번 지워봤더니

Could not delete 뭐시기... May be locked by another process.

라는 오류가 뜬다. 뭔진 잘 모르겠지만 일단 없어선 안되는 것 같다. 가만히 냅두자.

최종적으로 pom xml 파일은 이렇게 됐다.

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Choi</groupId>
	<artifactId>Heading</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.2-b02</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.0.2.RELEASE</version>
		</dependency>
		
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.25</version>
		</dependency>
		
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>utf-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

WEB XML

pom xml의 설정이 끝났으면 다음은 web xml이다. 근데 그냥 WEB-INF 폴더를 만들고 그 안에 web xml이라는 이름의 xml 파일을 넣어놓은거라 아무 형식도 없다.

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1" metadata-complete="true">

이걸 넣어줘서 web xml 형식을 갖추게 해주자.

참고로 지금 코드들은 스프링 교재 예제파일에서 떼온거다. 지금 내 머리로는 자력으로 도저히 못만든다.

암튼 이렇게 만든 <web-app> 태그를 벌려서 그 안에 <servlet> 태그를 넣자. 이건 예전에 할때도 자세한 설명을 못들어서 그냥 서블릿 설정이려니 한다.
서블릿이 뭐냐고? 서버 기능을 하게 만드는 뭐시기로 알고 있었는데. 음... 나중에 포스트 하나 더 만들자...
서블릿 태그를 만들고 그 안에 <servlet-name>을 만든다.
궁금해서 한번 없애봤는데 servlet-name이 없다고 오류가 뜬다. 필수요소인거 같다. 이름이 왜 필요할까? 여러개 들어가기도 하나? 궁금해서 찾아봤는데 아래에 들어가는 <servlet-mapping> 태그와 연관된다고 한다. 서블릿 매핑에서 뭘 매핑시킬지 알아야 하니 이름이 있어야 한다는 것. 그래서 servlet 태그 안에 servlet-name을 하나 더 넣었더니 오류가 뜬다. multiple annotation 이라면서 수많은 목록에 servlet-name이 뜬다.

얘는 오륜지 알면서 왜 어떤 오류인지는 정확히 안알려주는거냐. 그럴거면 아예 인식을 하질 말던가. 알고도 모르는 척 하는건가? 살짝 짜증난다. 똑똑한 것 같으면서 멍청하다.

암튼 servlet을 여러개 만드는건 servlet 태그 안에 serlvet-name을 넣는것이 아니라 추가로 servlet 태그를 만드는 것이다. 이제서야 기억난다. 옛날에도 궁금해서 이짓거리했었는데 왜 다 잊었을까.
이름을 정해줬으면 그 아래에 <servlet-class> 태그를 넣고 서블릿 클래스를 잡아준다. 근데 이건 하나밖에 못봤다.

org.springframework.web.servlet.DispatcherServlet

이거 말고도 있나? 암튼 클래스를 넣어줬으면 <init-param> 태그를 넣어줘서 초기 파라미터 설정을 해준다.

<init-param>
	<param-name>contextClass</param-name>
	<param-value>
    		org.springframework.web.context.support.AnnotationConfigWebApplicationContext
	</param-value>
</init-param>

무슨 기능인진 모르겠다. 쓰라니까 쓰는거지. 그리고 내가 설정해준 것 (컨트롤러) 위치도 넣는다.

<init-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		controller.MainController
	</param-value>
</init-param>

controller 패키지에 MainController 클래스를 넣어놔서 저렇게 해줬다. 컨트롤 누르고 클릭하면 들어가진다. 연결된거다.

그리고 밑에 이런 코드가 있다.

<load-on-startup>1</load-on-startup>

실행 시에 몇번째로 불러올 건지 설정하는 거라는데 솔직히 뭔지 모르겠다. 빼도 정상적으로 작동을 하니...
암튼 서블릿 설정이 끝났으니 매핑을 하자. <servlet-maaping> 태그를 만들고 안에 매핑해줄 이름, <servlet-name> 태그를 넣고 <url-pattern>으로 어떤식으로 들어올건지 정해주자.
패턴이 여러 개가 있는데 기억나는건 /* 로 모든 경로, /**/route 로 특정 경로, *.do로 끝 확장자 정도다. 일단 지금은 /로 한다.

최종적으로 web xml은 이렇게 됐다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1" metadata-complete="true">
	
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextClass</param-name>
			<param-value>
				org.springframework.web.context.support.AnnotationConfigWebApplicationContext
			</param-value>
		</init-param>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				controller.MainController
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

제일 복잡하고 극혐이고 어려운 xml 설정들이 끝났다. 이걸 자바 클래스였나 다른 방식으로 설정할 수도 있다고 들었는데 정확히 기억이 안난다. 그보다 xml이 너무 싫다....

마무리

java 파일은 이리저리 만지면 되고 기억나는게 좀 있으니 빠르게 컨트롤러를 만들고 실험해보자.

@Controller
public class MainController {
	@RequestMapping("/main")
	public String mainPage() {
		System.out.println("컨트롤러 실행");
		return "index.jsp";
	}
}

jsp를 만드는 것도 잊지 말자. 기본 지정 위치는 src-main-webapp인 것 같다.

그러면

이렇게 뙇 하고 페이지가 나온다.

소감

시작이 반이다. 난 시작했으니 반은 한거다.
sts4에서 레거시 안된다고 이게 뭔 개고생인가. 정말 극혐이다.
근데 스프링 부트로 만들면 xml 설정을 안해도 되는데 왜 이렇게 귀찮게 할까...
다음엔 db 연동을 해보자. 많은거 안바란다. 웹 만들고 db 연동하면 초급 실력이다. 검색이나 검증은 그 뒤다.

좋은 웹페이지 즐겨찾기