서비스하나 맹가놓고.. soap, rest, json 등.. 입맛에 맞는 넘으로 endpoint를 열어 놓는 세상.. 참 좋구만..

Spring 설정을 보면..

import

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:/META-INF/cxf/cxf-extension-jaxws.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-http-binding.xml" />

작업하다 추가된 넘들이라.. 기억이 가물가물하지만.. 저넘들 하나하나가 특정 프로토콜을 사용하는 데 필요하다.

JOSN endpoint 설정

<jaxws:endpoint id="getServiceJson"
        implementor="#starMapServiceImpl"
        implementorClass="star.map.service.StarMapService"
        address="/StarMapService/JSON"
        bindingUri="http://apache.org/cxf/binding/http">
        <jaxws:serviceFactory>
            <bean class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
                <property name="wrapped" value="false"/>
                <property name="properties">
                    <map>
                        <entry key="Content-Type" value="text/plain"/>
                        <entry>
                           <key><value>javax.xml.stream.XMLInputFactory</value></key>
                            <bean class="org.codehaus.jettison.mapped.MappedXMLInputFactory">
                                <constructor-arg>
                                    <map>
                                        <!-- targetNamespace : http://map.star -->
                                        <entry key="http://map.star" value=""/>
                                    </map>
                                </constructor-arg>
                            </bean>
                        </entry>
                        <entry>
                           <key><value>javax.xml.stream.XMLOutputFactory</value></key>
                            <bean class="org.codehaus.jettison.mapped.MappedXMLOutputFactory">
                                <constructor-arg>
                                    <map>
                                        <!-- targetNamespace : http://map.star -->
                                        <entry key="http://map.star" value=""/>
                                    </map>
                                </constructor-arg>
                            </bean>
                        </entry>
                    </map>
                </property>
            </bean>
        </jaxws:serviceFactory>
</jaxws:endpoint>

뭐.. 이넘과 매핑되는 소스코드를 보면.. (다운로드 받으면 제공되는 예제 참조함)
private static void createJsonRestService(Object serviceObj) {
        // Build up the server factory bean
        JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
        sf.setServiceClass(CustomerService.class);
        // Use the HTTP Binding which understands the Java Rest Annotations
        sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID);
        sf.setAddress("http://localhost:8080/json");
        sf.getServiceFactory().setInvoker(new BeanInvoker(serviceObj));

        // Turn the "wrapped" style off. This means that CXF won't generate
        // wrapper JSON elements and we'll have prettier JSON text. This
        // means that we need to stick to one request and one response
        // parameter though.
        sf.getServiceFactory().setWrapped(false);

        // Tell CXF to use a different Content-Type for the JSON endpoint
        // This should probably be application/json, but text/plain allows
        // us to view easily in a web browser.
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("Content-Type", "text/plain");

        // Set up the JSON StAX implementation
        Map<String, String> nstojns = new HashMap<String, String>();
        nstojns.put("http://demo.restful.server", "acme");

        MappedXMLInputFactory xif = new MappedXMLInputFactory(nstojns);
        properties.put(XMLInputFactory.class.getName(), xif);

        MappedXMLOutputFactory xof = new MappedXMLOutputFactory(nstojns);
        properties.put(XMLOutputFactory.class.getName(), xof);

        sf.setProperties(properties);

        sf.create();
    }


결국 JaxWsServerFactoryBean 를 생성..

REST

1. Spring 설정으로 배포
<jaxws:endpoint id="getServiceHttp"
      implementor="#starMapServiceImpl"
      implementorClass="star.map.service.StarMapService"
      address="/StarMapService"
      bindingUri="http://apache.org/cxf/binding/http">
      <jaxws:serviceFactory>
         <ref bean="jaxWsServiceFactoryBean"/>
      </jaxws:serviceFactory>
</jaxws:endpoint>

<bean id="jaxWsServiceFactoryBean"
    class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean" scope="prototype">
      <property name="wrapped" value="false" />
</bean>     

2. 소스코드로 배포
private static void createRestService(Object serviceObj) {
        // Build up the server factory bean
        JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
        sf.setServiceClass(CustomerService.class);
        // Use the HTTP Binding which understands the Java Rest Annotations
        sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID);
        sf.setAddress("http://localhost:8080/xml/");
        sf.getServiceFactory().setInvoker(new BeanInvoker(serviceObj));

        // Turn the "wrapped" style off. This means that CXF won't generate
        // wrapper XML elements and we'll have prettier XML text. This
        // means that we need to stick to one request and one response
        // parameter though.
        sf.getServiceFactory().setWrapped(false);

        sf.create();
}




SOAP

1. Spring 설정으로 배포
    <jaxws:endpoint
      id="getServiceSoap"
      implementor="#starMapServiceImpl"
      implementorClass="star.map.service.StarMapService"
      address="/StarMapService/SOAP" />

2. 소스코드로 배포
private static void createSoapService(Object serviceObj) {
        JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
        sf.setServiceClass(CustomerService.class);
        sf.setAddress("http://localhost:8080/soap");
        sf.getServiceFactory().setInvoker(new BeanInvoker(serviceObj));
        sf.getServiceFactory().setWrapped(false);

        sf.create();
    }
Posted by 짱가쟁이
이넘 저넘 찾아보다 쓸만한 방법을 찾음.



Class Root 에 /META-INF/cxf/org.apache.cxf.Logger 생성

추가
org.apache.cxf.common.logging.Log4jLogger

Posted by 짱가쟁이
apache cxf 는 기본적으로 thread safety를 지원 하지 않는다고 한다. 뭐 그래서 어쩌구 저쩌구 하지만... 다른 방법으로 할수 있다고는 한다.

cxf.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xsi:schemaLocation="
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <httpj:engine-factory bus="cxf">
        <httpj:engine port="9000">
            <httpj:sessionSupport>true</httpj:sessionSupport>
        </httpj:engine>
    </httpj:engine-factory>
  
    <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus>
</beans>

Server Side - service class
package bbaeggar.jaxws.simple.server.service;

import javax.annotation.Resource;
import javax.jws.WebService;
import javax.servlet.http.HttpSession;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;

@WebService(endpointInterface = "bbaeggar.jaxws.simple.server.service.Login",
        serviceName = "Login")
public class LoginImpl implements Login {

    //webServiceContext is injected by the JAXWS API
    @Resource private WebServiceContext wsContext;
  
    SessionVo sessionVo;
  
    @Override
    public boolean login(String id, String pw) {
        // TODO Auto-generated method stub

        MessageContext mc = wsContext.getMessageContext();
        HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession(true);
        // Get a session property "counter" from context
        if (session == null)
            System.out.println("session is null");
              
        sessionVo = new SessionVo();
      
        sessionVo.setId(id);
        sessionVo.setPw(pw);

        session.setAttribute("session", sessionVo);
              
        return true;

    }

    @Override
    public String getId() {
        // TODO Auto-generated method stub      
        MessageContext mc = wsContext.getMessageContext();      
        HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();      
        SessionVo vo = (SessionVo)session.getAttribute("session");

        return vo.getId();      
    }
}

Client side class
package bbaeggar.jaxws.simple.client;

import java.util.Map;

import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;

import bbaeggar.jaxws.simple.server.service.HelloWorld;
import bbaeggar.jaxws.simple.server.service.Login;

public class TestRunnable implements Runnable {
  
    @Override
    public void run() {
        login();      
    }
  
    public void login() {
                  
        Service service = Service.create(Client.SERVICE_LOGIN);
        String endpointAddress = "http://localhost:9000/Login";
        service.addPort(Client.PORT_LOGIN, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
      
        Login login = service.getPort(Login.class);
      
        Map requestContext = ((BindingProvider)login).getRequestContext();
        requestContext.put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);
      
        String id = "bbaeggar" + Thread.currentThread().getId();
      
        boolean isLogin = login.login(id, "aaaa");
      
        System.out.println("client : " + login.getId());
      
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      
        if(id.equals(login.getId())) {
            System.out.println("같은 세션임");
        } else {
            System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
        }
    }
}


위 코드는 미친척하고 테스트용으로 만든거임.. 테스트용으로만 사용하삼.  쩌ㅃ~
Posted by 짱가쟁이
KTF Khub 작업을 하던중... jdk 1.6 버전에서 khub 테스트 코드가 동작을 안하더라.. 이유를 찾아보니.. jaxb 버전 문제로 클라이언트 코드가 동작은 안함. 뭐. jdk 버전을 낮춰서 작업하면 되것지만.. cxf를 공부하고 있는 도중이였기에 cxf에서 제공하는 "wsdl2java" 툴을 사용하게 되었음.

우선 콘솔창에서 작업해도 무난히 동작하지만.. 이클립스를 사용하기 때문에 편하게 ant로 작업했음.(이클립스 너무 편한듯.. 쩌ㅃ~)

khub_wsdl2java.xml
<?xml version="1.0"?>
<project name="cxf khub_wsdl2java" basedir="."> 
   <property name="cxf.home" location ="C:\Develop\02. Documents\01. Apache cxf\apache-cxf-2.2.7\apache-cxf-2.2.7"/>

   <path id="cxf.classpath">
      <fileset dir="${cxf.home}/lib">
         <include name="*.jar"/>
      </fileset>
   </path>
    
   <target name="cxfWSDLToJava">
      <java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
         <arg value="-client"/>
         <arg value="-d"/>
         <arg value="D:\wsdl2java\khub_client"/>
         <arg value="http://125.131.85.42/khub/WebService?wsdl"/>
         <classpath>
            <path refid="cxf.classpath"/>
         </classpath>
      </java>
   </target>
</project>

cxf 홈 디렉트리, java code 생성 경로, wsdl 경로만 변경하면.. 무난히 동작함.
Ant로 빌드하면 코드가 생성되는데.. 패키지 구조가 좀 지져분한게 생성됨.. 뭐 따로 설정하면 되것지만.. 이거는 수작업을 함.
생성된 빌드를 보면 "IWebService_IWebServicePort_Client" 라는 넘이 있는데.. 이놈이 실제로 Entry point 가 된다.
jdk1.6 으로 작업하고 싶다면.. Apache CXF를 사용하는 것도 무난할듯..

Posted by 짱가쟁이
IBM developersorks 를 뒤적이다가 흥미로운 기사가 있어 참고용으로 남긴다. (난중에 쓸일이 있을지도 모를듯 ^^)
우선 일반적인 케이스와, WS-Security 상태로 나눠서 결과를 통계로 보여준다. 자세한 내용은 기사를 참조하기 바란다.

출처 

'framework > apache cxf' 카테고리의 다른 글

[Apache cxf] - session support  (0) 2010.06.28
[Apache cxf] - WSDL to Java  (0) 2010.06.28
[Apache cxf] - Spring 에서 endpoint 설정하자  (0) 2010.06.28
[Apache cxf] - client remote ip 가져오자  (1) 2010.06.28
[CXF] - cxf 소개  (0) 2010.06.28
Posted by 짱가쟁이
우선은 JAX-WS 에서 soap 과 http binding 의 endpoint sample을 올린다. http binding은 RS 가 좀더 낳다는 의견이 많지만, soap과 같이 서비스하며, 코드를 재사용할 수 있다는 장점 때문에 WS를 사용하게 됨.

sample
<?xml version="1.0" encoding="UTF-8"?>

<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-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-http-binding.xml" />

<!-- The service bean -->
   <bean id="demoServiceImpl" class="cxf.demo.service.DemoServiceImpl" />

   <jaxws:endpoint id="getServiceHttp"
      implementor="#demoServiceImpl"
      implementorClass="cxf.demo.service.DemoService"
      address="/DemoService"
      bindingUri="http://apache.org/cxf/binding/http">
      <jaxws:serviceFactory>
         <ref bean="jaxWsServiceFactoryBean"/>
      </jaxws:serviceFactory>
   </jaxws:endpoint>
  
   <jaxws:endpoint
      id="getServiceSoap"
      implementor="#demoServiceImpl"
      implementorClass="cxf.demo.service.DemoService"
      address="/DemoService/soap" />
           
   <bean id="jaxWsServiceFactoryBean"
    class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean" scope="prototype">
      <property name="wrapped" value="false" />
   </bean>    
</beans>
<!-- END SNIPPET: beans -->


'framework > apache cxf' 카테고리의 다른 글

[Apache cxf] - session support  (0) 2010.06.28
[Apache cxf] - WSDL to Java  (0) 2010.06.28
[Apache cxf] cxf, axis2, metro 성능 비교  (0) 2010.06.28
[Apache cxf] - client remote ip 가져오자  (1) 2010.06.28
[CXF] - cxf 소개  (0) 2010.06.28
Posted by 짱가쟁이
졸라 할게 많아서 짜증이 나기는 하지만.. 하나하나 찾는 재미는 쏠쏠한듯..

밑에 코드는 웹 서비스에 Request를 보내는 넘의 IP를 가져오는 코드임

@Resource
private WebServiceContext context;
  
/**
* Clinet IP 를 가져온다.
* @return
*     remote ip
*/
private String getRemoteAddr() {
   MessageContext msgCtxt = context.getMessageContext();
   HttpServletRequest req = (HttpServletRequest)msgCtxt.get(MessageContext.SERVLET_REQUEST);
   String clientIP = req.getRemoteAddr();

   return clientIP;
}

'framework > apache cxf' 카테고리의 다른 글

[Apache cxf] - session support  (0) 2010.06.28
[Apache cxf] - WSDL to Java  (0) 2010.06.28
[Apache cxf] cxf, axis2, metro 성능 비교  (0) 2010.06.28
[Apache cxf] - Spring 에서 endpoint 설정하자  (0) 2010.06.28
[CXF] - cxf 소개  (0) 2010.06.28
Posted by 짱가쟁이
출처
 - http://www.ibm.com/developerworks/kr/library/j-jws12.html (Java 웹 서비스 : CXF 소개)
 - http://www.ibm.com/developerworks/kr/library/ws-pojo-springcxf/(CXF 와 스프링을 사용하는 웹 서비스 만들기 소개)

IBM developerworks 에 소개된 기사들임.

최근에 한글로 번역된듯해서 올린다.
Posted by 짱가쟁이
이전버튼 1 이전버튼