제목을 써 놓고도 제목이 어렵네용..ㅡㅡ;;


여튼 RESTFul 서비스를 하여 JSON 으로 결과 값을 받을 경우


public class ResponseWrapper {

...

private Object data;

...

}


위와 같은 방식으로 Data를 받을 경우 저 Data의 값이 어떠한 타입인지 모르기 때문에 

결과 적으로는 


{

success : true,

data : { userId=kamsi76, password=1234 }

}


이렇게 data가 JSON 형식이 아닌 형식으로 받게 되어 맵핑이 정상적으로 되지 않습니다.


그래서 다음과 같이


public class ResponseWrapper<T> {

...

private T data;

...

}


이렇게 처리 하면 되겠구나 하고 다시 수정을 했으나....


다음과 같은 문제가 발생을 합니다.


RestTemplate restTemplate = getRestTemplate();

ResponseEntity<ResponseWrapper<UserVo>> response = restTemplate.exchange(

url,

method,

null,

ResponseWrapper.class

);


이런식으로 하면 오류가 발생한다는....


그래서 구글링 한 결과


RestTemplate restTemplate = getRestTemplate();

ResponseEntity<ResponseWrapper<UserVo>> response = restTemplate.exchange(

url,

method,

null,

new ParameterizedTypeReference<ResponseWrapper<UserVo>>() {});

);


이렇게 하면 정상 동작을 합니다...


하지만 여기서 더 나아가...


저걸 공통으로 사용하기 위해 Util을 만들어서 사용한다고 할 경우


public <V, T> ResponseEntity<ResponseWrapper<T>> send(String url, V sendObj, Class<T> responseType, HttpMethod method) {

RestTemplate restTemplate = getRestTemplate();

ResponseEntity<ResponseWrapper<T>> response = restTemplate.exchange(

url,

method,

getEntity(sendObj),

new ParameterizedTypeReference<ResponseWrapper<T>>() {});


return response;

}


이렇게 처리하면 될 줄 알았습니다....


그런데... 정상 동작하지 않고 


{

success : true,

data : { userId=kamsi76, password=1234 }

}


결과가 이렇게 나와 버리는 현상이 나오게 되었습니다..


다시 구글링....


그래서 최종 소스는 다음과 같습니다..


public class RESTUtil {


...


public <V, T> ResponseEntity<ResponseWrapper<T>> send(String url, V sendObj, Class<T> responseType, HttpMethod method) {

RestTemplate restTemplate = getRestTemplate();

ResponseEntity<ResponseWrapper<T>> response = restTemplate.exchange(

url,

method,

getEntity(sendObj),

new ParameterizedTypeReference<ResponseWrapper<T>>() {

public Type getType() {

return new CustomParameterizedTypeImpl((ParameterizedType)super.getType(), new Type[] { responseType});

}

}

);


return response;

}


//내부 클래스로 두었슴...

class CustomParameterizedTypeImpl implements ParameterizedType {


    private ParameterizedType delegate;


    private Type[] actualTypeArguments;


    CustomParameterizedTypeImpl(ParameterizedType delegate, Type[] actualTypeArguments) {

            this.delegate = delegate;

            this.actualTypeArguments = actualTypeArguments;

        }


@Override

public Type[] getActualTypeArguments() {

return actualTypeArguments;

}


@Override

public Type getRawType() {

return delegate.getRawType();

}


@Override

public Type getOwnerType() {

return delegate.getOwnerType();

}


}

}


이와 같이 사용하면 정상 동작합니다.


이상입니다.



'JAVA > Webservice(REST)' 카테고리의 다른 글

07. POST 방식 호출  (0) 2015.08.06
06. 서비스 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06

포스트 방식 호출을 위한 클라이언트 생성

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class CallREST {
 public static void main(String[] args) throws Exception {
  String xml = "<?xml version='1.0'?>                           "+
                "<x:addCustomer xmlns:x='http://cxf.gnnet.co.kr/'>        "+
                "<customer>                                         "+
                "    <id>1234</id>                                  "+
                "    <name>HaksooKim</name>              "+
                "    <address>Ilsan</address>               "+
                "</customer>                                       "+
                "</x:addCustomer>                               ";
 
  URL url = new URL("http://localhost:8080/REST/services/CXFServicePort/addCustomer");
 
  HttpURLConnection conn = (HttpURLConnection)url.openConnection();
     conn.setDoOutput(true);
  conn.setRequestMethod("POST");
  // Header 영역에 쓰기
  conn.addRequestProperty("Content-Type", "text/xml");
     // BODY 영역에 쓰기
     OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
     wr.write(xml);
  wr.flush();
    
     // 리턴된 결과 읽기
     String inputLine = null;
        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        while ((inputLine = in.readLine()) != null) {
         System.out.println(inputLine);
        }
        in.close();
  wr.close();
 }
}




앞서 봤던 SOAP 방식의 Webservice를 포스트로 호출 했을때와 다른점은 서버로 전달되는 XML의 형식이다.
SOAP 방식에서는 SOAP 프로토콜에 맞게 SOAP:ENV와 SOAP:HEADER, SOAP:BODY등을 명확히 명시해줘야 하지만 RESTful 방식에서는 내부적으로는 SOAP 프로토코을 사용 할지라도 실제 사용자 입장에서는 단순 XML만 넘겨주고 받으면 되는 것이다.

* 소스에서 <x:addCustomer xmlns:x='http://cxf.gnnet.co.kr/'> wrapper element로써 우리가 beans.xml에 다음과 같이 wrapped속성에 true라고 했기 때문에 customer element 바깥에 addCustomer라는 wrapper element로 감싸줘야 한다.




만약 wrapped속성을 false로 지정하면 앞의 [RESTful Step6] 단계에서 GET방식으로 id 파라미터를 넘기는 부분에서 다음과 같은 오류가 발생할 것이다.

org.apache.cxf.interceptor.Fault: A URI parameter cannot be mapped to a simple type in unwrapped mode

'JAVA > Webservice(REST)' 카테고리의 다른 글

[RESTFul] ResponseEntity 제너릭 타입 사용 타입처리 방법???  (5) 2018.01.25
06. 서비스 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06

http://localhost:8080/REST/services를 웹브라우저에 입력하면 다음과 같이 서비스 되고 있는 내역이 나타날 것이다.


이 중에서 getCustomer1이라는 서비스를 다음과 같이 GET방식으로 호출한다.
http://localhost:8080/REST/services/CXFServicePort/getCustomer1/1234를 웹브라우저의 주소창에 입력 후 엔터키를 누르면 다음과 같은 결과가 넘어 온다.


SOAP 방식의 웹서비스에서 넘어왔던 결과 값이랑 비교 했을때 더욱 간결한 것을 알 수 있다.
SOAP 방식에서는 SOAP 프로토콜에 사용되는 SOAP 태그들이 들어 있었지만
RESTful 방식에서는 SOAP 프로토콜을 내부적으로 사용은 하지만 표면적으로는
단순 XML만 넘어오게 된다.

'JAVA > Webservice(REST)' 카테고리의 다른 글

[RESTFul] ResponseEntity 제너릭 타입 사용 타입처리 방법???  (5) 2018.01.25
07. POST 방식 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06

 




-- beans.xml --

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:jaxws="http://cxf.apache.org/jaxws"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
 
 <import resource="classpath:META-INF/cxf/cxf.xml" />
 <import resource="classpath:META-INF/cxf/cxf-extension-http-binding.xml" />
 <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
 <jaxws:endpoint
  id="cxfservice"
  implementor="kr.co.gnnet.cxf.CXFServiceImpl"
  address="/CXFServicePort" <-- 서비스 호출시 URL과 연관
  bindingUri="http://apache.org/cxf/binding/http" >
    <jaxws:serviceFactory >
     <bean class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
      <property name="wrapped" value="true" /> <-- Step7에서 추가 설명 있슴
     </bean>
    </jaxws:serviceFactory >
 </jaxws:endpoint >
 
</beans>




-- web.xml --

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

 

  <display-name>REST</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description>Apache CXF Endpoint</description>
    <display-name>cxf</display-name>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>cxf</servlet-name>
    <url-pattern>/services/-</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>60</session-timeout>
  </session-config>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/beans.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

</web-app>

'JAVA > Webservice(REST)' 카테고리의 다른 글

07. POST 방식 호출  (0) 2015.08.06
06. 서비스 호출  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06
02. 개발환경  (0) 2015.08.06

REST라는 이름으로 Dynamic Web Project를 하나 생성한다.
속성값들은 모두 Default로 나둬도 무방하다.

 

예제를 위한 도메인 클래스 Customer 생성

 

웹서비스를 정의해 놓은 인터페이스 생성(이 인터페이스를 SEI-Service Endpoint Interface라고 한다. 반드시 인터페이스를 정의할 필요는 없다. 바로 서비스를 담당할 클래스에 어노테이션을 달아서 직접 서비스를 정의해도 되지만 서비스의 정의와 실제 서비스의 구현을 분리한다는 개념으로 받아들이면 된다.)


RESTful Webservice를 만들고 있기 때문에 @Get, @Post와 같이 HTTP 방식으로 호출될 때 사용될 Verb를 어노테이션으로 달아 줘야 한다. 그리고 @HttpResource를 이용해서 실제 매핑 URI를 지정해 준다.

JRA
HTTP 요청 메서드 액션
@Get GET get
@Post POST add /create
@Put PUT update
@Delete DELETE delete


실제 서비스의 구현


이 곳에서는 서비스를 정의해 놓은 인터페이스를 구현 했기 때문에 별다른 어노테이션 들이 사용 되지 않고 순수 비지니스 로직들로만 구성 된다.

 

 

'JAVA > Webservice(REST)' 카테고리의 다른 글

06. 서비스 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06
02. 개발환경  (0) 2015.08.06
01. WebService를 위한 Framework 선택  (0) 2015.08.06

1. Eclipse에서 CXF 홈 연결

 

Add 버튼을 눌러서 한출 추가시키고 CXF 홈을 2단계서 다운받은 CXF ZIP을 푼 디렉토리를 맞춰 주면된다.

(apache-cxf-2.3.4 폴더 바로 아래에 lib 폴더가 보여야 정상이다.)


2. Eclipse에서 Web Service의 주체인 Tomcat 서버와 연결

 

'JAVA > Webservice(REST)' 카테고리의 다른 글

06. 서비스 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
02. 개발환경  (0) 2015.08.06
01. WebService를 위한 Framework 선택  (0) 2015.08.06

1. Tomcat 서버 : apache-tomcat-7.0.12


2. CXF : apache-cxf-2.3.4


3. Eclipse : eclipse-jee-helios-SR2-win32


위의 세가지 설치 파일들은 아시다시피 다운받은 zip 파일을 풀기만 하면 된다

'JAVA > Webservice(REST)' 카테고리의 다른 글

06. 서비스 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06
01. WebService를 위한 Framework 선택  (0) 2015.08.06

가장 잘 알려진 자바 진영의 Web Service 프레임웤은 Apache AXIS2이다.


AXIS때 부터 시작해서 JAX-WS(Web Service를 위한 Java Open API)를 손쉽게 이용할 수 있도록 잘 만들어 져있다.


하지만 Web Service는 HTTP 기반이지만 SOAP 프로토콜을 이용하고 있다.

따라서 기존의 AXIS의 Web Service를 이용하기 위해서는 SOAP을 자유자재로 핸들링 할 수 있는 모듈이 필요했다.


여기서 RESTful이란 개념이 생겨나기 시작했다.

(RESTful이란 가장 보편화 되어 있는 HTTP를 이용해서 서비스에 접근하고 결과를 리턴 받는 방법을 말한다.)


여기서 JAX-RS(RESTful Web Service를 위한 Java Open API)가 등장 했고 이것을 지원하고 있는

자바 Web Service 프레임웤이 등장 했는데


이것이 바로 Apache의 CXF이다.


물론 CXF말고도 다른 프레임웤들이 존해한다.

하지만 Apache의 CXF를 이해할 수 있으면 다른 모든 프레임웤들도 이해할 수 있으리라 본다

'JAVA > Webservice(REST)' 카테고리의 다른 글

06. 서비스 호출  (0) 2015.08.06
05. beans.xml과 web.xml  (0) 2015.08.06
04. 프로젝트의 시작  (0) 2015.08.06
03. Eclipse 환경설정  (0) 2015.08.06
02. 개발환경  (0) 2015.08.06

+ Recent posts