Restful

개요

Spring MVC를 통해 구현한 RESTful은 리소스에 대한 접근을 URI를 이용하며, HTTP의 PUT, GET, POST, DELETE 등과 같은 메소드의 의미를 그대로 사용하므로, 단순하게 접근 할 수 있다.

설명

web.xml 설정

    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.xml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.json</url-pattern>
    </servlet-mapping>
 
    <filter>
	<filter-name>httpMethodFilter</filter-name>
	<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
	<filter-name>httpMethodFilter</filter-name>
	<url-pattern>/springrest/*</url-pattern>
    </filter-mapping>

자세한 설명은 아래에 있다.

Request Mapping

▪ 설정

REST 스타일의 URL은 '/cgr’, '/cgr/CATEGORY-00000000001' 처럼 계층 구조로 사용가능하도록 설계되었다. 따라서 web.xml에 DispatcherServlet을 정의하고 매핑할 URL 패턴을 '/'로 지정해야한다. DispatcherServlet URL 매핑 샘플은 다음과 같다.

    <servlet-mapping>    
	<servlet-name>action</servlet-name>    
	<url-pattern>/springrest/*</url-pattern>
    </servlet-mapping>

아래와 같은 방법으로도 DispatcherServlet URL 매핑을 사용 할 수 있다.

    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.xml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.json</url-pattern>
    </servlet-mapping>
▪ 사용

Spring에서 제공하는 REST 지원 기능들은 모두 Spring MVC 기반으로 되어 있다. REST 방식으로 노출되는 서비스는 곧 Controller의 메소드이기 때문에 기존에 웹 어플리케이션을 개발하던 방식과 크게 다르지 않다.

Resource의 ID인 URI를 Controller 클래스나 메소드에 매핑하기 위해서는 @RequestMapping을 사용한다. @RequestMapping이 URI Template을 지원하기 때문에 아래 샘플코드와 같이 사용할 수 있다.

@Controller
@SessionAttributes(types=CategoryVO.class)
public class EgovCategoryController {
	//…
   @RequestMapping(value="/springrest/cgr/{ctgryId}", method=RequestMethod.GET)
   public String updtCategoryView(@PathVariable String ctgryId, Model model) throws Exception{
	   // …
   }
}

모든 HTTP method 사용을 위해서 @RequestMapping에서 'method' 속성을 제공한다. 따라서, '/springrest/cgr/CATEGORY-00000000001'이라는 URI가 GET으로 요청이 들어올 경우 위의 updtCategoryView ( ) 메소드가 매핑될 것이다.

▪ @PathVariable annotation추가

‘/springrest/cgr/CATEGORY-00000000001’로 URI요청이 들어왔을 경우 @PathVariable을 사용하여 ‘ctgryID’ 입력 인자로 바인딩 된다.

@RequestMapping(value="/springrest/cgr/{ctgryId}", method=RequestMethod.GET)
public String updtCategoryView(@PathVariable String ctgryId, Model model) throws Exception{
	// …
}

HTTP Method Conversion

▪ 설정

브라우저 기반의 HTML에서는 GET, POST만 지원한다. 일반적으로 HTTP에서는 POST를 사용하고, hidden 타입의 입력값으로 HTTP METHOD를 지정하는 경우가 많다. 다음은 web.xml에 HiddenHttpMethodFilter를 정의한 모습이다.

    <filter>
	<filter-name>httpMethodFilter</filter-name>
	<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
	<filter-name>httpMethodFilter</filter-name>
	<url-pattern>/springrest/*</url-pattern>
    </filter-mapping>
▪ 사용

web.xml에 HiddenHttpMethodFilter 설정을 추가하면, HTTP Method가 POST이고 _method라는 파라미터가 존재하는 경우 HTTP의 Method를 _method 값으로 바꾼다.

또한 Spring에서는 <form:form>에서 실제 HTTP Method를 지정하는 hidden 타입의 입력 필드를 자동으로 추가해주기 때문에 훨씬 더 편리하게 사용할 수 있다.

    <form:form method="delete">
	<input type=submit value=Delete/>
    </form:form>

JSP에 위와 같이 작성하면, 내부적으로는 POST 방식으로 “_method=delete”가 전달되는 것이다.

샘플코드이다.

function fncSubmit(method) {
    document.detailForm._method.value=method;
    document.detailForm.submit();
}
 
//..
 
<form:form name="detailForm" method="${method}">
    <a href="javascript:fncSubmit('delete');">삭제</a>
</form:form>

HTTP Method Conversion

Xml과 json 등 다른 view로 보여지는 것으로 spring에서는 ContentNegotiatingViewResolver를 제공한다. ContentNegotiatingViewResolver는 다른 View Resolver들과 반드시 함께 사용되어야 하므로 View Resolver 설정 시 반드시 order를 정의해야 한다. 당연히 ContentNegotiatingViewResolver가 가장 높은 우선순위(가장 작은숫자)를 가져야 한다. defaultView는 View를 찾지 못한 경우 디폴트 View로 사용된다.

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="defaultViews">
	<list>
	   <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
		<property name="prefixJson" value="false"/>
	   </bean>
	</list>
    </property>
</bean>

Views

▪ MarshallingView

클라이언트에게 xml 응답을 돌려주기 위해 Spring OXM Marshaller를 사용한다. Spring oxm는 JAXB2, XMLBeans, JiBX, Castor등을 사용하여 Marshaller를 손쉽게 정희할 수 있게 해준다. Restful 예제에서는 JAXB2를 사용하였다. (OXM예제는 Castor사용)

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	<property name="mediaTypes">
		<map>
			<entry key="html" value="text/html" />
			<entry key="xml" value="application/xml" />
			<entry key="json" value="application/json" />
		</map>
	</property>
	<property name="order" value="0" />
//..
</beans>
 
<bean name="cgr/egovCategoryRegister" class="org.springframework.web.servlet.view.xml.MarshallingView">
	<property name="marshaller" ref="marshaller" />
</bean>
 
<oxm:jaxb2-marshaller id="marshaller">
	<oxm:class-to-be-bound name="egovframework.rte.tex.cgr.service.CategoryVO" />
</oxm:jaxb2-marshaller>
▪ MappingJacksonJsonView

JSON으로 응답을 전달할 수 있는 View.

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	<property name="mediaTypes">
		<map>
			<entry key="html" value="text/html" />
			<entry key="xml" value="application/xml" />
			<entry key="json" value="application/json" />
		</map>
	</property>
	<property name="order" value="0" />
	//..
</beans>
 
<bean name="cgr/egovCategoryList" 
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

실제 사용 예

▪ jsp
function fncSubmit(method) {
	document.detailForm._method.value=method;		
	document.detailForm.submit();
}
 
//..
 
<form:form name="detailForm" method="${method}">
//..
</form:form>
 
//..
<a href="javascript:fncSubmit('post');">등록</a> //----------- controller 2.
<a href="javascript:fncSubmit('put');">수정</a> //------------- controller 3.
<a href="javascript:fncSubmit('delete');">삭제</a> //----------- controller 4.
<a href=" /springrest/cgr/{id}.xml">xml 보기</a> // ContentNegotiatingViewResolver설정
<a href=" /springrest/cgr/{id}.json">json(defaultView) 보기</a> // ContentNegotiatingViewResolver설정
<a href=" /springrest/cgr.html">목록</a> //------------------ controller 1.
<a href=" /springrest/cgr.json">목록(json)</a> // ContentNegotiatingViewResolver 설정
▪ controller
// 1. 목록
@RequestMapping(value="/springrest/cgr", method=RequestMethod.GET)
public String selectCategoryList(..) throws Exception {
	//..
}
 
// 2. 등록
@RequestMapping(value="/springrest/cgr", method = RequestMethod.POST, ..)
public String create( ..) throws Exception {
	//..
}
 
// 3. 수정
@RequestMapping(value = "/springrest/cgr/{ctgryId}", method = RequestMethod.PUT, ..)
public String update(..) throws Exception {
	//..
}
 
// 4. 삭제
@RequestMapping(value = "/springrest/cgr/{ctgryId}", method=RequestMethod.DELETE)
public String deleteCategory(@PathVariable String ctgryId, SessionStatus status) throws Exception{
	//..
}

참고자료

 
egovframework/rte2/itl/restful.txt · 마지막 수정: 2020/07/06 13:26 작성자 com
 
이 위키의 내용은 다음의 라이센스에 따릅니다 :CC Attribution-Noncommercial-Share Alike 3.0 Unported
전자정부 표준프레임워크 라이센스(바로가기)

전자정부 표준프레임워크 활용의 안정성 보장을 위해 위험성을 지속적으로 모니터링하고 있으나, 오픈소스의 특성상 문제가 발생할 수 있습니다.
전자정부 표준프레임워크는 Apache 2.0 라이선스를 따르고 있는 오픈소스 프로그램입니다. Apache 2.0 라이선스에 따라 표준프레임워크를 활용하여 발생된 업무중단, 컴퓨터 고장 또는 오동작으로 인한 손해 등에 대해서 책임이 없습니다.
Recent changes RSS feed CC Attribution-Noncommercial-Share Alike 3.0 Unported Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki