목차 >> 웹서비스 
+- JAX-WS  
+- RESTful

16장 웹서비스

이 장은 JAX-WS, RESTful관련 Glue Framework과의 관계와 연결 방법에 대해 설명하는 것을 목적으로 한다. 각 단원 마다 예제 및 Sample Code를 삽입하여 개발자가 쉽게 따라 개발할 수 있도록 하였다.
Glue Framework를 사용하여 웹 서비스를 개발할 경우 필요한 내용들을 설명한다. 본 문서에서는 JAX-WS, RESTful관련 개념이나 어노테이션(annotation)관련 부분은 꼭 필요한 부분만 설명하고 좀 더 구체적인 내용은 사이트를 참고하도록 한다.

JAX-WS

JAX-WS(Java API for XML Web Services)는 웹 서비스를 생성하는 자바 API로써, Java EE의 일부이다.
다른 Java EE의 자바 API와 같이, JAX-WS는 Java SE 5에서 도입된 어노테이션(annotation)을 사용하여 웹 서비스 클라이언트 및 서버 모듈의 개발 및 배포를 쉽게 하고 있다. JAX-WS는 JAX-RPC 표준을 발전 시킨 개념으로 XML의 바인딩을 위한 JAXB 표준과 표준 스트리밍 파서를 위한 StAX 표준, 기능이 향상된 새로운 SAAJ 표준을 기반으로 통합, 발전된 자바 진영의 노력의 산물이다.
JAX-WS 2.0이 JAX-RPC 1.1의 차후 버전으로 JAX-RPC 1.1의 다음 버전인 JAX-RPC 2.0이 나오면서, PC라는 용어 대신 메시지 지향 웹 서비스인 WS로 대체되어 JAX-WS 2.0으로 불리게 되었다.

  • JAX-WS : Java API for XML-Based Web Services
  • JAX-RPC : Java API for XML-Based RPC(Remote Procedure call)

많이 사용되는 웹 서비스 오픈 소스 프레임워크로는 Apache CXF, Apache Axis/Axis2, Spring Web Services 등이 존재하며 여러 프레임워크 중 사용하고자 하는 목적에 적합한 웹 서비스 프레임워크를 선정해야하는데 Glue Framework에서는 Apache CXF를 선정하였다.
Apache CXF의 장점은 다음과 같다.

  1. AX-WS 지원:CXF에서는 JAX-WS API를 구현하고 있어서 웹 서비스 구현을 쉽게 하고 있다.
  2. Spring Integration:CXF는 Spring 2.X 이상을 지원하며 endpoint 설정이나 client injection 등 Spring과의 통합을 용이 하게 한다.
  3. Apache Licensed:아파치 라이센스 사용으로 활용에 자유롭다.

JAXB는 Java Architecture for XML Binding의 약자로 XML Schema로부터 클래스 데이터를 바인딩하여 XML로부터 객체를 Unmarshalling 하거나, 반대로 객체를 XML로 저장하는 Marshalling을 수행할 수 있도록 해 준다. (JAXB Databinding) 이러한 JAXB의 특징은 다음과 같다.

  1. Apache CXF 사용 시 디폴트 Databinding 방식이 JAXB이므로, JAXB 사용을 위한 추가 설정이 필요없다.
  2. JavaBeans 코드에 @XmlElement와 같은 Annotation을 설정하여 element 명을 변경시킬 수 있다.
  3. JavaBeans 코드에 Annotation 설정 없이도 JAXB를 사용할 수 있다.
  4. List 형태의 타입은 지원하나 Map 형태의 타입에 대해서는 Databinding을 기본적으로 지원하지 않으므로 Map 형태의 타입을 이용하여 Databinding 하기 위해서는 XmlAdapter 클래스를 추가로 작성해줘야 한다.

JAXB사용시 SEI (Service Endpoint Interface) 클래스에 정의된 메소드의 입력값이나 리턴값으로 참조되지 않은 Java Type 클래스가 사용될 경우, Runtime 시 Data binding이 일어날 때 다음과 같은 에러 메시지가 나오게 된다.

org.apache.cxf.interceptor.Fault: Marshalling Error: xxxxxxx nor any of its super class is known to this context.

이 경우 아래와 같은 방법을 통해서 해결 할 수 있다.
SEI(Service Endpoint Interface) 클래스의 메소드에는 List 형태의 결과값을 리턴하는 메소드가 존재하고 해당 List내에 저장된 Java Type 클래스에 대해서는 참조하는 메소드가 없는 경우, 클라이언트가 해당 메소드를 호출할 때 Runtime시에 JAXB Databinding을 시도하려고 하면서 Marshalling Error가 발생하게 된다. 이를 방지하기 위해서 @XmlSeeAlso Annotation 혹은 JDK1.5의 Generic Type을 설정하도록 한다.
다음은 @XmlSeeAlso 사용 예제이다.

@WebService
@XmlSeeAlso({EmpVo.class})
public interface JaxService {
    public List getList( . . . );
    . . . 

다음은 JDK 1.5의 Generic Type 사용 예제이다.

@WebService
public interface JaxService {
    public List<EmpVo> getList ( . . . );
    . . .

Web Service 작성

Web Service 를 구현할 �는 인터페이스 와 구현 클래스로 작성한다.
인터페이스(interface)는 상단에 @WebService Annotation을 작성해줘야 한다. @WebService annotation의 속성 값들도 다양하게 존재하고, 각 메소드와 파라미터 별로 정의할 수 있는 Annotation의 종류도 여러가지가 있으나 필수 사항으로 필요한 Annotation은 @WebService뿐이다.

@WebService
public interface JaxSampleService  {
    public String findString(String id) throws Exception;    
    public HashMap<String,Object> findMap(String id) throws Exception;    
    public List<EmpVO> findList() throws Exception;    
    public List<EmpVO> doGlueService(HashMap<String,Object> glueMap) throws Exception;    
}

인터페이스(interface) 에서 @WebService 선언해 주었으므로 구현 클래스에서는 Web Service 구현과 관련된 부분 없이 작성될 수 있다. 인터페이스(interface)에서 설정하지 않은 부분을 추가로 설정해야할 경우에는 구현 클래스 상단에 @WebService Annotation관련해서 추가 작성해줄 수도 있다. 아래 예제에서는 인터페이스 클래스 상단에 @WebService Annotation을 작성해주었으므로 생략했다.

public class JaxSampleServiceImpl implements JaxSampleService
{
    . . .
    @Override
    public List<EmpVO> doGlueService(HashMap<String,Object> glueMap)
              throws Exception
    {
        GlueBizController bizIf = GlueBizProvider.getController();
        GlueContext ctx = new GlueDefaultContext();
        ctx.putAll(glueMap);
        bizIf.doAction(ctx);
        List<EmpVO> rowSet = (List<EmpVO>)ctx.get("EmpList");     
        return rowSet;
    }
    . . . 
}

Server 부분

작성된 서비스를 Web Service로 노출시키는 서버를 구동하기 위해서는 여러가지 방식이 지원되는데 이중 Spring Configuration XML - <jaxws:endpoint/> tag를 사용하여 서버를 구동하는 방법에 대해서 살펴보자. <jaxws:endpoint/> tag의 필수 속성값에 대한 설명은 다음 표와 같다. 아래 표에 나와있지 않은 속성들도 여러 가지가 존재한다.

구분 설명
id spring bean id를 작성한다
implementor 구현 클래스를 작성한다. 클래스명 대신에 spring bean id로 대체하고자 하면 bean id 앞에 #을 붙여서 작성하면 된다.
address 서비스가 동작할 주소를 상대 경로로 작성한다.

아래는 <jaxws:endpoint/> tag 속성을 정의한 xml 의 일부이다

<!-- Load CXF modules from cxf.jar -->
<importresource="classpath:META-INF/cxf/cxf.xml"/>
<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<importresource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<beanid="jaxSampleServiceImpl"class="sample.jax.JaxSampleServiceImpl"></bean>   
<jaxws:endpointid="jaxSampleService" 
       implementor="#jaxSampleServiceImpl"
       address="/jaxSample"/>

일반적으로 Tomcat 서버 등의 WAS를 이용하여 웹 어플리케이션을 구동하고 비즈니스 레이어의 서비스를 Web Service로 노출시키게 되는데, 이때 web.xml 파일에 Spring 속성 정의 XML 파일을 org.springframework.web.context.ContextLoaderListener를 이용하여 등록시켜 줘야 한다. 다음은 CXFServlet과 ContextLoaderListener를 정의한 web.xml의 일부이다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/jaxws-server-endpoint.xml</param-value>
</context-param>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener> 
<servlet>
    <servlet-name>CXFServlet</servlet-name>
    <display-name>CXF Servlet</display-name>
    <servlet-class>
        org.apache.cxf.transport.servlet.CXFServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>  
<servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
</servlet-mapping>

Client 부분

<jaxws:client/> tag의 각각의 Attribute 속성값에 대한 설명은 다음 표와 같다. 아래 표에 나와있지 않은 속성들도 여러 가지가 존재한다. 단, 여기서는 필수적으로 작성해야 하는 Attribute 속성값에 대한 설명을 작성해놓은 것으로 나머지 속성 값들에 대한 설명은 [JAX-WS Spring Configuration] 을 참고하도록 한다.

구분 설명
id spring bean id를 작성한다
serviceBean 서비스의 인터페이스 클래스를 작성한다.
address 서비스 접근 URL Address를 절대 경로로 작성한다.

다음은 Web Services로 노출된 Movie Service에 접근하는 jaxws:client/ tag 속성을 정의한 xml 의 일부이다.

<jaxws:client id="glueJaxWsClientService"
              serviceClass="com.poscoict.glueframework.jaxws.GlueJaxWebService"
              address="http://localhost:8080/sample/ws/glueJaxWs" />

다음은 앞서 정의한 속성 설정 파일들을 기반으로 하여 Web Services로 노출된 GlueJaxWebService에 접근하는java소스의 일부이다.

GlueJaxWebService sampleService = (GlueJaxWebService) GlueStaticContext.getBeanFactory().getBeanObject("glueJaxWsClientService");
try{
    HashMap<String,Object> glueMap = new HashMap<String, Object>();
    glueMap.put("ServiceName", "sample01-service");
    glueMap.put(GlueBizControlConstants.JAXWS_RESULT, "EmpList");
    glueMap.put("find", "event");
    glueMap.put("deptno", "10");
    List<GlueRowImpl> resultList 
           = (List<GlueRowImpl>) sampleService.doGlueServiceGetList(glueMap);
    . . .

Apache CXF에서 제공하는 JaxWsProxyFactoryBean를 직접 이용하여 Web Services로 노출된 Service에 접근하는 것도 가능하며, java 소스 일부는 다음과 같다.

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(GlueJaxWebService.class);

factory.setAddress("http://localhost:8080/sample/ws/glueJaxWs");
GlueJaxWebService sampleService = (GlueJaxWebService) factory.create();

Glue에서제공하는 WebService 클래스

glue-ws 모듈을 통해 다음 2가지 형태의 WebService 를 제공한다.

  • GlueJaxWebService interface: jax-ws기반에서 웹 서비스 기능을 제공하기 위한 interface로 Glue Service를 실행 시키고 GlueContext에서 해당 객체를 리턴하는 메서드들을 제공한다. 파라미터나 리턴 객체가 Map이나 List인 경우 map이나 list Type의 객체 혹은 interface나 abstract Class가 담길 경우 JAXB Databinding 에서 Error가 발생하므로 맵핑 객체에 주의해야 한다.
  • GlueJaxWebServiceImpl 구현체: jax-ws기반에서 웹 서비스 기능을 제공하기 위한 GlueJaxWebService의 구현체
  • GlueWebServiceJson interface: jax-ws기반에서 웹 서비스 기능을 제공하기 위한 interface로 Glue Service를 실행 시키고 GlueContext에서 해당 객체를 리턴하는 메서드들을 제공한다. 파라미터와 리턴 String을 JSON 형태로 제공한다.
  • GlueWebServiceJsonImpl 구현체: jax-ws기반에서 웹 서비스 기능을 제공하기 위한 GlueWebServiceJson의 구현체
    구분 메소드 설명
    GlueJaxWebService doGlueServiceGetStringByName Glue Service를 실행 시키고 GlueContext에서 String객체를 Return한다.
    doGlueServiceGetListByName Glue Service를 실행 시키고 GlueContext에서 List?객체를 Return한다.
    doGlueServiceGetMapByName Glue Service를 실행 시키고 GlueContext에서 HashMapString,Object객체를 Return한다.
    doGlueServiceGetString Glue Service를 실행 시키고 GlueContext에서 String객체를 Return한다.
    doGlueServiceGetList Glue Service를 실행 시키고 GlueContext에서 List?객체를 Return한다.
    doGlueServiceGetMap Glue Service를 실행 시키고 GlueContext에서 HashMapString,Object객체를 Return한다.
    GlueWebServiceJson doGlueServiceByJson Glue Service를 실행 시키고 GlueContext에서 Json형태의 String객체를 Return한다.

RESTful

REST란 ROA(Resource Oriented Architecture)를 따르는 웹 서비스 디자인 표준으로 웹의 모든 리소스를 URI로 표현하고, 이를 구조적이고 유기적으로 연결하여, 비 상태 지향적인 방법으로 일관된 method를 사용하여 리소스를 사용한다.
REST 방식의 웹서비스는 잘 정의된 Cool URI로 리소스를 표현한다는 특징을 갖는다.
무분별한 파라미터의 남발이 아니라, 마치 오브젝트의 멤버변수를 따라가듯이예를 들면 아래와 같다.

http://www.glue.net/user/mk/age/32

기존의 서블릿을 이용한 URI는아래와 같은 방식 이었다.

http://www.glue.net/finduser.jsp?user=mk&age=32

일반적으로 ROA는

  • 웹의 모든 리소스를 URI로 표현하고
  • 모든 리소스를 구조적이고 유기적으로 연결하여
  • 비 상태 지향적인 방법으로
  • 정해진 method만을 사용하여 리소스를 사용하는 아키텍쳐

라고 4가지로 정의 한다.
ROA를 따르는 RESTful 웹서비스는 아래와 같은 4가지 속성을 갖는다.

  1. Addressablilty (주소로 표현 가능함) : 제공하는 모든 정보를 URI로 표시할 수 있어야 한다. 직접 URI로 접근할 수 없고 HyperLink를 따라서만 해당 리소스에 접근할 수 있다면 이는 RESTful하지 않은 웹서비스이다.
  2. Connectedness (연결됨) : 일반 웹 페이지처럼 하나의 리소스들은 서로 주변의 연관 리소스들과 연결되어 표현(Presentation)되어야 한다.
    다음은 독립적인 리소스 예제이며,
    <user>
    <name>MK</name>
    </user>
    

    다음은 관련 리소스(home, office)가 잘 연결된 리소스 예제이다.

    <user>
    <name>MK</name>
    <home>MK/home/</home>
    <office>MK/office</office>
    </user>
    
  3. Statelessness (상태 없음) : 현재 클라이언트의 상태를 절대로 서버에서 관리하지 않아야 한다. 모든 요청은 일회성의 성격을 가지며 이전의 요청에 영향을 받지 말아야 한다. 세션을 유지 하지 않기 때문에 서버 로드 발란싱이 매우 유리하다.
  4. Homogeneous Interface (동일한 인터페이스) : HTTP에서 제공하는 기본적인 4가지의 method와 추가적인 2가지의 method를 이용해서 리소스의 모든 동작을 정의한다.
    구분 method 추가설명
    리소스 조회 GET
    새로운 리소스 생성 PUT, POST 새로운 리소스의 URI를 생성하는 주체가 서버이면 POST를 사용
    존재하는 리소스 변경 PUT
    존재하는 리소스 삭제 DELETE
    존재하는 리소스 메타데이터 보기 HEAD
    존재하는 리소스의 지원 method 체크 OPTION

Server 파트

Spring 기반에서 RESTful방식으로 구현한다.
Spring의 REST를 위한 기능은 모두 Spring MVC를 기반으로 지원된다. 다양한 Annotation과 HTTP Request/Response Body 메세지 처리를 위한 HttpMessageConverter, Content Negotiation 지원을 위한 ViewResolver, 모든 HTTP method 사용을 위한 Filter, 그리고 REST 클라이언트 어플리케이션 개발에 도움을 주는 RestTemplate 등이 있다.
web.xml에 아래와 같이 확장자로 맵핑되지 않도록 DispatcherServlet을 등록한다.

<servlet>
    <servlet-name>restful</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>restful</servlet-name>
    <url-pattern>/restful/*</url-pattern>
</servlet-mapping>

DipatcherServlet은 servlet-name-servlet.xml 을 필요로 하며, web.xml이 위와 같다면 restful-servlet.xml을 필요로 한다. 그 내용은 다음과 같이 설정한다.

<context:component-scan base-package="sample.controller" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".jsp" />
</bean>
<bean name="ViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
    <property name="order" value="1"/>
    <property name="location" value="/WEB-INF/views.xml"/>
</bean>

json으로 데이터를 주고 받을 경우 json데이터를 변환해줄 AnnotationMethodHandlerAdater를 빈으로 등록하고 messageConverters 속성에 Json용 Converters 클래스를 추가해야 하는데 mvc:annotation-driven /이 해당 bean 설정을 자동으로 설정해 준다. 해당 빈 설정을 변경해야 할 경우에는 <mvc:annotation-driven />을 사용하지 말고 AnnotationMethodHandlerAdater등의 Bean을 직접 등록해주면 된다.
@controller 가 있는 Class를 자동 스캔 하기 위해서 <context:component-scan base-package=. . .>을 통해서 해당 package를 설정해 주어야 한다. 그래서 <context:component-scan base-package="sample.controller" />이 사용되었다.
ViewResolver에서는 views.xml을 필요로 하며, MappingJacksonJsonView를 사용할 수 있도록 해당 Bean을 다음과 같이 등록해야 한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean name="jsonView" class=org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
</beans>

<context:component-scan base-package="sample.controller" /> 를 통해 자동 스캔되는 Class는 다음과 같은 형태이다.

@Controller
public class RestfulController
{
    /** logger */
    protected GlueLog logger = GlueLogFactory.getLogger(getClass());
    @RequestMapping(value = "/glue/{serviceName}", method = RequestMethod.GET)
    public ModelAndView doGlueServiceGet(@PathVariable String serviceName)
    {
        ModelAndView mav = new ModelAndView("jsonView");
        //비지니즈 로직 구현
        return mav;
    }
}

RestfulController의 @Controller 어노테이션은 해당 클래스가 컨트롤러의 역할을 한다는 것을 나타낸다. 스프링에서는 어떤 컨트롤러 기반 클래스도 확장할 필요가 없고 서블릿 API를 참조할 필요도 없다. 하지만 필요하다면 서블릿에 특화된 기능을 참조할 수 있다.
@Controller 어노테이션은 어노테이션이 붙은 클래스의 스테레오 타입처럼 동작하고 클래스의 역할을 나타낸다. 디스패처는 매핑된 메서드에 이러한 어노테이션이 붙은 클래스를 찾고 @RequestMapping 어노테이션을 탐지한다.
디스패처의 컨텍스트에 표준 스프링 빈 정의를 사용해서 어노테이션이 붙은 컨트롤러 빈을 명시적으로 정의할 수 있다. 하지만 클래스패스에서 컴포넌트 클래스를 탐지와 컴포넌트 클래스들을 위해 빈 정의의 자동등록에 대한 스프링의 일반적인 지원에 맞추어 @Controller 스테레오타입도 자동탐지(<context:component-scan . . . >)가 가능하다.
특정 URL을 매핑하려면 전체 클래스나 특정 핸들러 메서드에 @RequestMapping 어노테이션을 사용해야 한다. 보통 클래스수준의 어노테이션은 폼(form) 컨트롤러에 특정 요청 경로(또는 경로 패턴)을 매핑하고 추가적인 메서드 수준의 어노테이션은 특정 HTTP 요청 메서드("GET", "POST" 등)나 HTTP 요청 파라미터 상태로 매핑 범위를 좁힌다.

@Controller
@RequestMapping("/poscoict")
public class AppointmentsController
{
    @RequestMapping(method = RequestMethod.GET)
    public ModelAndViewget()
    {
        // 구현
    }
    @RequestMapping(value="/test", method = RequestMethod.GET)
    public ModelAndViewgetNew()
    {
        // 구현
    }
}

위 예제에서 @RequestMapping를 여러 곳에서 사용했다. 먼저 클래스 수준에서 사용했는데 이것은 컨트롤러의 모든 핸들링 메서드는 /poscoict 경로에 상대적이라는 것을 나타낸다. get() 메서드의 @RequestMapping의 method 만을 정의했는데, 이것은 GET 요청만 받아들인다는 것을 의미한다. 즉, /poscoict에 대한 HTTP GET 요청만 이 메서드를 실행한다. POST요청 처리를 위해서도 마찬가지 방식으로 구현할 수 있다. getNew()은 HTTP 메서드와 경로를 함께 사용했으므로 poscoict/new에 대한 GET 요청을 이 메서드가 처리한다.
Method 정의시 일부 오래된 장비나 서버의 경우 GET,POST만 허용하는 경우도 있으므로 주의해야 한다.
클래스 수준의 @RequestMapping는 필수가 아니다. 클래스에 @RequestMapping를 사용하지 않으면 모든 경로는 상대경로가 아니라 절대경로가 된다.
스프링 MVC에서 URI 템플릿 변수의 값에 바인딩하려고 메서드 인자에 @PathVariable 어노테이션을 사용할 수 있다.

@RequestMapping(value="/glue/{loginid}", method=RequestMethod.GET)
public String findOwner(@PathVariable(“loginid”) String id) {
    // 구현
}

@PathVariable 어노테이션을 처리하려면 스프링 MVC가 이름과 일치하는 URI 템플릿 변수(loginid)를 찾아야 한다. 어노테이션에서 이를 지정할 수 있다.
또는 URI 템플릿 변수 이름이 메서드 인자의 이름과 일치한다면 생략할 수 있다.
메서드는 다수의 @PathVariable 어노테이션을 가질 수 있다.
@PathVariable 인자는 int, long, Date 등의 간단한 어떠한 타입이라도 될 수 있다. 스프링이 자동으로 적절한 타입으로 변환하거나 타입변환에 실패한다면 TypeMismatchException를 던진다.

Client 파트

다음은 jquery를 이용한 호출 예제이다.

$.ajax({
   type: 'GET',
   url: "http://localhost:8080/GlueSample/restful/glue/sample01-service/",
   data: formdata,
   success: function(resultdata){
      //비즈니스 로직 구현
      // resultdata은 해당 웹서비스에서 넘어온 값
   }
});

다음은 RestTemplate을 사용한 예제이다.

RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject ( "http://localhost:8080/GlueSample/restful/glue/sample01-service/" , String.class );

위와 같이 가급적 RestTemplate 클래스의 빈으로 등록하여 사용하는 것을 권장한다.
GET방식의 요청일 경우에는 getForObject(String, Class, String...)을 사용하고 POST방식일 경우에는 postForLocation(String, Object, String...)을 PUT방식일 경우에는 put(String, Object, String...)을 DELETE방식일 경우에는 delete(String, String...)를 사용한다.

Glue에서제공하는 RESTful용 Controller

Glue에서는 특정 서비스를 실행 시키고 결과 값을 JSON형태로 반환하는 RestfulController를 제공하고 있다.
servlet.xml 에 Controller 스캔 Package를 다음과 같이 정의해준다.

<context:component-scan base-package="com.poscoict.glueframework.web.control.restful" />

Controller는 다음과 같은 URI 패턴을 처리할 수 있다.

  • /glue/serviceName : URI의serviceName과 Service명이일치하는 Glue Servic가실행된다.
  • /glue/serviceName/data/gluedata : URI의serviceName과 Service명이일치하는 Glue Service가 실행되며 URI의gluedata값은“gluedata”를 Key로GlueContext에저장된다.

RequestMethod 로는 GET,POST,PUT,DELETE 방식이 지원되며 어떤 방식의 요청이었는지는 “action”을 Key로 GlueContext에 소문자로 저장된다. 해당 요청이 Key로도 등록되므로 아래와 같이 Default Router로 분기도 가능하다.

그림 : Default Router분기
Default Router분기

POST방식은 RequestParam으로 넘어온 값을 모두 GlueContext에 전달하며, PUT 방식의 경우에는 RequestBody로 넘어온 값을 모두 GlueContext에 전달한다.
Glue에서제공하는 RESTful용 Controller가 사용되었다면, Client부분에서는 ajax방식이나 RestTemplate을 사용하여 서비스를 호출 할 수 있으면 JSON 형식의 데이터가 Return된다.