[Spring] *.do 없애기 (깔끔한 URL, servlet mapping)

sua_ahn·2023년 3월 30일
0

Spring

목록 보기
8/8
post-thumbnail

Servlet Mapping

: servlet을 요청할 때, 경로를 간결하게 표현하는 것

→ servlet 경로에 닉네임을 붙여주는 것

       출처: https://www.youtube.com/watch?v=1plrQdt1pk8

위 사진처럼 매핑을 하지 않은 full path는 서블릿의 디렉토리 구조가 노출되므로 보안에 취약하고, 접근하려면 클래스명을 모두 입력해야 하므로 불편하다.

따라서 매핑을 통해 디렉토리 구조를 숨기고, 간결하게 나타냄으로써 위 문제들을 해결할 수 있다.

이러한 servlet mapping에는 2가지 방법이 있다. web.xml 파일을 이용한 맵핑과 Java Annotation을 이용한 맵핑이다. 여기서는 web.xml을 통해 URL 패턴을 바꿔보도록 하자.

 

URL pattern

Spring framework는 서블릿 기반으로 구동되기 때문에 servlet mapping이 1개 이상 필요하다.

또한, Front Controller에서 모든 요청을 받기 위해 servlet mapping의 url pattern을 지정해야 한다. 특정한 요청만 받게끔 하드코딩이 되어있으면 안된다는 뜻이다.

 

과거에는 확장자 즉, extension 방식을 많이 사용했다. 많은 예제들과 책의 영향으로 *.action, *.do가 관습처럼 자리잡았고, 기업의 경우 기업명을 확장자로 이용하는 경우도 있다.

그러나 extension 방식으로 요청을 분기하다 보면, 계층화가 깔끔하게 이루어지기 어려워서 일관성이나 규칙이 있는 요청을 만들기 어렵다. 아무런 의미가 없는 .do 확장자가 붙어 URI가 지저분하고 혼란스럽게 되기도 한다.

 

더 깔끔한 URL을 만들기 위해 *.do 대신 /을 URL pattern으로 사용할 수 있다. 다만 한 가지 문제가 있다. /로 URL을 연결하는 경우에는 js나 css 같은 정적 리소스 파일을 탐색하지 못한다.

모든 요청은 controller가 받기 전에 톰캣 서버를 거치게 된다. 이때 톰캣 역시 tomcat/conf/web.xml에 서술되어있는 default servlet mapping을 따라 요청을 처리한다. 톰캣 서버의 default servlet mapping 또한 /로 지정되어 있기 때문에, 충돌이 일어나 default servlet이 작동하지 않고 정적 리소스를 탐색할 수 없다.

이를 해결하기 위해 *.js나 *.img *.png 등의 servlet mapping을 다시 정의해주어야 하며, 설정 및 사용예시는 아래와 같다.

 

web.xml

<!-- The mapping for the default servlet -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

servlet-context.xml

<!-- Annotation 활성화 -->
<mvc:annotation-driven/>
<!-- spring에서 처리할 수 없는 요청은 tomcat이 처리 -->
<mvc:default-servlet-handler />

혹은

<!-- 정적파일 디렉토리 표기 -->
<mvc:resources mapping="/resources/**" location="/resources/"/>

view

<!-- .do 없이 적기 --!>

<a href="/projectName/login">로그인</a>

<!-- 또는 --!>

<a href="login">로그인</a>

controller

@Controller
public class Controller {

	@GetMapping(value = "login")	// .do 없이 적기
	public String login() {

		return "login";
	}
}

 

 

※ 참고
*.do 없애고 깔끔한 HTTP API 만들기
servlet mapping /와 /* 차이점

profile
해보자구

0개의 댓글