Apache CXF 개발 가이드


Red Hat Fuse 7.12

Apache CXF 웹 서비스를 사용하여 애플리케이션 개발

Red Hat Fuse Documentation Team

초록

Apache CXF를 사용하여 웹 서비스 개발 가이드.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 용어를 교체하기 위해 최선을 다하고 있습니다. 먼저 마스터(master), 슬레이브(slave), 블랙리스트(blacklist), 화이트리스트(whitelist) 등 네 가지 용어를 교체하고 있습니다. 이러한 변경 작업은 작업 범위가 크므로 향후 여러 릴리스에 걸쳐 점차 구현할 예정입니다. 자세한 내용은 CTO Chris Wright의 메시지에서 참조하십시오.

I 부. WSDL 계약 작성

이 부분에서는 WSDL을 사용하여 웹 서비스 인터페이스를 정의하는 방법을 설명합니다.

1장. WSDL 계약 소개

초록

WSDL 문서는 웹 서비스 설명 언어 및 여러 가능한 확장을 사용하여 서비스를 정의합니다. 문서에는 논리적 부분과 구체적인 부분이 있습니다. 계약의 요약 부분은 구현 중립 데이터 유형 및 메시지의 관점에서 서비스를 정의합니다. 문서의 구체적인 부분은 서비스를 구현하는 엔드 포인트가 외부 세계와 상호 작용하는 방법을 정의합니다.

서비스를 설계하는 데 권장되는 방법은 코드를 작성하기 전에 WSDL 및 XML 스키마에서 서비스를 정의하는 것입니다. WSDL 문서를 직접 편집할 때 문서가 올바른지 확인해야 합니다. 이렇게 하려면 WSDL에 대해 어느 정도 익숙해야 합니다. W3C 웹 사이트인 www.w3.org 에서 표준을 찾을 수 있습니다.

1.1. WSDL 문서의 구조

1.1.1. 개요

WSDL 문서는 가장 간단한 방법으로 루트 정의 요소에 포함된 요소 컬렉션입니다. 이러한 요소는 서비스와 해당 서비스를 구현하는 끝점에 대해 설명합니다.

WSDL 문서에는 다음 두 가지 부분이 있습니다.

  • 구현 중립 용어로 서비스를 정의하는 논리 부분
  • 서비스를 구현하는 끝점이 네트워크에서 노출되는 방법을 정의하는 구체적인 부분

1.1.2. 논리 부분

WSDL 문서의 논리 부분에는 유형, 메시지portType 요소가 포함되어 있습니다. 서비스의 인터페이스와 서비스에서 교환한 메시지를 설명합니다. 형식 요소 내에서 XML 스키마는 메시지를 구성하는 데이터의 구조를 정의하는 데 사용됩니다.Within the types element, XML Schema is used to define the structure of the data that makes up the messages. 여러 메시지 요소가 서비스에서 사용하는 메시지의 구조를 정의하는 데 사용됩니다. portType 요소에는 서비스에서 노출하는 작업에서 보낸 메시지를 정의하는 하나 이상의 작업 요소가 포함되어 있습니다.

1.1.3. 자세한 내용

WSDL 문서의 구체적인 부분은 바인딩서비스 요소를 포함합니다. 서비스를 구현하는 엔드포인트가 외부 세계에 연결하는 방법을 설명합니다. 바인딩 요소는 message 요소에 의해 설명된 데이터 단위가 issue-the-wire 데이터 형식과 같은 구체적인 데이터 형식으로 매핑되는 방법을 설명합니다. service 요소에는 서비스를 구현하는 엔드포인트를 정의하는 하나 이상의 포트 요소가 포함됩니다.

1.2. WSDL 요소

WSDL 문서는 다음 요소로 구성됩니다.

  • 정의 - WSDL 문서의 루트 요소입니다. 이 요소의 속성은 WSDL 문서의 이름, 문서의 대상 네임스페이스 및 WSDL 문서에서 참조하는 네임스페이스에 대한 간략한 정의를 지정합니다.
  • 유형 - 서비스에서 사용하는 메시지의 빌딩 블록을 형성하는 데이터 단위의 XML 스키마 정의입니다. 데이터 유형 정의에 대한 자세한 내용은 2장. 논리 데이터 단위 정의 을 참조하십시오.
  • Message - 서비스 작업을 호출하는 동안 교환되는 메시지에 대한 설명입니다. 이러한 요소는 서비스를 구성하는 작업의 인수를 정의합니다. 메시지 정의에 대한 자세한 내용은 3장. 서비스에서 사용하는 논리 메시지 정의 에서 참조하십시오.
  • portType - 서비스의 논리 인터페이스를 설명하는 작업 요소의 컬렉션입니다. 포트 유형 정의에 대한 자세한 내용은 4장. 논리 인터페이스 정의 을 참조하십시오.
  • 작업 - 서비스에서 수행한 작업에 대한 설명입니다. 작업은 작업이 호출될 때 두 끝점 간에 전달되는 메시지에 의해 정의됩니다. 작업 정의에 대한 자세한 내용은 “작업” 에서 참조하십시오.
  • 바인딩 - 끝점의 구체적인 데이터 형식 사양입니다. 바인딩 요소는 추상 메시지가 끝점에서 사용하는 구체적인 데이터 형식으로 매핑되는 방법을 정의합니다. 이 요소는 매개변수 순서 및 반환 값과 같은 세부 사항이 지정된 위치입니다.
  • Service - 관련 포트 요소의 컬렉션입니다. 이러한 요소는 끝점 정의를 설정하기 위한 리포지토리입니다.
  • port - 바인딩과 물리적 주소로 정의된 끝점입니다. 이러한 요소는 전송 세부 정보 정의와 결합된 모든 추상 정의를 결합하고 서비스가 노출되는 물리적 끝점을 정의합니다.

1.3. 계약 설계

서비스에 대한 WSDL 계약을 설계하려면 다음 단계를 수행해야 합니다.

  1. 서비스에서 사용하는 데이터 유형을 정의합니다.
  2. 서비스에서 사용하는 메시지를 정의합니다.
  3. 서비스의 인터페이스를 정의합니다.
  4. 각 인터페이스에서 사용하는 메시지와 유선 데이터의 구체적인 표현 간의 바인딩을 정의합니다.
  5. 각 서비스에 대한 전송 세부 정보를 정의합니다.

2장. 논리 데이터 단위 정의

초록

WSDL 계약 복잡한 데이터 유형의 서비스를 설명하는 경우 XML 스키마를 사용하여 논리 단위로 정의됩니다.

2.1. 논리 데이터 단위 소개

서비스를 정의할 때 가장 먼저 고려해야 할 사항은 노출된 작업에 대한 매개 변수로 사용되는 데이터가 표시되는 방법입니다. 고정 데이터 구조를 사용하는 프로그래밍 언어로 작성된 애플리케이션과 달리 서비스는 여러 애플리케이션에서 사용할 수 있는 논리 단위로 데이터를 정의해야 합니다. 여기에는 다음 두 단계가 포함됩니다.

  1. 데이터를 서비스의 물리적 구현에서 사용하는 데이터 유형으로 매핑할 수 있는 논리 단위로 데이터를 분할
  2. 논리 단위를 끝점 간에 전달되는 메시지에 결합하여 작업을 수행합니다.

이 장에서는 첫 번째 단계에 대해 설명합니다. 3장. 서비스에서 사용하는 논리 메시지 정의 두 번째 단계에 대해 설명합니다.

2.2. 데이터를 논리 데이터 단위로 매핑

2.2.1. 개요

서비스를 구현하는 데 사용되는 인터페이스는 작업 매개 변수를 XML 문서로 나타내는 데이터를 정의합니다. 이미 구현된 서비스에 대한 인터페이스를 정의하는 경우 구현된 작업의 데이터 형식을 메시지로 어셈블할 수 있는 불일치 XML 요소로 변환해야 합니다. 처음부터 시작하는 경우 메시지가 빌드되는 빌딩 블록을 결정하여 구현 관점에서 이해할 수 있도록 해야 합니다.

2.2.2. 서비스 데이터 단위를 정의하는 데 사용 가능한 유형 시스템

WSDL 사양에 따라 선택한 모든 유형 시스템을 사용하여 WSDL 계약에서 데이터 유형을 정의할 수 있습니다. 그러나 W3C 사양에서는 XML 스키마가 WSDL 문서에 대해 기본 표준 유형 시스템이라고 명시되어 있습니다. 따라서 XML 스키마는 Apache CXF의 내장 유형 시스템입니다.

2.2.3. 유형 시스템으로 XML 스키마

XML 스키마는 XML 문서가 구성된 방법을 정의하는 데 사용됩니다. 이 작업은 문서를 구성하는 요소를 정의하여 수행됩니다. 이러한 요소는 xsd:int 와 같은 네이티브 XML 스키마 유형을 사용하거나 사용자가 정의한 형식을 사용할 수 있습니다. 사용자 정의 형식은 XML 요소의 조합을 사용하여 빌드되거나 기존 형식을 제한하여 정의됩니다. 형식 정의 및 요소 정의를 결합하여 복잡한 데이터를 포함할 수 있는 복잡한 XML 문서를 만들 수 있습니다.By combining type definitions and element definitions you can create in complex XML documents that can contain complex data.

WSDL XML 스키마에서 사용되는 경우 서비스와 상호 작용하는 데 사용되는 데이터를 보유하는 XML 문서의 구조를 정의합니다. 서비스에서 사용하는 데이터 단위를 정의할 때 메시지 부분의 구조를 지정하는 유형으로 정의할 수 있습니다. 데이터 단위를 메시지 부분을 구성하는 요소로 정의할 수도 있습니다.

2.2.4. 데이터 단위 생성에 대한 고려 사항

단순히 서비스를 구현할 때 사용하여 예상하는 유형에 직접 매핑되는 논리 데이터 단위를 생성하는 것을 고려할 수 있습니다. 이 접근 방식은 작동하고 RPC 스타일 애플리케이션 빌드 모델을 밀접하게 따르지만 서비스 지향 아키텍처의 일부를 빌드하는 데 반드시 이상적인 것은 아닙니다.

웹 서비스 상호 운용성 조직의 WS-I 기본 프로필은 데이터 단위를 정의하기위한 여러 지침을 제공하며 http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#WSDLTYPES 에서 액세스할 수 있습니다. 또한 W3C는 XML 스키마를 사용하여 WSDL 문서의 데이터 유형을 나타내는 다음 지침도 제공합니다.

  • 속성이 아닌 요소를 사용합니다.
  • 프로토콜별 유형을 기본 유형으로 사용하지 마십시오.

2.3. 계약에 데이터 단위 추가

2.3.1. 개요

WSDL 계약을 만들기로 선택하는 방법에 따라 새로운 데이터 정의를 생성하려면 다양한 양의 지식이 필요합니다. Apache CXF GUI 툴에서는 XML 스키마를 사용하여 데이터 유형을 설명하는 다양한 지원을 제공합니다. 다른 XML 편집기는 다양한 수준의 지원을 제공합니다. 선택한 편집기에 관계없이 결과 계약이 어떻게 표시되는지에 대한 지식이 있어야 합니다.

2.3.2. 절차

WSDL 계약에 사용되는 데이터를 정의하려면 다음 단계를 수행해야 합니다.

  1. 계약에 의해 설명된 인터페이스에 사용되는 모든 데이터 유닛을 결정합니다.
  2. 계약에 형식 요소를 만듭니다.Create a type element in your contract.
  3. 예 2.1. “WSDL 계약의 스키마 항목” 에 표시된 스키마 요소를 type 요소의 하위 항목으로 생성합니다.

    targetNamespace 속성은 새 데이터 형식이 정의된 네임스페이스를 지정합니다. 가장 좋은 방법은 대상 네임스페이스에 대한 액세스를 제공하는 네임스페이스도 정의하는 것입니다. 나머지 항목은 변경하지 않아야 합니다.

    예 2.1. WSDL 계약의 스키마 항목

    <schema targetNamespace="http://schemas.iona.com/bank.idl"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:xsd1="http://schemas.iona.com/bank.idl"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    Copy to Clipboard Toggle word wrap
  4. 요소의 컬렉션인 각 복잡한 형식에 대해 complexType 요소를 사용하여 데이터 형식을 정의합니다. 2.5.1절. “데이터 구조 정의”을 참조하십시오.
  5. 각 배열에 대해 complexType 요소를 사용하여 데이터 형식을 정의합니다. 2.5.2절. “배열 정의”을 참조하십시오.
  6. 간단한 유형에서 파생되는 각 복잡한 형식에 대해 simpleType 요소를 사용하여 데이터 형식을 정의합니다. 2.5.4절. “제한적으로 유형 정의”을 참조하십시오.
  7. 각 열거된 형식에 대해 simpleType 요소를 사용하여 데이터 형식을 정의합니다. 2.5.5절. “열거된 유형 정의”을 참조하십시오.
  8. 각 요소에 대해 element 요소를 사용하여 정의합니다. 2.6절. “요소 정의”을 참조하십시오.

2.4. XML 스키마 간단한 유형

2.4.1. 개요

메시지 부분이 간단한 유형이 될 경우 해당 부분에 대한 유형 정의를 생성할 필요가 없습니다. 그러나 계약에 정의된 인터페이스에서 사용하는 복잡한 유형은 간단한 유형을 사용하여 정의됩니다.

2.4.2. 간단한 유형 입력

XML 스키마 간단한 유형은 주로 계약의 유형 섹션에서 사용되는 요소 요소에 배치됩니다. 또한 제한 요소 및 확장 요소의 기본 특성에 사용됩니다.

단순 유형은 항상 xsd 접두사를 사용하여 입력합니다. 예를 들어 요소가 int 유형임을 지정하려면 예 2.2. “간단한 유형으로 요소 정의” 에 표시된 대로 type 속성에 xsd:int 를 입력합니다.

예 2.2. 간단한 유형으로 요소 정의

<element name="simpleInt" type="xsd:int" />
Copy to Clipboard Toggle word wrap

2.4.3. 지원되는 XSD 간단한 유형

Apache CXF는 다음과 같은 XML 스키마 간단한 유형을 지원합니다.

  • xsd:string
  • xsd:normalizedString
  • xsd:int
  • xsd:unsignedInt
  • xsd:long
  • xsd:unsignedLong
  • xsd:short
  • xsd:unsignedShort
  • xsd:float
  • xsd:double
  • xsd:boolean
  • xsd:byte
  • xsd:unsignedByte
  • xsd:integer
  • xsd:positiveInteger
  • xsd:negativeInteger
  • xsd:nonPositiveInteger
  • xsd:nonNegativeInteger
  • xsd:decimal
  • xsd:dateTime
  • xsd:time
  • xsd:date
  • xsd:QName
  • xsd:base64Binary
  • xsd:hexBinary
  • xsd:ID
  • xsd:token
  • xsd:language
  • xsd:Name
  • xsd:NCName
  • xsd:NMTOKEN
  • xsd:anySimpleType
  • xsd:anyURI
  • xsd:gYear
  • xsd:gMonth
  • xsd:gDay
  • xsd:gYearMonth
  • xsd:gMonthDay

2.5. 복잡한 데이터 유형 정의

초록

XML 스키마는 간단한 데이터 유형에서 복잡한 데이터 구조를 구축하기 위한 유연하고 강력한 메커니즘을 제공합니다. 요소 및 특성의 시퀀스를 만들어 데이터 구조를 생성할 수 있습니다. 정의된 형식을 확장하여 더 복잡한 유형을 만들 수도 있습니다.

복잡한 데이터 구조를 빌드하는 것 외에도 열거된 형식, 특정 값 범위가 있는 데이터 형식 또는 기본 형식을 확장하거나 제한하여 특정 패턴을 따라야 하는 데이터 유형을 설명할 수도 있습니다.In addition to building complex data structures, you can also describe specialized types such as enumerated types, data types that have a specific range of values, or data types that need to follow certain patterns by either extending or restricting the primitive types.

2.5.1. 데이터 구조 정의

2.5.1.1. 개요

XML 스키마에서는 데이터 필드의 컬렉션인 데이터 단위는 complexType 요소를 사용하여 정의됩니다. 복잡한 유형을 지정하려면 다음 세 가지 정보가 필요합니다.

  1. 정의된 형식의 이름은 complexType 요소의 name 특성에 지정됩니다.
  2. complexType 의 첫 번째 자식 요소는 전선에 배치되었을 때의 구조 필드의 동작을 설명합니다. “복잡한 유형 변수”을 참조하십시오.
  3. 정의된 구조의 각 필드는 complexType 요소의 할아자인 요소 요소에 정의됩니다. “구조의 부분 정의”을 참조하십시오.

예를 들어 예 2.3. “간단한 structure” 에 표시된 구조는 두 개의 요소가 있는 복잡한 유형으로 XML 스키마에 정의됩니다.

예 2.3. 간단한 structure

struct personalInfo
{
  string name;
  int age;
};
Copy to Clipboard Toggle word wrap

예 2.4. “복잡한 유형” 예 2.3. “간단한 structure” 에 정의된 구조에 대해 하나의 가능한 XML 스키마 매핑을 표시합니다. 예 2.4. “복잡한 유형” 에 정의된 구조는 nameage 라는 두 개의 요소가 포함된 메시지를 생성합니다.

.

예 2.4. 복잡한 유형

<complexType name="personalInfo">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="age" type="xsd:int" />
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap
2.5.1.2. 복잡한 유형 변수

XML 스키마에는 복잡한 유형의 필드가 XML 문서로 표시되고 유선에 전달되는 방법을 설명하는 세 가지 방법이 있습니다. complexType 요소의 첫 번째 자식 요소는 사용 중인 다양한 복잡한 유형을 결정합니다. 표 2.1. “복잡한 유형 설명자 요소” 복잡한 형식 동작을 정의하는 데 사용되는 요소를 표시합니다.Shows the elements used to define complex type behavior.

Expand
표 2.1. 복잡한 유형 설명자 요소
element복잡한 유형 동작

순서

복잡한 유형의 필드가 모두 존재할 수 있으며 형식 정의에 지정된 순서에 따라 있어야 합니다.

all

복잡한 유형의 필드는 모두 존재할 수 있지만 순서에 따라 있을 수 있습니다.

선택

구조의 요소 중 하나만 메시지에 배치할 수 있습니다.

예 2.5. “복잡한 선택 유형” 에 표시된 대로 선택 요소를 사용하여 구조를 정의하면 name 요소 또는 age 요소가 있는 메시지를 생성합니다.

예 2.5. 복잡한 선택 유형

<complexType name="personalInfo">
  <choice>
    <element name="name" type="xsd:string"/>
    <element name="age" type="xsd:int"/>
  </choice>
</complexType>
Copy to Clipboard Toggle word wrap
2.5.1.3. 구조의 부분 정의

요소 요소를 사용하여 구조를 구성하는 데이터 필드를 정의합니다. 모든 complexType 요소에는 하나 이상의 요소가 포함되어야 합니다. complexType 요소의 각 요소는 정의된 데이터 구조의 필드를 나타냅니다.

데이터 구조의 필드를 완전히 설명하려면 요소 요소에 는 두 가지 필수 특성이 있습니다.

  • name 속성은 데이터 필드의 이름을 지정하고 정의된 복잡한 유형 내에서 고유해야 합니다.
  • type 속성은 필드에 저장된 데이터의 유형을 지정합니다. 형식은 XML 스키마 간단한 유형 중 하나이거나 계약에 정의된 이름이 지정된 복잡한 유형 중 하나일 수 있습니다.

nametype 외에도요소 요소에minOcurrsmax occur라는 두 가지 다른 일반적으로 사용되는 선택적 속성이 있습니다. 이러한 속성은 구조에서 필드가 발생하는 횟수에 바인딩된 위치를 지정합니다. 기본적으로 각 필드는 복잡한 유형에서 한 번만 수행됩니다. 이러한 특성을 사용하여 필드에 사용해야 하거나 구조에 나타날 수 있는 횟수를 변경할 수 있습니다. 예를 들어 예 2.6. “발생 제약 조건이 있는 간단한 복잡한 유형” 에 표시된 것처럼 최소 3번 이상 발생해야 하는 이전Jobs 필드를 정의할 수 있습니다.

예 2.6. 발생 제약 조건이 있는 간단한 복잡한 유형

<complexType name="personalInfo">
  <all>
    <element name="name" type="xsd:string"/>
    <element name="age" type="xsd:int"/>
    <element name="previousJobs" type="xsd:string:
             minOccurs="3" maxOccurs="7"/>
  </all>
</complexType>
Copy to Clipboard Toggle word wrap

또한 min Cryostat를 사용하여 예 2.7. “min#187가 0으로 설정된 간단한 복잡한 유형” 에 표시된 대로 min #187를 0으로 설정하여 수명 필드를 선택 사항으로 만들 수도 있습니다. 이 경우 수명은 생략할 수 있으며 데이터는 계속 유효합니다.

예 2.7. min#187가 0으로 설정된 간단한 복잡한 유형

<complexType name="personalInfo">
  <choice>
    <element name="name" type="xsd:string"/>
    <element name="age" type="xsd:int" minOccurs="0"/>
  </choice>
</complexType>
Copy to Clipboard Toggle word wrap
2.5.1.4. 속성 정의

XML 문서에는 속성이 요소의 태그에 포함됩니다. 예를 들어 아래 코드의 complexType 요소에서 name 은 특성입니다. 복잡한 형식에 대한 특성을 지정하려면 complexType 요소 정의에 특성 요소를 정의합니다. 특성 요소는 all,sequence 또는 choice 요소 후에만 나타날 수 있습니다. 각 복잡한 유형의 속성에 대해 하나의 특성 요소를 지정합니다. 모든 특성 요소는 complexType 요소의 직접적인 자식이어야 합니다.

예 2.8. 속성이 있는 복잡한 유형

<complexType name="personalInfo">
  <all>
    <element name="name" type="xsd:string"/>
    <element name="previousJobs" type="xsd:string"
             minOccurs="3" maxOccurs="7"/>
  </all>
  <attribute name="age" type="xsd:int" use="required" />
</complexType>
Copy to Clipboard Toggle word wrap

이전 코드에서 특성 요소는 personalInfo 복잡한 형식에 age 특성이 있음을 지정합니다. 특성 요소에는 다음과 같은 특성이 있습니다.

  • name - 특성을 식별하는 문자열을 지정하는 필수 특성입니다.
  • type - 필드에 저장된 데이터 유형을 지정합니다. 형식은 XML 스키마 간단한 유형 중 하나일 수 있습니다.
  • use - 이 특성을 갖는 데 복잡한 유형이 필요한지 여부를 지정하는 선택적 특성입니다. 유효한 값은 필수 또는 선택 사항입니다. 기본값은 속성이 선택 사항이라는 것입니다.

특성 요소에서는 특성의 기본값 을 지정할 수 있는 선택적 기본 특성을 지정할 수 있습니다.

2.5.2. 배열 정의

2.5.2.1. 개요

Apache CXF는 계약에 배열을 정의하는 두 가지 방법을 지원합니다. 첫 번째는 max #187 특성의 값이 두 개 이상인 단일 요소를 사용하여 복잡한 형식을 정의합니다. 두 번째는 Cryostat 배열을 사용하는 것입니다. Cryo stat 배열은 다차원 배열을 쉽게 정의하고 스파스적으로 채워진 배열을 전송할 수 있는 기능과 같은 추가 기능을 제공합니다.

2.5.2.2. 복잡한 유형 배열

복잡한 유형 배열은 시퀀스 복잡한 유형의 특수한 사례입니다. 간단히 단일 요소를 사용하여 복잡한 형식을 정의하고 max #187 특성에 값을 지정합니다. 예를 들어 20개의 부동 소수점 숫자 배열을 정의하려면 예 2.9. “복잡한 유형 배열” 에 표시된 것과 유사한 복잡한 유형을 사용합니다.

예 2.9. 복잡한 유형 배열

<complexType name="personalInfo">
  <element name="averages" type="xsd:float" maxOccurs="20"/>
</complexType>
Copy to Clipboard Toggle word wrap

min #187 속성의 값을 지정할 수도 있습니다.

2.5.2.3. Cryostat 배열

Cryostat 배열은 wsdl:arrayType 요소를 사용하여 Cryostat -ENC:Array 기본 유형에서 파생하여 정의됩니다. 이 구문은 예 2.10. “wsdl:arrayType을 사용하여 파생된 Cryostat 배열의 구문” 에 표시됩니다. definitions 요소가 SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 를 선언하는지 확인합니다.

예 2.10. wsdl:arrayType을 사용하여 파생된 Cryostat 배열의 구문

<complexType name="TypeName">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <attribute ref="SOAP-ENC:arrayType"
                 wsdl:arrayType="ElementType<ArrayBounds>"/>
    </restriction>
  </complexContent>
</complexType>
Copy to Clipboard Toggle word wrap

이 구문을 사용하여 TypeName 은 새로 정의된 배열 유형의 이름을 지정합니다. elementType 은 배열의 요소 유형을 지정합니다. ArrayBounds 배열의 차원 수를 지정합니다. 단일 차원 배열을 지정하려면 [] 를 사용합니다. 2차원 배열을 지정하려면 [][] 또는 [,] 을 사용합니다.

예를 들어 예 2.11. “Cryostat 배열의 정의” 에 표시된 Cryostat 배열, CryostatStrings는 1차원 문자열 배열을 정의합니다. wsdl:arrayType 속성은 배열 요소의 유형을 지정하며, xsd:string 및 차원 수는 [] 차원을 의미합니다.

예 2.11. Cryostat 배열의 정의

<complexType name="SOAPStrings">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <attribute ref="SOAP-ENC:arrayType"
                 wsdl:arrayType="xsd:string[]"/>
    </restriction>
  </complexContent>
</complexType>
Copy to Clipboard Toggle word wrap

Cryostat 1.1 사양에 설명된 대로 간단한 요소를 사용하여 Cryostat 배열을 설명할 수도 있습니다. 이 구문은 예 2.12. “요소를 사용하여 파생된 Cryostat 배열의 구문” 에 표시됩니다.

예 2.12. 요소를 사용하여 파생된 Cryostat 배열의 구문

<complexType name="TypeName">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <sequence>
        <element name="ElementName" type="ElementType"
                 maxOccurs="unbounded"/>
      </sequence>
    </restriction>
  </complexContent>
</complexType>
Copy to Clipboard Toggle word wrap

이 구문을 사용하는 경우 요소의 max Cryostat 속성을 항상 unbounded 로 설정해야 합니다.

2.5.3. 확장별 유형 정의

대부분의 주요 코딩 언어와 마찬가지로 XML 스키마를 사용하면 다른 데이터 유형에서 일부 요소를 상속하는 데이터 유형을 만들 수 있습니다. 이를 확장에 따른 유형 정의라고 합니다. 예를 들어, 다음과 같은 새 유형을 생성하여 예 2.4. “복잡한 유형” 에 정의된 personal Info 구조를 확장한 새 유형을 생성할 수 있습니다. 즉, Earth라는 새 요소를 추가하여 에 정의된 personalInfo 구조를 확장할 수 있습니다.

확장으로 정의된 유형에는 다음 네 가지 부분이 있습니다.

  1. 유형 이름은 complexType 요소의 name 특성에 따라 정의됩니다.
  2. complexContent 요소는 새 형식에 둘 이상의 요소가 포함되도록 지정합니다.

    참고

    복잡한 유형에 새 특성만 추가하는 경우 simpleContent 요소를 사용할 수 있습니다.

  3. 기본 유형이라고 하는 새 형식이 파생되는 형식은 확장 요소의 기본 특성에 지정됩니다.
  4. 새 유형의 요소 및 특성은 확장 요소에 정의되어 있으며 일반 복잡한 형식에도 마찬가지입니다.

예를 들어, Ali Info예 2.13. “확장에 의해 정의된 유형” 에 표시된 대로 정의됩니다.

예 2.13. 확장에 의해 정의된 유형

<complexType name="alienInfo">
  <complexContent>
    <extension base="xsd1:personalInfo">
      <sequence>
        <element name="planet" type="xsd:string"/>
      </sequence>
    </extension>
  </complexContent>
</complexType>
Copy to Clipboard Toggle word wrap

2.5.4. 제한적으로 유형 정의

2.5.4.1. 개요

XML 스키마를 사용하면 XML 스키마 간단한 유형의 가능한 값을 제한하여 새 형식을 만들 수 있습니다. 예를 들어 간단한 유형인 SSN 을 정의할 수 있습니다. 정확히 9자 문자열입니다. 간단한 형식을 제한하여 정의된 새 형식은 simpleType 요소를 사용하여 정의됩니다.

제한적으로 유형의 정의에는 다음 세 가지가 필요합니다.

  1. 새 형식의 이름은 simpleType 요소의 name 특성에 따라 지정됩니다.
  2. 기본 유형이라고 하는 새 형식이 파생되는 simple 유형은 restriction 요소에 지정됩니다. “기본 유형 지정”을 참조하십시오.
  3. facet 라는 규칙은 기본 유형에 배치된 제한을 정의하는 제한 사항은 제한 요소의 하위 항목으로 정의됩니다. “제한 사항 정의”을 참조하십시오.
2.5.4.2. 기본 유형 지정

기본 유형은 새 유형을 정의하도록 제한되는 유형입니다. restriction 요소를 사용하여 지정합니다. restriction 요소는 simpleType 요소의 유일한 자식이며 기본 유형을 지정하는 하나의 특성인 base 입니다. 기본 유형은 XML 스키마 간단한 유형 중 하나일 수 있습니다.

예를 들어 xsd:int 의 값을 제한하여 새 유형을 정의하려면 예 2.14. “int를 기본 유형으로 사용” 에 표시된 것과 같은 정의를 사용합니다.

예 2.14. int를 기본 유형으로 사용

<simpleType name="restrictedInt">
  <restriction base="xsd:int">
    ...
  </restriction>
</simpleType>
Copy to Clipboard Toggle word wrap
2.5.4.3. 제한 사항 정의

기본 유형에 배치된 제한을 정의하는 규칙을 facet 라고 합니다. facet는 facet를 적용하는 방법을 정의하는 하나의 속성인 값이 있는 요소입니다. 사용 가능한 facet 및 유효한 설정은 기본 유형에 따라 다릅니다. 예를 들어 xsd:string 은 다음을 포함하여 6개의 facet를 지원합니다.

  • length
  • minLength
  • maxLength
  • 패턴
  • whitespace
  • 열거

각 facet 요소는 restriction 요소의 자식입니다.

2.5.4.4. 예제

예 2.15. “SSN 간단한 유형 설명” 소셜 보안 번호를 나타내는 간단한 유형 SSN 의 예를 보여줍니다. 결과 유형은 xxx-xx-xxxx 형식의 문자열입니다. <SSN>032-43-9876<SSN>은 이 유형의 요소에 유효한 값이지만 <SSN>032439876</SSN>은 그렇지 않습니다.

예 2.15. SSN 간단한 유형 설명

<simpleType name="SSN">
  <restriction base="xsd:string">
    <pattern value="\d{3}-\d{2}-\d{4}"/>
  </restriction>
</simpleType>
Copy to Clipboard Toggle word wrap

2.5.5. 열거된 유형 정의

2.5.5.1. 개요

XML 스키마의 열거 형식은 제한에 따라 정의의 특수한 사례입니다. 이는 모든 XML 스키마 기본 유형에서 지원하는 열거 facet를 사용하여 설명됩니다. 최신 프로그래밍 언어의 열거된 형식과 마찬가지로 이 형식의 변수에는 지정된 값 중 하나만 있을 수 있습니다.As with enumerated types in most modern programming languages, a variable of this type can only have one of the specified values.

2.5.5.2. XML 스키마에서 열거 정의

열거를 정의하는 구문은 예 2.16. “열거의 구문” 에 표시됩니다.

예 2.16. 열거의 구문

<simpleType name="EnumName">
  <restriction base="EnumType">
    <enumeration value="Case1Value"/>
    <enumeration value="Case2Value"/>
    ...
    <enumeration value="CaseNValue"/>
  </restriction>
</simpleType>
Copy to Clipboard Toggle word wrap

EnumName 은 열거 유형의 이름을 지정합니다. EnumType 은 대소문자 값의 유형을 지정합니다. CaseNValues(여기서 N은 숫자 1 이상)는 열거자의 각 특정 사례에 대한 값을 지정합니다.Critical caseNValue, where N is any number one or greater, specifies the value for each specific case of the enumeration. 열거된 형식에는 임의의 수의 대소문자 값이 있을 수 있지만 간단한 유형에서 파생되므로 한 번에 하나의 case 값만 유효합니다.

2.5.5.3. 예제

예를 들어, 열거 위젯Size에 정의된 요소가 있는 XML 문서는 < widgetSize >big</widgetSize>가 포함된 경우 유효하지만 <widgetSize>big,mungo</widgetSize>가 포함된 경우 유효하지 않습니다. 예 2.17. “widgetSize 열거”

예 2.17. widgetSize 열거

<simpleType name="widgetSize">
  <restriction base="xsd:string">
    <enumeration value="big"/>
    <enumeration value="large"/>
    <enumeration value="mungo"/>
  </restriction>
</simpleType>
Copy to Clipboard Toggle word wrap

2.6. 요소 정의

XML 스키마의 요소는 스키마에서 생성된 XML 문서의 요소 인스턴스를 나타냅니다. 가장 기본적인 요소는 단일 요소 요소로 구성됩니다. 복잡한 유형의 멤버를 정의하는 데 사용되는 요소 요소와 마찬가지로 세 가지 속성이 있습니다.

  • name - XML 문서에 표시되는 요소의 이름을 지정하는 필수 특성입니다.
  • type - 요소의 유형을 지정합니다. 유형은 모든 XML 스키마 기본 유형 또는 계약에 정의된 이름이 지정된 복잡한 유형일 수 있습니다. 유형에 인라인 정의가 있는 경우 이 속성을 생략할 수 있습니다.
  • nillable - 요소에서 완전히 생략할 수 있는지 여부를 지정합니다. nillabletrue 로 설정된 경우 스키마를 사용하여 생성된 모든 문서에서 요소를 생략할 수 있습니다.

요소에는 인라인 유형 정의가 있을 수도 있습니다. 인라인 유형은 complexType 요소 또는 simpleType 요소를 사용하여 지정됩니다. 데이터 유형이 복잡하거나 간단한지 지정하면 각 데이터 유형에 사용할 수 있는 도구를 사용하여 필요한 모든 유형의 데이터를 정의할 수 있습니다. 인라인 유형 정의는 재사용 가능하지 않기 때문에 권장되지 않습니다.

3장. 서비스에서 사용하는 논리 메시지 정의

초록

서비스는 작업이 호출될 때 교환되는 메시지에 의해 정의됩니다. WSDL 계약에서 이러한 메시지는 message 요소를 사용하여 정의됩니다. 메시지는 part 요소를 사용하여 정의된 하나 이상의 부분으로 구성됩니다.

3.1. 개요

서비스의 작업은 작업이 호출될 때 교환되는 논리 메시지를 지정하여 정의합니다. 이러한 논리 메시지는 네트워크를 통해 XML 문서로 전달되는 데이터를 정의합니다. 여기에는 메서드 호출의 일부인 모든 매개 변수가 포함됩니다. 논리 메시지는 계약에서 message 요소를 사용하여 정의됩니다. 각 논리 메시지는 part 요소에 정의된 하나 이상의 부분으로 구성됩니다.

메시지는 각 매개변수를 별도의 부분으로 나열할 수 있지만 권장되는 방법은 작업에 필요한 데이터를 캡슐화하는 단일 부분만 사용하는 것입니다.

3.2. 메시지 및 매개변수 목록

서비스에 의해 노출되는 각 작업에는 하나의 입력 메시지와 하나의 출력 메시지만 있을 수 있습니다. 입력 메시지는 작업이 호출될 때 서비스가 수신하는 모든 정보를 정의합니다. 출력 메시지는 작업이 완료될 때 서비스가 반환하는 모든 데이터를 정의합니다. 오류 메시지는 오류가 발생할 때 서비스에서 반환하는 데이터를 정의합니다.

또한 각 작업에는 여러 오류 메시지가 있을 수 있습니다. 오류 메시지는 서비스에 오류가 발생할 때 반환되는 데이터를 정의합니다. 이러한 메시지에는 일반적으로 소비자가 오류를 이해할 수 있는 충분한 정보를 제공하는 하나의 부분만 있습니다.

3.3. 레거시 시스템과 통합을 위한 메시지 설계

기존 애플리케이션을 서비스로 정의하는 경우 작업을 구현하는 메서드에서 사용하는 각 매개 변수가 메시지에 표시되도록 해야 합니다. 반환 값이 작업의 출력 메시지에 포함되어 있는지도 확인해야 합니다.

메시지를 정의하는 한 가지 방법은 RPC 스타일입니다. RPC 스타일을 사용할 때 메서드의 매개 변수 목록의 각 매개 변수에 대해 한 부분을 사용하여 메시지를 정의합니다. 각 메시지 부분은 계약의 유형 요소에 정의된 형식을 기반으로 합니다. 입력 메시지에는 메서드의 각 입력 매개변수에 대한 한 부분이 포함되어 있습니다. 출력 메시지에는 각 출력 매개변수에 대한 한 부분과 반환 값을 나타내는 부분이 포함됩니다(필요한 경우). 매개 변수가 input 매개 변수와 출력 매개 변수인 경우 입력 메시지와 출력 메시지의 일부로 나열됩니다.

RPC 스타일 메시지 정의는 Tibco 또는 CORBA와 같은 전송을 사용하는 레거시 시스템을 서비스할 때 유용합니다. 이러한 시스템은 절차 및 방법을 중심으로 설계되었습니다. 따라서 호출되는 작업의 매개 변수 목록과 유사한 메시지를 사용하여 쉽게 모델링할 수 있습니다. RPC 스타일은 서비스와 노출 중인 애플리케이션 간에 보다 깔끔한 매핑을 만듭니다.

3.4. Cryostat 서비스에 대한 메시지 설계

RPC 스타일은 기존 시스템을 모델링하는 데 유용하지만 서비스의 커뮤니티는 래핑된 문서 스타일을 적극 권장합니다. 래핑된 문서 스타일에서는 각 메시지에 단일 부분이 있습니다. 메시지의 부분은 계약의 types 요소에 정의된 래퍼 요소를 참조합니다. 래퍼 요소에는 다음과 같은 특징이 있습니다.

  • 요소의 시퀀스를 포함하는 복잡한 형식입니다. 자세한 내용은 2.5절. “복잡한 데이터 유형 정의” 에서 참조하십시오.
  • 입력 메시지에 대한 래퍼인 경우:

    • 각 메서드의 입력 매개 변수에 대해 하나의 요소가 있습니다.
    • 해당 이름은 연결된 작업의 이름과 동일합니다.
  • 출력 메시지에 대한 래퍼인 경우:

    • 각 메서드의 출력 매개 변수에 대해 하나의 요소와 메서드의 inout 매개변수 각각에 대해 하나의 요소가 있습니다.
    • 첫 번째 요소는 메서드의 반환 매개 변수를 나타냅니다.
    • 래퍼가 연결된 작업의 이름에 Response 를 추가하여 해당 이름이 생성됩니다.

3.5. 메시지 이름 지정

계약의 각 메시지는 해당 네임스페이스 내에 고유한 이름이 있어야 합니다. 다음 명명 규칙을 사용하는 것이 좋습니다.

  • 메시지는 단일 작업에서만 사용해야 합니다.
  • 입력 메시지 이름은 작업 이름에 요청을 추가하여 구성됩니다.
  • 출력 메시지 이름은 작업 이름에 Response 를 추가하여 구성됩니다.
  • 오류 메시지 이름은 오류의 이유를 나타냅니다.

3.6. 메시지 부분

메시지 부분은 논리 메시지의 공식 데이터 단위입니다. 각 부분은 part 요소를 사용하여 정의되며 name 특성과 type 특성 또는 해당 데이터 유형을 지정하는 요소 특성으로 식별됩니다. 데이터 유형 속성은 표 3.1. “파트 데이터 유형 속성” 에 나열됩니다.

Expand
표 3.1. 파트 데이터 유형 속성
속성설명

element="elem_name"

부분의 데이터 유형은 elem_name 이라는 요소로 정의됩니다.

type="type_name"

부분의 데이터 유형은 type_name 이라는 유형으로 정의됩니다.

메시지는 부분 이름을 재사용할 수 있습니다. 예를 들어, 메서드에 참조로 전달되거나 in/out 매개변수가 있는 경우 예 3.1. “재사용된 부분” 에 표시된 것처럼 요청 메시지와 응답 메시지의 일부일 수 있습니다.

예 3.1. 재사용된 부분

<message name="fooRequest">
  <part name="foo" type="xsd:int"/>
<message>
<message name="fooReply">
  <part name="foo" type="xsd:int"/>
<message>
Copy to Clipboard Toggle word wrap

3.7. 예제

예를 들어, 개인 정보를 저장하고 직원의 ID 번호를 기반으로 직원의 데이터를 반환하는 방법을 제공한 서버가 있다고 가정해 보겠습니다. 데이터를 검색하는 방법 서명은 예 3.2. “personalInfo 조회 방법” 과 유사합니다.

예 3.2. personalInfo 조회 방법

personalInfo lookup(long empId)
Copy to Clipboard Toggle word wrap

이 메서드 서명을 예 3.3. “RPC WSDL 메시지 정의” 에 표시된 RPC 스타일 WSDL 조각에 매핑할 수 있습니다.

예 3.3. RPC WSDL 메시지 정의

<message name="personalLookupRequest">
  <part name="empId" type="xsd:int"/>
<message/>
<message name="personalLookupResponse>
  <part name="return" element="xsd1:personalInfo"/>
<message/>
Copy to Clipboard Toggle word wrap

또한 예 3.4. “래핑된 문서 WSDL 메시지 정의” 에 표시된 래핑된 문서 스타일 WSDL 조각에 매핑할 수도 있습니다.

예 3.4. 래핑된 문서 WSDL 메시지 정의

<wsdl:types>
  <xsd:schema ... >
  ...
  <element name="personalLookup">
    <complexType>
      <sequence>
        <element name="empID" type="xsd:int" />
      </sequence>
    </complexType>
  </element>
  <element name="personalLookupResponse">
    <complexType>
      <sequence>
        <element name="return" type="personalInfo" />
      </sequence>
    </complexType>
  </element>
  </schema>
</types>
<wsdl:message name="personalLookupRequest">
  <wsdl:part name="empId" element="xsd1:personalLookup"/>
<message/>
<wsdl:message name="personalLookupResponse">
  <wsdl:part name="return" element="xsd1:personalLookupResponse"/>
<message/>
Copy to Clipboard Toggle word wrap

4장. 논리 인터페이스 정의

초록

논리 서비스 인터페이스는 portType 요소를 사용하여 정의됩니다.

4.1. 개요

논리 서비스 인터페이스는 WSDL portType 요소를 사용하여 정의됩니다. portType 요소는 추상 작업 정의 컬렉션입니다. 각 작업은 작업이 나타내는 트랜잭션을 완료하는 데 사용되는 입력, 출력 및 오류 메시지에 의해 정의됩니다. portType 요소에서 정의한 서비스 인터페이스를 구현하기 위해 코드가 생성되면 각 작업은 계약에 지정된 입력, 출력 및 오류 메시지에 정의된 매개 변수를 포함하는 메서드로 변환됩니다.

4.2. 프로세스

WSDL 계약에 논리 인터페이스를 정의하려면 다음을 수행해야 합니다.

  1. 인터페이스 정의를 포함하는 portType 요소를 생성하고 고유한 이름을 지정합니다. “포트 유형”을 참조하십시오.
  2. 인터페이스에 정의된 각 작업에 대한 작업 요소를 생성합니다. “작업”을 참조하십시오.
  3. 각 작업에 대해 작업의 매개 변수 목록, 반환 유형 및 예외를 나타내는 데 사용되는 메시지를 지정합니다. “작업 메시지”을 참조하십시오.

4.3. 포트 유형

WSDL portType 요소는 논리 인터페이스 정의의 root 요소입니다. 많은 웹 서비스 구현은 portType 요소를 생성된 구현 오브젝트에 직접 매핑하지만 논리 인터페이스 정의는 구현된 서비스에서 제공하는 정확한 기능을 지정하지 않습니다. 예를 들어, ticketSystem이라는 논리 인터페이스는 구현 결과를 초래할 수 있으며, 구현 결과를 얻을 수 있습니다.

portType 요소는 정의된 서비스를 노출하는 끝점에서 사용하는 물리적 데이터를 정의하기 위해 바인딩에 매핑되는 WSDL 문서의 단위입니다.

WSDL 문서의 각 portType 요소에는 name 특성을 사용하여 지정되고 작업 요소에 설명된 작업 컬렉션으로 구성된 고유한 이름이 있어야 합니다. WSDL 문서는 임의의 수의 포트 유형을 설명할 수 있습니다.

4.4. 작업

WSDL 작업 요소를 사용하여 정의된 논리 작업은 두 끝점 간의 상호 작용을 정의합니다. 예를 들어, 계정 밸런스 확인 요청과 위젯의 Gross에 대한 주문은 둘 다 작업으로 정의할 수 있습니다.

portType 요소 내에 정의된 각 작업에는 name 특성을 사용하여 지정된 고유한 이름이 있어야 합니다. name 속성은 작업을 정의하는 데 필요합니다.

4.5. 작업 메시지

논리 작업은 작업을 실행하기 위해 끝점 간에 전달되는 논리 메시지를 나타내는 일련의 요소로 구성됩니다. 작업을 설명할 수 있는 요소는 표 4.1. “작업 메시지 요소” 에 나열됩니다.

Expand
표 4.1. 작업 메시지 요소
element설명

입력

요청 시 클라이언트 끝점이 서비스 공급자에게 보내는 메시지를 지정합니다. 이 메시지의 일부는 작업의 입력 매개 변수에 해당합니다.

출력

서비스 공급자가 요청에 대한 응답으로 클라이언트 끝점에 전송하는 메시지를 지정합니다. 이 메시지의 일부는 참조로 전달된 값과 같이 서비스 공급자가 변경할 수 있는 모든 작업 매개변수에 해당합니다. 여기에는 작업의 반환 값이 포함됩니다.

fault

끝점 간 오류 상태를 전달하는 데 사용되는 메시지를 지정합니다.

입력 또는 하나의 출력 요소를 하나 이상 보유하려면 작업이 필요합니다. 작업에는 inputoutput 요소가 모두 있을 수 있지만 각 요소 중 하나만 있을 수 있습니다. fault 요소가 필요한 것은 아니지만 필요한 경우 여러 fault 요소가 있을 수 있습니다.

요소에는 표 4.2. “입력 및 출력 요소의 속성” 에 나열된 두 가지 속성이 있습니다.

Expand
표 4.2. 입력 및 출력 요소의 속성
속성설명

name

작업을 구체적인 데이터 형식으로 매핑할 때 참조할 수 있도록 메시지를 식별합니다. 이름은 enclosing 포트 유형 내에서 고유해야 합니다.

message

전송 또는 수신 중인 데이터를 설명하는 추상 메시지를 지정합니다. 메시지 특성 값은 WSDL 문서에 정의된 추상 메시지 중 하나의 name 속성에 해당해야 합니다.

모든 입력출력 요소에 대한 name 속성을 지정할 필요는 없습니다. WSDL은 enclosing 작업의 이름을 기반으로 기본 이름 지정 체계를 제공합니다. 작업에 하나의 요소만 사용되는 경우 요소 이름은 기본적으로 작업 이름으로 설정됩니다. 입력출력 요소가 모두 사용되는 경우 요소 이름은 기본적으로 Request 또는 Response 가 이름에 각각 추가된 작업의 이름으로 설정됩니다.

4.6. 반환 값

작업 요소는 작업 중에 전달된 데이터의 추상적 정의이므로 WSDL은 작업에 대해 지정된 반환 값을 제공하지 않습니다. 메서드가 값을 반환하는 경우 해당 메시지의 마지막 부분으로 출력 요소에 매핑됩니다.

4.7. 예제

예를 들어 예 4.1. “personalInfo 조회 인터페이스” 에 표시된 인터페이스와 유사한 인터페이스가 있을 수 있습니다.

예 4.1. personalInfo 조회 인터페이스

interface personalInfoLookup
{
  personalInfo lookup(in int empID)
  raises(idNotFound);
}
Copy to Clipboard Toggle word wrap

이 인터페이스는 예 4.2. “personalInfo 조회 포트 유형” 의 포트 유형에 매핑할 수 있습니다.

예 4.2. personalInfo 조회 포트 유형

<message name="personalLookupRequest">
  <part name="empId" element="xsd1:personalLookup"/>
<message/>
<message name="personalLookupResponse">
  <part name="return" element="xsd1:personalLookupResponse"/>
<message/>
<message name="idNotFoundException">
  <part name="exception" element="xsd1:idNotFound"/>
<message/>
<portType name="personalInfoLookup">
  <operation name="lookup">
    <input name="empID" message="tns:personalLookupRequest"/>
    <output name="return" message="tns:personalLookupResponse"/>
    <fault name="exception" message="tns:idNotFoundException"/>
  </operation>
</portType>
Copy to Clipboard Toggle word wrap

II 부. Web Services 바인딩

이 부분에서는 Apache CXF 바인딩을 WSDL 문서에 추가하는 방법을 설명합니다.

5장. WSDL의 바인딩 이해

초록

바인딩은 서비스를 정의하는 데 사용되는 논리 메시지를 엔드포인트에서 전송 및 수신할 수 있는 구체적인 페이로드 형식으로 매핑합니다.

5.1. 개요

바인딩은 서비스에서 사용하는 논리 메시지 간에 끝점이 물리적 환경에서 사용하는 구체적인 데이터 형식에 대한 브릿지를 제공합니다. 논리 메시지가 끝점에 의해 유선에 사용되는 페이로드 형식으로 매핑되는 방법을 설명합니다. 매개 변수 순서, 구체적인 데이터 유형 및 반환 값과 같은 세부 정보가 지정된 바인딩 내에 있습니다. 예를 들어 RPC 호출에 필요한 순서를 반영하도록 메시지 부분을 바인딩에서 다시 정렬할 수 있습니다. 바인딩 유형에 따라 메서드의 반환 유형을 나타내는 메시지 부분(있는 경우)을 확인할 수도 있습니다.

5.2. 포트 유형 및 바인딩

포트 유형 및 바인딩은 직접 관련이 있습니다. 포트 유형은 두 개의 논리 서비스 간의 상호 작용 집합에 대한 추상적 정의입니다. 바인딩은 논리 서비스를 구현하는 데 사용된 메시지가 물리적 환경에서 인스턴스화되는 방법에 대한 구체적인 정의입니다. 각 바인딩은 포트 유형에서 정의한 논리 서비스를 노출하는 하나의 끝점의 정의를 완료하는 네트워크 세부 정보 세트와 연결됩니다.

엔드포인트가 단일 서비스만 정의하도록 하려면 WSDL을 사용하려면 바인딩이 단일 포트 유형만 나타낼 수 있습니다. 예를 들어 두 포트 유형과의 계약이 있는 경우 두 포트 모두 구체적인 데이터 형식으로 매핑되는 단일 바인딩을 작성할 수 없습니다. 두 개의 바인딩이 필요합니다.

그러나 WSDL을 사용하면 포트 유형을 여러 바인딩에 매핑할 수 있습니다. 예를 들어 계약에 단일 포트 유형이 있는 경우 두 개 이상의 바인딩에 매핑할 수 있습니다. 각 바인딩은 메시지의 일부가 매핑되는 방식을 변경하거나 메시지에 대해 완전히 다른 페이로드 형식을 지정할 수 있습니다.

5.3. WSDL 요소

바인딩은 WSDL 바인딩 요소를 사용하여 계약에 정의됩니다. 바인딩 요소는 PortType에 대한 참조를 제공하는 바인딩 및 형식에 대한 고유 이름을 지정하는 name 과 같은 특성으로 구성됩니다. 이 속성의 값은 4장. 논리 인터페이스 정의 에서 설명한 대로 바인딩을 끝점과 연결하는 데 사용됩니다.

실제 매핑은 바인딩 요소의 자식에서 정의됩니다. 이러한 요소는 사용하려는 페이로드 형식 유형에 따라 다릅니다. 다양한 페이로드 형식 및 매핑을 지정하는 데 사용되는 요소는 다음 장에서 설명합니다.

5.4. 계약에 추가

Apache CXF는 사전 정의된 서비스 인터페이스에 대한 바인딩을 생성할 수 있는 명령줄 도구를 제공합니다.

이 도구는 귀하의 계약에 적절한 요소를 추가합니다. 그러나 다양한 유형의 바인딩 작동 방식에 대한 지식이 있는 것이 좋습니다.

텍스트 편집기를 사용하여 계약에 바인딩을 추가할 수도 있습니다. 계약을 직접 편집할 때 계약이 유효한지 확인할 책임이 있습니다.

5.5. 지원되는 바인딩

Apache CXF는 다음 바인딩을 지원합니다.

  • SOAP 1.1
  • SOAP 1.2
  • CORBA
  • 순수 XML

6장. Cryostat 1.1 메시지 사용

초록

Apache CXF는 ESP 헤더를 사용하지 않는 Cryostat 1.1 바인딩을 생성하는 툴을 제공합니다. 그러나 텍스트 또는 XML 편집기를 사용하여 바인딩에 Cryostat 헤더를 추가할 수 있습니다.

6.1. Cryostat 1.1 바인딩 추가

6.1.1. wsdl2soap 사용

wsdl2soap 을 사용하여 Cryostat 1.1 바인딩을 생성하려면 다음 명령을 사용합니다. wsdl2soap-iport-type-name-bbinding-name-doutput-directory-ooutput-file-nsoap-body-namespace-style (document/rpc)-use (literal/encoded)-v-verbose-quietwsdlurl

참고

wsdl2soap 을 사용하려면 Apache CXF 배포를 다운로드해야 합니다.

명령에는 다음과 같은 옵션이 있습니다.

Expand
옵션해석

-i port-type-name

바인딩이 생성되는 portType 요소를 지정합니다.

wsdlurl

portType 요소 정의가 포함된 WSDL 파일의 경로와 이름입니다.

툴에는 다음과 같은 선택적 인수가 있습니다.

Expand
옵션해석

-b binding-name

생성된 Cryostat 바인딩의 이름을 지정합니다.

-d output-directory

생성된 WSDL 파일을 배치할 디렉터리를 지정합니다.

- O output-file

생성된 WSDL 파일의 이름을 지정합니다.

-n soap-body-namespace

스타일이 RPC인 경우 Cryostat 본문 네임스페이스를 지정합니다.

-style (document/rpc)

Cryostat 바인딩에 사용할 인코딩 스타일(문서 또는 RPC)을 지정합니다. 기본값은 document입니다.

-use (literal/encoded)

Cryostat 바인딩에 사용할 바인딩 사용(로 인코딩된 또는 리터럴)을 지정합니다. 기본값은 literal입니다.

-v

도구의 버전 번호를 표시합니다.

-verbose

코드 생성 프로세스 중에 주석을 표시합니다.

-quiet

코드 생성 프로세스 중에 주석을 비활성화합니다.

-iport-type-namewsdlurl 인수가 필요합니다. -style rpc 인수가 지정된 경우 -nsoap-body-namspace 인수도 필요합니다. 다른 모든 인수는 선택 사항이며 순서에 따라 나열될 수 있습니다.

중요

wsdl2soap문서/코드로 인코딩된 Cryostat 바인딩 생성을 지원하지 않습니다.

6.1.2. 예제

시스템에 주문을 받아서 주문하기 위한 단일 작업을 제공하는 인터페이스가 있는 경우 예 6.1. “시스템 인터페이스 순서 지정” 에 표시된 것과 유사한 WSDL 조각에 정의되어 있습니다.

예 6.1. 시스템 인터페이스 순서 지정

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>
...
</definitions>
Copy to Clipboard Toggle word wrap

orderWidgets 용으로 생성된 Cryostat 바인딩은 예 6.2. “orderWidgets를 위한 Cryostat 1.1 바인딩” 에 표시됩니다.

예 6.2. orderWidgets를 위한 Cryostat 1.1 바인딩

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap:operation soapAction="" style="document"/>
      <input name="order">
        <soap:body use="literal"/>
      </input>
      <output name="bill">
        <soap:body use="literal"/>
      </output>
      <fault name="sizeFault">
        <soap:body use="literal"/>
      </fault>
  </operation>
</binding>
Copy to Clipboard Toggle word wrap

이 바인딩은 문서/ 일반 메시지 스타일을 사용하여 메시지가 전송되도록 지정합니다.

6.2. Cryostat 1.1 바인딩에 Syslog 헤더 추가

6.2.1. 개요

Cryostat 헤더는 soap:header 요소를 기본 Cryostat 1.1 바인딩에 추가하여 정의됩니다. soap:header 요소는 바인딩의 입력,출력fault 요소의 선택적 자식입니다. Cryostat 헤더는 상위 메시지의 일부가 됩니다. Cryostat 헤더는 메시지와 메시지 부분을 지정하여 정의됩니다. 각 Cryostat 헤더는 하나의 메시지 부분만 포함할 수 있지만 필요에 따라 많은 Cryostat 헤더를 삽입할 수 있습니다.

6.2.2. 구문

Cryostat 헤더를 정의하는 구문은 예 6.3. “Cryostat 헤더 구문” 에 표시됩니다. soap:headermessage 속성은 해당 부분이 헤더에 삽입되는 메시지의 정규화된 이름입니다. part 속성은 Cryostat 헤더에 삽입된 메시지 부분의 이름입니다. Cryostat 헤더는 항상 문서 스타일이므로, ESP 헤더에 삽입된 WSDL 메시지 부분은 요소를 사용하여 정의해야 합니다. messagepart 특성을 함께 사용하여 Cryostat 헤더에 삽입할 데이터를 완전히 설명합니다.

예 6.3. Cryostat 헤더 구문

<binding name="headwig">
  <soap:binding style="document"
                transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="weave">
      <soap:operation soapAction="" style="document"/>
      <input name="grain">
        <soap:body ... />
        <soap:header message="QName" part="partName"/>
      </input>
...
</binding>
Copy to Clipboard Toggle word wrap

soap:header 는 필수 메시지일부 속성뿐만 아니라 네임스페이스, use, encodingStyle 특성도 지원합니다. 이러한 속성은 soap:body 와 동일한 soap:header 에 대해 작동합니다.

6.2.3. 본문과 헤더 간에 메시지 분할

message part가 contract의 유효한 메시지 부분이 될 수 있습니다. 이 필드는 parent 메시지의 일부일 수도 있으며, 이 메시지는 Cryostat 본문으로 사용됩니다. 동일한 메시지에 정보를 두 번 보낼 가능성은 낮기 때문에 Cryostat 바인딩은 Cryostat 본문에 삽입되는 메시지 부분을 지정하는 수단을 제공합니다.

soap:body 요소에는 공백으로 구분된 구성 요소 목록을 사용하는 선택적 속성인 parts 가 있습니다. 부분이 정의되면 나열된 메시지 부분만 Cryostat 본문에 삽입됩니다. 그런 다음 나머지 부분을 Cryostat 헤더에 삽입할 수 있습니다.

참고

상위 메시지의 일부를 사용하여 Cryostat 헤더를 정의하면 Apache CXF가 자동으로 Cryostat 헤더에 채워집니다.

6.2.4. 예제

예 6.4. “Cryostat 헤더를 사용한 Cryostat 1.1 바인딩” 예 6.1. “시스템 인터페이스 순서 지정” 에 표시된 orderWidgets 서비스의 수정된 버전을 표시합니다. 이 버전은 각 주문에 요청 및 응답의 Cryostat 헤더에 배치된 xsd:base64binary 값이 적용되도록 수정되었습니다. Cryostat 헤더는 widgetKey 메시지의 keyVal 부분으로 정의됩니다. 이 경우 입력 또는 출력 메시지의 일부가 아니므로 애플리케이션 논리에 Cryostat 헤더를 추가해야 합니다.

예 6.4. Cryostat 헤더를 사용한 Cryostat 1.1 바인딩

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>
<message name="widgetKey">
  <part name="keyVal" element="xsd1:keyElem"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap:operation soapAction="" style="document"/>
      <input name="order">
        <soap:body use="literal"/>
        <soap:header message="tns:widgetKey" part="keyVal"/>
      </input>
      <output name="bill">
        <soap:body use="literal"/>
        <soap:header message="tns:widgetKey" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>
Copy to Clipboard Toggle word wrap

헤더 값이 입력 및 출력 메시지의 일부가 되도록 예 6.4. “Cryostat 헤더를 사용한 Cryostat 1.1 바인딩” 를 수정할 수도 있습니다.

7장. Cryostat 1.2 메시지 사용

초록

Apache CXF는 ESP 헤더를 사용하지 않는 Cryostat 1.2 바인딩을 생성하는 툴을 제공합니다. 텍스트 또는 XML 편집기를 사용하여 바인딩에 Cryostat 헤더를 추가할 수 있습니다.

7.1. WSDL 문서에 Cryostat 1.2 바인딩 추가

7.1.1. wsdl2soap 사용

참고

wsdl2soap을 사용하려면 Apache CXF 배포를 다운로드해야 합니다.

wsdl2soap 을 사용하여 Cryostat 1.2 바인딩을 생성하려면 다음 명령을 사용합니다. wsdl2soap-iport-type-name-bbinding-name-soap12-doutput-directory-nsoap-body-namespace-style (document/rpc)-use (literal/encoded)-v-verbose-quietwsdl URL 에는 다음과 같은 필수 인수가 있습니다.

Expand
옵션해석

-i port-type-name

바인딩이 생성되는 portType 요소를 지정합니다.

-soap12

생성된 바인딩에서 Cryostat 1.2를 사용하도록 지정합니다.

wsdlurl

portType 요소 정의가 포함된 WSDL 파일의 경로와 이름입니다.

툴에는 다음과 같은 선택적 인수가 있습니다.

Expand
옵션해석

-b binding-name

생성된 Cryostat 바인딩의 이름을 지정합니다.

-soap12

생성된 바인딩에서 Cryostat 1.2를 사용하도록 지정합니다.

-d output-directory

생성된 WSDL 파일을 배치할 디렉터리를 지정합니다.

- O output-file

생성된 WSDL 파일의 이름을 지정합니다.

-n soap-body-namespace

스타일이 RPC인 경우 Cryostat 본문 네임스페이스를 지정합니다.

-style (document/rpc)

Cryostat 바인딩에 사용할 인코딩 스타일(문서 또는 RPC)을 지정합니다. 기본값은 document입니다.

-use (literal/encoded)

Cryostat 바인딩에 사용할 바인딩 사용(로 인코딩된 또는 리터럴)을 지정합니다. 기본값은 literal입니다.

-v

도구의 버전 번호를 표시합니다.

-verbose

코드 생성 프로세스 중에 주석을 표시합니다.

-quiet

코드 생성 프로세스 중에 주석을 비활성화합니다.

-i port-type-namewsdlurl 인수가 필요합니다. -style rpc 인수가 지정된 경우 -n soap-body-namspace 인수도 필요합니다. 다른 모든 인수는 선택 사항이며 순서에 따라 나열할 수 있습니다.

중요

wsdl2soap문서/ 로깅 1.2 바인딩 생성을 지원하지 않습니다.

7.1.2. 예제

시스템에 주문을 받아서 주문하기 위한 단일 작업을 제공하는 인터페이스가 있는 경우 예 7.1. “시스템 인터페이스 순서 지정” 에 표시된 것과 유사한 WSDL 조각에 정의되어 있습니다.

예 7.1. 시스템 인터페이스 순서 지정

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>
...
</definitions>
Copy to Clipboard Toggle word wrap

orderWidgets용으로 생성된 Cryostat 바인딩은 예 7.2. “orderWidgets를 위한 Cryostat 1.2 바인딩” 에 표시됩니다.

예 7.2. orderWidgets를 위한 Cryostat 1.2 바인딩

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap12:operation soapAction="" style="document"/>
      <input name="order">
        <soap12:body use="literal"/>
      </input>
      <output name="bill">
        <wsoap12:body use="literal"/>
      </output>
      <fault name="sizeFault">
        <soap12:body use="literal"/>
      </fault>
  </operation>
</binding>
Copy to Clipboard Toggle word wrap

이 바인딩은 문서/ 일반 메시지 스타일을 사용하여 메시지가 전송되도록 지정합니다.

7.2. Cryostat 1.2 메시지에 헤더 추가

7.2.1. 개요

Cryostat 메시지 헤더는 soap12:header 요소를 Cryostat 1.2 메시지에 추가하여 정의됩니다. soap12:header 요소는 바인딩의 입력,출력fault 요소의 선택적 자식입니다. Cryostat 헤더는 상위 메시지의 일부가 됩니다. Cryostat 헤더는 메시지와 메시지 부분을 지정하여 정의됩니다. 각 Cryostat 헤더는 하나의 메시지 부분만 포함할 수 있지만 필요에 따라 헤더를 많이 삽입할 수 있습니다.

7.2.2. 구문

Cryostat 헤더를 정의하는 구문은 예 7.3. “Cryostat 헤더 구문” 에 표시됩니다.

예 7.3. Cryostat 헤더 구문

<binding name="headwig">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="weave">
      <soap12:operation soapAction="" style="documment"/>
      <input name="grain">
        <soap12:body ... />
        <soap12:header message="QName" part="partName"
                       use="literal|encoded"
                        encodingStyle="encodingURI"
                        namespace="namespaceURI" />
      </input>
...
</binding>
Copy to Clipboard Toggle word wrap

soap12:header 요소의 속성은 표 7.1. “soap12:header 속성” 에 설명되어 있습니다.

Expand
표 7.1. soap12:header 속성
속성설명

message

헤더에 삽입되는 부분이 사용되는 메시지의 정규화된 이름을 지정하는 필수 속성입니다.

부분

Cryostat 헤더에 삽입된 메시지 부분의 이름을 지정하는 필수 속성입니다.

사용

인코딩 규칙을 사용하여 메시지 부분을 인코딩할지 여부를 지정합니다. 인코딩된 것으로 설정하면 메시지 부분이 encodingStyle 속성 값으로 지정된 인코딩 규칙을 사용하여 인코딩됩니다. 리터럴 로 설정하면 메시지 부분은 참조되는 스키마 유형에 의해 정의됩니다.

encodingStyle

메시지를 구성하는 데 사용되는 인코딩 규칙을 지정합니다.

namespace

use="encoded" 로 직렬화된 헤더 요소에 할당할 네임스페이스를 정의합니다.

7.2.3. 본문과 헤더 간에 메시지 분할

message part가 contract의 유효한 메시지 부분이 될 수 있습니다. 이 필드는 parent 메시지의 일부일 수도 있으며, 이 메시지는 Cryostat 본문으로 사용됩니다. 동일한 메시지에서 정보를 두 번 보내지 않을 수 있기 때문에 Cryostat 1.2 바인딩은 Cryostat 본문에 삽입되는 메시지 부분을 지정하는 수단을 제공합니다.

soap12:body 요소에는 공백으로 구분된 부분 목록을 사용하는 선택적 특성인 parts 가 있습니다. 부분이 정의되면 나열된 메시지 부분만 Cryostat 1.2 메시지의 본문에 삽입됩니다. 그런 다음 나머지 부분을 메시지의 헤더에 삽입할 수 있습니다.

참고

상위 메시지의 일부를 사용하여 Cryostat 헤더를 정의하면 Apache CXF가 자동으로 Cryostat 헤더에 채워집니다.

7.2.4. 예제

예 7.4. “Cryostat 1.2 Binding with a Cryostat Header” 예 7.1. “시스템 인터페이스 순서 지정” 에 표시된 orderWidgets 서비스의 수정된 버전을 표시합니다. 이 버전은 각 주문에 요청 헤더와 응답에 xsd:base64binary 값이 할당되도록 수정되었습니다. 헤더는 widgetKey 메시지의 keyVal 부분으로 정의됩니다. 이 경우 입력 또는 출력 메시지의 일부가 아니므로 헤더를 생성하기 위해 애플리케이션 논리를 추가해야 합니다.

예 7.4. Cryostat 1.2 Binding with a Cryostat Header

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>
<message name="widgetKey">
  <part name="keyVal" element="xsd1:keyElem"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap12:operation soapAction="" style="document"/>
      <input name="order">
        <soap12:body use="literal"/>
        <soap12:header message="tns:widgetKey" part="keyVal"/>
      </input>
      <output name="bill">
        <soap12:body use="literal"/>
        <soap12:header message="tns:widgetKey" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap12:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>
Copy to Clipboard Toggle word wrap

예 7.4. “Cryostat 1.2 Binding with a Cryostat Header” 에 표시된 대로 헤더 값이 입력 및 출력 메시지의 일부가 되도록 예 7.5. “Cryostat 1.2 Binding for orderWidgets with a Cryostat Header” 를 수정할 수 있습니다. 이 경우 keyVal 은 입력 및 출력 메시지의 일부입니다. soap12:body 요소에서 parts 속성은 keyVal 을 본문에 삽입하지 않도록 지정합니다. 그러나 헤더에 삽입됩니다.

예 7.5. Cryostat 1.2 Binding for orderWidgets with a Cryostat Header

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
  <part name="keyVal" element="xsd1:keyElem"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
  <part name="keyVal" element="xsd1:keyElem"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap12:operation soapAction="" style="document"/>
      <input name="order">
        <soap12:body use="literal" parts="numOrdered"/>
        <soap12:header message="tns:widgetOrder" part="keyVal"/>
      </input>
      <output name="bill">
        <soap12:body use="literal" parts="bill"/>
        <soap12:header message="tns:widgetOrderBill" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap12:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>
Copy to Clipboard Toggle word wrap

8장. 첨부 파일과 함께 Cryostat를 사용하여 바이너리 데이터 전송

초록

Cryostat 첨부 파일은 바이너리 데이터를 Cryostat 메시지의 일부로 전송하기 위한 메커니즘을 제공합니다. 첨부 파일과 함께 Cryostat 메시지를 MIME 다중 파트 메시지로 정의해야 합니다.

8.1. 개요

Cryostat 메시지는 일반적으로 바이너리 데이터를 전송하지 않습니다. 그러나 W3C Cryostat 1.1 사양을 사용하면 MIME 다중 파트/관련 메시지를 사용하여 Cryostat 메시지에서 바이너리 데이터를 보낼 수 있습니다. 이 기술은 첨부 파일과 함께 Cryostat를 사용하는 것을 호출합니다. Cryostat 첨부 파일은 첨부 파일이 있는 W3C의 Cryostat 메시지에 정의되어 있습니다.

8.2. 네임스페이스

MIME 다중 파트/관련 메시지를 정의하는 데 사용되는 WSDL 확장은 http://schemas.xmlsoap.org/wsdl/mime/ 네임스페이스에 정의됩니다.

다음 토론에서는 이 네임스페이스 앞에 mime 이 붙은 것으로 가정합니다. 이를 설정하는 WSDL 정의 요소의 항목은 예 8.1. “계약의 MIME 네임스페이스 사양” 에 표시됩니다.

예 8.1. 계약의 MIME 네임스페이스 사양

xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
Copy to Clipboard Toggle word wrap

8.3. 메시지 바인딩 변경

기본 Cryostat 바인딩에서 입력,출력fault 요소의 첫 번째 자식 요소는 데이터를 나타내는 Cryostat 메시지의 본문을 설명하는 soap:body 요소입니다. 첨부 파일과 함께 Cryostat를 사용할 때 soap:body 요소는 mime:multipartRelated 요소로 교체됩니다.

참고

WSDL은 오류 메시지에 대해 mime:multipartRelated 사용을 지원하지 않습니다.

mime:multipartRelated 요소는 Apache CXF에 메시지 본문이 바이너리 데이터를 포함하는 다중 파트 메시지임을 알립니다. 요소의 내용은 메시지 및 해당 콘텐츠의 부분을 정의합니다. MIME:multipartRelated 요소에는 메시지의 개별 부분을 설명하는 하나 이상의 mime:part 요소가 포함됩니다.

첫 번째 mime:part 요소에는 일반적으로 기본 Cryostat 바인딩에 표시되는 soap:body 요소가 포함되어야 합니다. 나머지 mime:part 요소는 메시지에 전송되는 첨부 파일을 정의합니다.

8.4. MIME multipart 메시지 설명

MIME multipart 메시지는 여러 mime:part 요소를 포함하는 mime:multipartRelated 요소를 사용하여 설명됩니다. MIME multipart 메시지를 완전히 설명하려면 다음을 수행해야 합니다.

  1. MIME multipart 메시지로 보내는 입력 또는 출력 메시지 내부에서 mime:mulipartRelated 요소를 enclosing 메시지의 첫 번째 자식 요소로 추가합니다.
  2. mime:part 하위 요소를 mime:multipartRelated 요소에 추가하고 name 속성을 고유한 문자열로 설정합니다.
  3. soap:body 요소를 mime:part 요소의 자식으로 추가하고 해당 특성을 적절하게 설정합니다.

    참고

    계약에 기본 Cryostat 바인딩이 있는 경우 기본 바인딩에서 MIME multipart 메시지로 soap:body 요소를 해당 메시지에서 복사할 수 있습니다.

  4. mime:part 하위 요소를 mime:multipartReleated 요소에 추가하고 name 속성을 고유한 문자열로 설정합니다.
  5. mime:content 하위 요소를 mime:part 요소에 추가하여 메시지의 이 부분의 내용을 설명합니다.

    MIME 메시지 부분의 내용을 완전히 설명하려면 mime:content 요소에는 다음과 같은 속성이 있습니다.

    Expand
    표 8.1. MIME:content 속성
    속성설명 +

    부분

    부모 메시지 정의에서 알로어에 배치되는 MIME multi part 메시지의 콘텐츠로 사용되는 WSDL 메시지 부분의 이름을 지정합니다.

    +

    type

    이 메시지 부분에 있는 데이터의 MIME 유형입니다. MIME 유형은 유형 및 구문 유형/하위 유형을 사용하여 하위 유형으로 정의됩니다.

    +

    image/jpegtext/plain 과 같은 다양한 MIME 유형이 있습니다. MIME 유형은 INA(Internet Assigned Numbers Authority)에 의해 유지 관리되며, MIME(Multipurpose Internet Mail Extensions) 파트 1: Format of Internet Message Bodies and Multipurpose Internet Mail Extensions (MIME) part 2 에 자세히 설명되어 있습니다.

    +

  6. 추가 MIME 부분에 대해 [i303819][i303821] 단계를 반복합니다.

8.5. 예제

예 8.2. “Attachments와 함께 Cryostat를 사용한 계약” X-ray를 JPEG 형식으로 저장하는 서비스를 정의하는 WSDL 조각이 표시됩니다. 이미지 데이터인 x Cryostat는 xsd:base64binary 로 저장되며 MIME multipart 메시지의 두 번째 부분인 imageData 에 패키징되어 있습니다. 입력 메시지의 나머지 두 부분인 patientNamepatientNumber 는 MIME 다중 파트 이미지의 첫 번째 부분에서 192.0.2. 본문의 일부로 전송됩니다.

예 8.2. Attachments와 함께 Cryostat를 사용한 계약

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="XrayStorage"
    targetNamespace="http://mediStor.org/x-rays"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://mediStor.org/x-rays"
    xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <message name="storRequest">
    <part name="patientName" type="xsd:string"/>
    <part name="patientNumber" type="xsd:int"/>
    <part name="xRay" type="xsd:base64Binary"/>
  </message>
  <message name="storResponse">
    <part name="success" type="xsd:boolean"/>
  </message>

  <portType name="xRayStorage">
    <operation name="store">
      <input message="tns:storRequest" name="storRequest"/>
      <output message="tns:storResponse" name="storResponse"/>
    </operation>
  </portType>

  <binding name="xRayStorageBinding" type="tns:xRayStorage">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="store">
      <soap:operation soapAction="" style="document"/>
      <input name="storRequest">
        <mime:multipartRelated>
          <mime:part name="bodyPart">
            <soap:body use="literal"/>
          </mime:part>
          <mime:part name="imageData">
            <mime:content part="xRay" type="image/jpeg"/>
          </mime:part>
        </mime:multipartRelated>
      </input>
      <output name="storResponse">
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>

  <service name="xRayStorageService">
    <port binding="tns:xRayStorageBinding" name="xRayStoragePort">
      <soap:address location="http://localhost:9000"/>
    </port>
  </service>
</definitions>
Copy to Clipboard Toggle word wrap

9장. Cryostat MTOM을 사용하여 바이너리 데이터 전송

초록

NSX Message Transmission optimization Mechanism (MTOM)은 binary data를 XML 메시지의 일부로 전송하기 위한 메커니즘으로서의 첨부 파일로 대체됩니다. Apache CXF와 함께 MTOM을 사용하려면 서비스 계약에 올바른 스키마 유형을 추가하고 MTOM 최적화를 활성화해야 합니다.

9.1. MTOM 개요

message Transmission optimization Mechanism (MTOM)은 바이너리 데이터를 Cryostat 메시지의 일부로 전송하기 위한 최적화된 방법을 지정합니다. Attachments와 달리 MTOM은 바이너리 데이터를 전송하기 위해 XML-binary Cryostatd Packaging(XOP) 패키지를 사용해야 합니다. MTOM을 사용하여 바이너리 데이터를 보내는 경우 MIME Multipart/Related 메시지를 Cryostat 바인딩의 일부로 완전히 정의할 필요가 없습니다. 그러나 다음 작업을 수행해야 합니다.

  1. 첨부 파일로 보낼 데이터에 주석 을 답니다.

    WSDL 또는 데이터를 구현하는 Java 클래스에 주석을 달 수 있습니다.

  2. 런타임의 MTOM 지원을 활성화합니다.

    이 작업은 프로그래밍 방식으로 또는 구성을 통해 수행할 수 있습니다.

  3. 첨부 파일로 전달되는 데이터에 대한 DataHandler 를 개발합니다.

    참고

    Developing DataHandlers는 이 문서의 범위를 벗어납니다.

9.2. MTOM을 사용하도록 데이터 유형에 주석 처리

9.2.1. 개요

WSDL에서 이미지 파일 또는 사운드 파일과 같은 바이너리 데이터 블록을 전달하는 데이터 유형을 정의할 때 데이터의 요소를 xsd:base64Binary 형식으로 정의합니다. 기본적으로 xsd:base64Binary 유형의 모든 요소는 MTOM을 사용하여 직렬화할 수 있는 byte[] 생성을 생성합니다. 그러나 코드 생성기의 기본 동작은 직렬화를 최대한 활용하지 않습니다.

MTOM을 최대한 활용하기 위해서는 서비스의 WSDL 문서 또는 바이너리 데이터 구조를 구현하는 CryostatB 클래스에 주석을 추가해야 합니다. WSDL 문서에 주석을 추가하면 코드 생성기가 바이너리 데이터에 대한 스트리밍 데이터 처리기를 생성하도록 합니다. CryostatB 클래스에 주석을 달 때는 적절한 콘텐츠 유형을 지정해야 하며 바이너리 데이터가 포함된 필드의 유형 사양을 변경해야 할 수도 있습니다.

9.2.2. 먼저 WSDL

예 9.1. “MTOM의 메시지” 하나의 문자열 필드, 하나의 정수 필드 및 바이너리 필드를 포함하는 메시지를 사용하는 웹 서비스에 대한 WSDL 문서를 표시합니다. 바이너리 필드는 큰 이미지 파일을 전송하기 위한 것이므로 일반 Cryostat 메시지의 일부로 보내는 것은 적절하지 않습니다.

예 9.1. MTOM의 메시지

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="XrayStorage"
    targetNamespace="http://mediStor.org/x-rays"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://mediStor.org/x-rays"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:xsd1="http://mediStor.org/types/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <types>
    <schema targetNamespace="http://mediStor.org/types/"
            xmlns="http://www.w3.org/2001/XMLSchema">
      <complexType name="xRayType">
        <sequence>
          <element name="patientName" type="xsd:string" />
          <element name="patientNumber" type="xsd:int" />
          <element name="imageData" type="xsd:base64Binary" />
        </sequence>
      </complexType>
      <element name="xRay" type="xsd1:xRayType" />
    </schema>
  </types>

  <message name="storRequest">
    <part name="record" element="xsd1:xRay"/>
  </message>
  <message name="storResponse">
    <part name="success" type="xsd:boolean"/>
  </message>

  <portType name="xRayStorage">
    <operation name="store">
      <input message="tns:storRequest" name="storRequest"/>
      <output message="tns:storResponse" name="storResponse"/>
    </operation>
  </portType>

  <binding name="xRayStorageSOAPBinding" type="tns:xRayStorage">
    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="store">
      <soap12:operation soapAction="" style="document"/>
      <input name="storRequest">
        <soap12:body use="literal"/>
      </input>
      <output name="storResponse">
        <soap12:body use="literal"/>
      </output>
    </operation>
  </binding>
  ...
</definitions>
Copy to Clipboard Toggle word wrap

MTOM을 사용하여 메시지의 바이너리 부분을 최적화된 첨부 파일로 보내려면 바이너리 데이터가 포함된 요소에 xmime:expectedContentTypes 속성을 추가해야 합니다. 이 속성은 http://www.w3.org/2005/05/xmlmime 네임스페이스에 정의되어 있으며 요소에 포함될 것으로 예상되는 MIME 유형을 지정합니다. 쉼표로 구분된 MIME 유형 목록을 지정할 수 있습니다. 이 속성의 설정은 코드 생성기가 데이터에 대한 CryostatB 클래스를 생성하는 방법을 변경합니다. 대부분의 MIME 유형의 경우 코드 생성기는 DataHandler를 생성합니다. 이미지 옵션과 같은 일부 MIME 유형에는 매핑이 정의되어 있습니다.

참고

MIME 유형은 Internet Assigned Numbers Authority(IANA)에 의해 유지 관리되며 Multipurpose Internet Mail Extensions (MIME) Part One: Internet Message Bodies 및 Multipurpose Internet Mail Extensions (MIME) Part 2 에 자세히 설명되어 있습니다.

대부분의 용도에서 application/octet-stream 을 지정합니다.

예 9.2. “MTOM의 바이너리 데이터” MTOM을 사용하기 위해 예 9.1. “MTOM의 메시지” 에서 x CryostatType 을 수정하는 방법을 보여줍니다.

예 9.2. MTOM의 바이너리 데이터

...
  <types>
    <schema targetNamespace="http://mediStor.org/types/"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:xmime="http://www.w3.org/2005/05/xmlmime">
      <complexType name="xRayType">
        <sequence>
          <element name="patientName" type="xsd:string" />
          <element name="patientNumber" type="xsd:int" />
          <element name="imageData" type="xsd:base64Binary"
                   xmime:expectedContentTypes="application/octet-stream"/>
        </sequence>
      </complexType>
      <element name="xRay" type="xsd1:xRayType" />
    </schema>
  </types>
...
Copy to Clipboard Toggle word wrap

x CryostatType 용으로 생성된 생성된 CryostatB 클래스에는 더 이상 byte[] 가 포함되어 있지 않습니다. 대신 코드 생성기는 xmime:expectedContentTypes 속성을 보고 imageData 필드에 대한 DataHandler를 생성합니다.

참고

MTOM을 사용하기 위해 바인딩 요소를 변경할 필요가 없습니다. 런타임은 데이터를 전송할 때 적절한 변경을 수행합니다.

9.2.3. Java 첫 번째

Java를 처음 개발하는 경우 다음 작업을 수행하여 CryostatB 클래스 MTOM을 준비할 수 있습니다.

  1. 바이너리 데이터를 보유하는 필드가 DataHandler인지 확인합니다.
  2. 스트림할 데이터가 MTOM 첨부 파일로 포함된 필드에 @ CryostatMimeType() 주석을 추가합니다.

예 9.3. “MTOM용 CryostatB 클래스” MTOM을 사용하기 위해 주석이 추가된 CryostatB 클래스를 표시합니다.

예 9.3. MTOM용 CryostatB 클래스

@XmlType
public class XRayType {
    protected String patientName;
    protected int patientNumber;
    @XmlMimeType("application/octet-stream")
    protected DataHandler imageData;
  ...
}
Copy to Clipboard Toggle word wrap

9.3. MTOM 활성화

기본적으로 Apache CXF 런타임은 MTOM 지원을 활성화하지 않습니다. 모든 바이너리 데이터를 일반 Cryostat 메시지의 일부 또는 최적화되지 않은 연결로 전송합니다. 프로그래밍 방식으로 또는 구성 사용을 통해 MTOM 지원을 활성화할 수 있습니다.

9.3.1. Cryostat-WS API 사용

9.3.1.1. 개요

서비스 공급자와 소비자 모두 MTOM 최적화를 활성화해야 합니다. Cryostat-WS API는 각 유형의 끝점에 대해 다양한 메커니즘을 제공합니다.

9.3.1.2. 서비스 공급자

Cryostat-WS API를 사용하여 서비스 공급자를 게시한 경우 다음과 같이 런타임의 MTOM 지원을 활성화합니다.

  1. 게시된 서비스에 대한 Endpoint 오브젝트에 액세스합니다.

    Endpoint 오브젝트에 액세스하는 가장 쉬운 방법은 엔드포인트를 게시하는 것입니다. 자세한 내용은 31장. 서비스 게시 에서 참조하십시오.

  2. 예 9.4. “끝점에서 Cryostat 바인딩 가져오기” 에 표시된 대로 getBinding() 메서드를 사용하여 끝점에서 Cryostat 바인딩을 가져옵니다.

    예 9.4. 끝점에서 Cryostat 바인딩 가져오기

    // Endpoint ep is declared previously
    SOAPBinding binding = (SOAPBinding)ep.getBinding();
    Copy to Clipboard Toggle word wrap

    반환된 바인딩 오브젝트를 MTOM 속성에 액세스하려면 CryostatBinding 오브젝트로 캐스팅해야 합니다.

  3. 예 9.5. “서비스 공급자의 MTOM 활성화 속성 설정” 와 같이 바인딩의 setMTOMEnabled() 메서드를 사용하여 바인딩의 MTOM enabled 속성을 true 로 설정합니다.

    예 9.5. 서비스 공급자의 MTOM 활성화 속성 설정

    binding.setMTOMEnabled(true);
    Copy to Clipboard Toggle word wrap
9.3.1.3. 소비자

MTOM을 활성화하려면 다음을 수행해야 합니다.

  1. 소비자의 프록시를 BindingProvider 개체로 캐스팅합니다.

    소비자 프록시를 가져오는 방법에 대한 자세한 내용은 25장. WSDL 계약 없이 소비자 개발 또는 28장. WSDL 계약에서 소비자 개발 을 참조하십시오.

  2. 예 9.6. “BindingProvider에서 Cryostat 바인딩 가져오기” 에 표시된 대로 getBinding() 메서드를 사용하여 BindingProvider 에서 Cryostat 바인딩을 가져옵니다.

    예 9.6. BindingProvider에서 Cryostat 바인딩 가져오기

    // BindingProvider bp declared previously
    SOAPBinding binding = (SOAPBinding)bp.getBinding();
    Copy to Clipboard Toggle word wrap
  3. 예 9.7. “소비자의 MTOM 활성화 속성 설정” 에 표시된 대로 바인딩의 setMTOMEnabled() 방법을 사용하여 바인딩 MTOM enabled 속성을 true 로 설정합니다.

    예 9.7. 소비자의 MTOM 활성화 속성 설정

    binding.setMTOMEnabled(true);
    Copy to Clipboard Toggle word wrap

9.3.2. 구성 사용

9.3.2.1. 개요

컨테이너에 배포할 때와 같이 XML을 사용하여 서비스를 게시하는 경우 엔드포인트의 구성 파일에서 끝점의 MTOM 지원을 활성화할 수 있습니다. 끝점 구성에 대한 자세한 내용은 IV 부. 웹 서비스 엔드 포인트 구성 을 참조하십시오.

9.3.2.2. 절차

MTOM 속성은 끝점의 jaxws:endpoint 요소 내에 설정됩니다. MTOM을 활성화하려면 다음을 수행합니다.

  1. 엔드포인트의 jaxws:endpoint 요소에 jaxws:property 하위 요소를 추가합니다.
  2. jaxws:property 요소에 항목 하위 요소를 추가합니다.
  3. entry 요소의 key 속성을 mtom-enabled 로 설정합니다.
  4. entry 요소의 value 속성을 true 로 설정합니다.
9.3.2.3. 예제

예 9.8. “MTOM 활성화 구성” MTOM이 활성화된 엔드포인트를 표시합니다.

예 9.8. MTOM 활성화 구성

<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-2.0.xsd
                           http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">

  <jaxws:endpoint id="xRayStorage"
                  implementor="demo.spring.xRayStorImpl"
                  address="http://localhost/xRayStorage">
    <jaxws:properties>
      <entry key="mtom-enabled" value="true"/>
    </jaxws:properties>
  </jaxws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap

10장. XML 문서 사용

초록

순수한 XML 페이로드 형식은 services에서 직접 XML 문서를 사용하여 데이터 교환을 허용하여 Cryostat 바인딩에 대한 대안을 제공합니다.

10.1. XML 바인딩 네임스페이스

XML 형식 바인딩을 설명하는 데 사용되는 확장은 네임스페이스 http://cxf.apache.org/bindings/xformat 에 정의됩니다. Apache CXF 툴에서는 접두사 xformat 을 사용하여 XML 바인딩 확장 기능을 나타냅니다. 계약에 다음 행을 추가합니다.

xmlns:xformat="http://cxf.apache.org/bindings/xformat"
Copy to Clipboard Toggle word wrap

10.2. 수동 편집

인터페이스를 순수 XML 페이로드 형식에 매핑하려면 다음을 수행합니다.

  1. XML 바인딩을 정의하는 확장을 포함하도록 네임스페이스 선언을 추가합니다. “XML 바인딩 네임스페이스”을 참조하십시오.
  2. 표준 WSDL 바인딩 요소를 계약에 추가하여 XML 바인딩을 유지하고, 바인딩에 고유한 이름을 지정하고, 바인딩된 인터페이스를 나타내는 WSDL portType 요소의 이름을 지정합니다.
  3. xformat:binding 하위 요소를 바인딩 요소에 추가하여 메시지가 Cryostat 없이 순수 XML 문서로 처리되고 있는지 확인합니다.
  4. 선택적으로 xformat:binding 요소의 rootNode 특성을 유효한 QName으로 설정합니다. rootNode 속성의 영향에 대한 자세한 내용은 “유선에 XML 메시지” 을 참조하십시오.
  5. 바인딩된 인터페이스에 정의된 각 작업에 대해 표준 WSDL 작업 요소를 추가하여 작업 메시지에 대한 바인딩 정보를 유지합니다.
  6. 바인딩에 추가된 각 작업에 대해 입력,출력fault 하위 요소를 추가하여 작업에서 사용하는 메시지를 나타냅니다.

    이러한 요소는 논리 작업의 인터페이스 정의에 정의된 메시지에 해당합니다.

  7. 선택적으로 유효한 rootNode 특성을 사용하여 바인딩 수준에서 rootNode 설정된 rootNode 값을 재정의하는 데 필요한 경우 추가된 입력,출력fault 요소에 xformat:body 요소를 추가합니다.
참고

메시지 중 하나라도 포함되어 있지 않은 경우(예: void를 반환하는 작업의 출력 메시지)에 대해 rootNode 특성을 설정하여wire에 기록된 메시지가 유효하지만 빈 XML 문서인지 확인해야 합니다.

10.3. 유선에 XML 메시지

인터페이스의 메시지가 XML 문서로 전달되도록 지정하는 경우 message가wire에 기록될 때 유효한 XML 문서를 형성하도록 주의해야 합니다. 또한 XML 문서를 수신하는 비 Apache CXF 참가자가 Apache CXF에서 생성한 메시지를 이해할 수 있도록 해야 합니다.

두 문제를 모두 해결하는 간단한 방법은 글로벌 xformat:binding 요소 또는 개별 메시지의 xformat:body 요소에서 선택적 rootNode 특성을 사용하는 것입니다. rootNode 속성은 Apache CXF에서 생성한 XML 문서의 루트 노드 역할을 하는 요소의 QName을 지정합니다. rootNode 속성이 설정되지 않은 경우 Apache CXF는 doc 스타일 메시지를 사용할 때 메시지 부분의 root 요소 또는 rpc 스타일 메시지를 사용할 때 메시지 부분 이름을 root 요소로 사용하는 요소를 사용합니다.

예를 들어 rootNode 속성이 예 10.1. “유효한 XML 바인딩 메시지” 에 정의된 메시지를 설정하지 않으면 root 요소 lineNumber 를 사용하여 XML 문서가 생성됩니다.

예 10.1. 유효한 XML 바인딩 메시지

<type ... >
  ...
  <element name="operatorID" type="xsd:int"/>
  ...
</types>
<message name="operator">
  <part name="lineNumber" element="ns1:operatorID"/>
</message>
Copy to Clipboard Toggle word wrap

한 부분이 있는 메시지의 경우 Apache CXF는 rootNode 속성이 설정되지 않은 경우에도 항상 유효한 XML 문서를 생성합니다. 그러나 예 10.2. “잘못된 XML 바인딩 메시지” 의 메시지는 유효하지 않은 XML 문서를 생성합니다.

예 10.2. 잘못된 XML 바인딩 메시지

<types>
  ...
  <element name="pairName" type="xsd:string"/>
  <element name="entryNum" type="xsd:int"/>
  ...
</types>

<message name="matildas">
  <part name="dancing" element="ns1:pairName"/>
  <part name="number" element="ns1:entryNum"/>
</message>
Copy to Clipboard Toggle word wrap

XML 바인딩에 지정된 rootNode 속성이 없으면 Apache CXF는 예 10.2. “잘못된 XML 바인딩 메시지” 에 정의된 메시지에 대한 예 10.3. “잘못된 XML 문서” 과 유사한 XML 문서를 생성합니다. 생성된 XML 문서는 pairNameentryNum 이라는 두 개의 루트 요소가 있기 때문에 유효하지 않습니다.

예 10.3. 잘못된 XML 문서

<pairName>
  Fred&Linda
</pairName>
<entryNum>
  123
</entryNum>
Copy to Clipboard Toggle word wrap

rootNode 속성을 설정하면 예 10.4. “rootNode가 설정된 XML 바인딩” Apache CXF에 표시된 대로 지정된 root 요소에서 요소를 래핑합니다. 이 예에서 rootNode 속성은 전체 바인딩에 대해 정의되며 루트 요소의 이름을 렌터로 지정합니다.

예 10.4. rootNode가 설정된 XML 바인딩

<portType name="danceParty">
  <operation name="register">
    <input message="tns:matildas" name="contestant"/>
  </operation>
</portType>

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered"/>
</binding>
Copy to Clipboard Toggle word wrap

입력 메시지에서 생성된 XML 문서는 예 10.5. “rootNode 특성을 사용하여 생성된 XML 문서” 과 유사합니다. XML 문서에는 이제 하나의 root 요소만 있습니다.

예 10.5. rootNode 특성을 사용하여 생성된 XML 문서

<entrants>
  <pairName>
    Fred&Linda
  <entryNum>
    123
  </entryNum>
</entrants>
Copy to Clipboard Toggle word wrap

10.4. 바인딩의 rootNode 속성 설정 덮어쓰기

각 개별 메시지에 대해 rootNode 특성을 설정하거나 메시지 바인딩 내의 xformat:body 요소를 사용하여 특정 메시지의 전역 설정을 덮어쓸 수도 있습니다. 예를 들어, 예 10.4. “rootNode가 설정된 XML 바인딩” 에 정의된 출력 메시지가 입력 메시지와 다른 루트 요소를 갖도록 하려면 예 10.6. “xformat:body사용” 에 표시된 대로 바인딩의 root 요소를 덮어쓸 수 있습니다.

예 10.6. xformat:body사용

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered">
      <xformat:body rootNode="entryStatus" />
    </output>
  </operation>
</binding>
Copy to Clipboard Toggle word wrap

III 부. 웹 서비스 전송

이 부분에서는 Apache CXF 전송을 WSDL 문서에 추가하는 방법을 설명합니다.

11장. WSDL에서 끝점을 정의하는 방법 이해

초록

끝점은 인스턴스화된 서비스를 나타냅니다. 바인딩과 끝점을 노출하는 데 사용되는 네트워킹 세부 정보를 결합하여 정의합니다.

11.1. 개요

끝점은 서비스의 물리적 표현으로 간주할 수 있습니다. 바인딩은 서비스에서 사용하는 논리 데이터의 물리적 표현과 다른 엔드포인트에서 서비스를 연결할 수 있도록 하는 데 사용되는 물리적 연결 세부 정보를 정의하는 네트워킹 세부 정보 집합을 결합합니다.

참고

CXF 공급자는 클라이언트에 해당하는 CXF 소비자용 서버입니다. CXF(camel-cxf) 구성 요소를 경로에서 시작 끝점으로 사용하는 경우 끝점은 Camel 소비자와 CXF 공급자 모두입니다. Camel CXF 구성 요소를 경로의 끝 끝점으로 사용하는 경우 엔드포인트는 Camel 생산자와 CXF 소비자 둘 다입니다.

11.2. 엔드포인트 및 서비스

바인딩이 단일 인터페이스를 매핑할 수 있는 것과 동일한 방식으로 끝점은 단일 서비스에만 매핑할 수 있습니다. 그러나 서비스는 여러 끝점으로 표시될 수 있습니다. 예를 들어 4개의 서로 다른 엔드포인트로 표시된 티켓 판매 서비스를 정의할 수 있습니다. 그러나 티켓 판매 서비스와 위젯 판매 서비스를 모두 표시하는 단일 끝점을 사용할 수 없었습니다.

11.3. WSDL 요소

끝점은 WSDL 서비스 요소 및 WSDL 포트 요소의 조합을 사용하여 계약에 정의됩니다. service 요소는 관련 포트 요소의 컬렉션입니다. port 요소는 실제 엔드포인트를 정의합니다.

WSDL 서비스 요소에는 고유한 이름을 지정하는 단일 속성 name이 있습니다. service 요소는 관련 포트 요소의 컬렉션의 부모 요소로 사용됩니다. WSDL은 포트 요소가 어떻게 관련되어 있는지에 대한 사양을 제시하지 않습니다. 포트 요소를 원하는 방식으로 연결할 수 있습니다.

WSDL 포트 요소에는 끝점에서 사용하는 바인딩 을 지정하고 wsdl:binding 요소에 대한 참조를 지정하는 바인딩 특성이 있습니다. 또한 모든 포트 간에 고유한 이름을 제공하는 필수 속성인 name 속성이 포함됩니다. port 요소는 끝점에서 사용하는 실제 전송 세부 정보를 지정하는 요소의 부모 요소입니다. 전송 세부 정보를 지정하는 데 사용되는 요소는 다음 섹션에서 설명합니다.

11.4. 계약에 끝점 추가

Apache CXF는 사전 정의된 서비스 인터페이스 및 바인딩 조합을 위해 엔드포인트를 생성할 수 있는 명령줄 툴을 제공합니다.

이 도구는 귀하의 계약에 적절한 요소를 추가합니다. 그러나 끝점을 정의하는 데 사용된 다양한 전송 방법에 대한 지식이 있어야 합니다.

텍스트 편집기를 사용하여 계약에 끝점을 추가할 수도 있습니다. 계약을 편집하면 계약이 유효한지 확인할 책임이 있습니다.

11.5. 지원되는 전송

엔드포인트 정의는 각 전송에 대해 정의된 확장을 사용하여 빌드됩니다 Apache CXF가 지원합니다. 여기에는 다음과 같은 전송이 포함됩니다.

  • HTTP
  • CORBA
  • Java 메시징 서비스

12장. HTTP 사용

초록

HTTP는 웹의 기본 전송입니다. 엔드포인트 간에 통신할 수 있는 표준화되고 강력하고 유연한 플랫폼을 제공합니다. 이러한 요인으로 인해 대부분의 WS-* 사양에 대해 가정된 전송이며 RESTful 아키텍처에 통합됩니다.

12.1. 기본 HTTP 끝점 추가

12.1.1. 대체 HTTP 런타임

Apache CXF는 다음과 같은 대체 HTTP 런타임 구현을 지원합니다.

12.1.2. Netty HTTP URL

일반적으로 HTTP 끝점은 클래스 경로( Cryostat 또는 Netty)에 포함된 HTTP 런타임을 사용합니다. 그러나 Cryostat 런타임과 Netty 런타임이 모두 classpath에 포함된 경우 기본적으로 Cryostat 런타임을 사용하므로 Netty 런타임을 사용하려는 경우 명시적으로 지정해야 합니다.

classpath에서 둘 이상의 HTTP 런타임을 사용할 수 있는 경우 다음 형식을 갖도록 끝점 URL을 지정하여 Cryostat 런타임을 선택할 수 있습니다.

netty://http://RestOfURL
Copy to Clipboard Toggle word wrap

12.1.3. 페이로드 유형

사용 중인 페이로드 형식에 따라 HTTP 끝점의 주소를 지정하는 세 가지 방법이 있습니다.

  • Cryostat 1.1은 표준화된 soap:address 요소를 사용합니다.
  • Cryostat 1.2는 soap12:address 요소를 사용합니다.
  • 다른 모든 페이로드 형식에서는 http:address 요소를 사용합니다.
참고

Camel 2.16.0 릴리스에서 Apache Camel CXF Payload는 즉시 스트림 캐시를 지원합니다.

12.1.4. SOAP 1.1

HTTP를 통해 Cryostat 1.1 메시지를 전송하는 경우 endpoint의 주소를 지정하기 위해 Cryostat 1.1 주소 요소를 사용해야 합니다. 여기에는 엔드포인트의 주소를 URL로 지정하는 하나의 속성 location 이 있습니다. Cryostat 1.1 주소 요소는 네임스페이스 http://schemas.xmlsoap.org/wsdl/soap/ 에 정의되어 있습니다.

예 12.1. “Cryostat 1.1 포트 요소” HTTP를 통해 Cryostat 1.1 메시지를 보내는 데 사용되는 포트 요소를 표시합니다.

예 12.1. Cryostat 1.1 포트 요소

<definitions ...
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" ...>
  ...
  <service name="SOAP11Service">
    <port binding="SOAP11Binding" name="SOAP11Port">
      <soap:address location="http://artie.com/index.xml">
    </port>
  </service>
  ...
<definitions>
Copy to Clipboard Toggle word wrap

12.1.5. SOAP 1.2

HTTP를 통해 Cryostat 1.2 메시지를 전송하는 경우 endpoint의 주소를 지정하려면 Cryostat 1.2 주소 요소를 사용해야 합니다. 여기에는 엔드포인트의 주소를 URL로 지정하는 하나의 속성 location 이 있습니다. Cryostat 1.2 주소 요소는 네임스페이스 http://schemas.xmlsoap.org/wsdl/soap12/ 에 정의되어 있습니다.

예 12.2. “Cryostat 1.2 포트 요소” HTTP를 통해 Cryostat 1.2 메시지를 보내는 데 사용되는 포트 요소를 표시합니다.

예 12.2. Cryostat 1.2 포트 요소

<definitions ...
             xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" ... >
  <service name="SOAP12Service">
    <port binding="SOAP12Binding" name="SOAP12Port">
      <soap12:address location="http://artie.com/index.xml">
    </port>
  </service>
  ...
</definitions>
Copy to Clipboard Toggle word wrap

12.1.6. 기타 메시지 유형

messages가 Cryostat 이외의 모든 페이로드 형식으로 매핑되는 경우 HTTP 주소 요소를 사용하여 끝점의 주소를 지정해야 합니다. 여기에는 엔드포인트의 주소를 URL로 지정하는 하나의 속성 location 이 있습니다. HTTP 주소 요소는 네임스페이스 http://schemas.xmlsoap.org/wsdl/http/ 에 정의되어 있습니다.

예 12.3. “HTTP 포트 요소” XML 메시지를 보내는 데 사용되는 포트 요소를 표시합니다.

예 12.3. HTTP 포트 요소

<definitions ...
             xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" ... >
  <service name="HTTPService">
    <port binding="HTTPBinding" name="HTTPPort">
      <http:address location="http://artie.com/index.xml">
    </port>
  </service>
  ...
</definitions>
Copy to Clipboard Toggle word wrap

12.2. 소비자 구성

12.2.1. HTTP Consumer Endpoints

HTTP 소비자 끝점은 엔드포인트에서 리디렉션 응답을 자동으로 수락하는지, 엔드포인트에서 청크를 사용할 수 있는지 여부, 엔드포인트에서 계속 연결을 요청할지 여부, 엔드포인트가 프록시와 상호 작용하는 방식을 포함하여 많은 HTTP 연결 속성을 지정할 수 있습니다. HTTP 연결 속성 외에도 HTTP 소비자 끝점은 보안 방법을 지정할 수 있습니다.

소비자 끝점은 다음 두 가지 메커니즘을 사용하여 구성할 수 있습니다.

12.2.2. 설정 사용

12.2.2.1. 네임스페이스

HTTP 소비자 끝점을 구성하는 데 사용되는 요소는 네임스페이스 http://cxf.apache.org/transports/http/configuration 에 정의되어 있습니다. 일반적으로 접두사 http-conf 를 사용합니다. HTTP 구성 요소를 사용하려면 예 12.4. “HTTP 소비자 구성 네임스페이스” 에 표시된 행을 끝점 구성 파일의 요소에 추가해야 합니다. 또한 구성 요소의 네임스페이스를 xsi:schemaLocation 속성에 추가해야 합니다.

예 12.4. HTTP 소비자 구성 네임스페이스

<beans ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       ...
       xsi:schemaLocation="...
                           http://cxf.apache.org/transports/http/configuration
                              http://cxf.apache.org/schemas/configuration/http-conf.xsd
                          ...">
Copy to Clipboard Toggle word wrap
12.2.2.2. Cryostat 런타임 또는 Netty 런타임

http-conf 네임스페이스의 요소를 사용하여 Cryostat 런타임 또는 Netty 런타임을 구성할 수 있습니다.

12.2.2.3. Conduit 요소

http-conf:conduit 요소 및 해당 하위 항목을 사용하여 HTTP 소비자 끝점을 구성합니다. http-conf:conduit 요소는 엔드포인트에 해당하는 WSDL 포트 요소를 지정하는 단일 속성 name 을 사용합니다. name 속성 값은 portQName'.http-conduit' 형식을 사용합니다. 예 12.5. “HTTP-conf:conduit Element” 끝점의 대상 네임스페이스가 http://widgets.widgetvendor.net인 경우 WSDL 조각 < port binding="widgetSOAPBinding" name="widgetSOAPPort >에 의해 지정된 끝점에 대한 구성을 추가하는 데 사용할 http-conf:conduit 요소를 표시합니다.

예 12.5. HTTP-conf:conduit Element

...
  <http-conf:conduit name="{http://widgets/widgetvendor.net}widgetSOAPPort.http-conduit">
    ...
  </http-conf:conduit>
...
Copy to Clipboard Toggle word wrap

http-conf:conduit 요소에는 구성 정보를 지정하는 하위 요소가 있습니다. 해당 내용은 표 12.1. “HTTP 소비자 끝점을 구성하는 데 사용되는 요소” 에 설명되어 있습니다.

Expand
표 12.1. HTTP 소비자 끝점을 구성하는 데 사용되는 요소
element설명

http-conf:client

시간 초과, keep-alive 요청, 콘텐츠 유형 등과 같은 HTTP 연결 속성을 지정합니다. “client 요소”을 참조하십시오.

http-conf:authorization

끝점에서 선점하는 기본 인증 방법을 구성하기 위한 매개변수를 지정합니다. 기본 접근 방식은 http-conf:basicAuthSupplier 오브젝트를 제공하는 것입니다.

http-conf:proxyAuthorization

발신 HTTP 프록시 서버에 대한 기본 인증을 구성하기 위한 매개변수를 지정합니다.

http-conf:tlsClientParameters

SSL/TLS를 구성하는 데 사용되는 매개변수를 지정합니다.

http-conf:basicAuthSupplier

엔드포인트에서 사용하는 기본 인증 정보를 선점하거나 401 HTTP 챌린지에 대한 응답으로 제공하는 object의 8080 참조 또는 클래스 이름을 지정합니다.

http-conf:trustDecider

정보가 전송되기 전에 HTTPS 서비스 공급자와의 연결에 대한 신뢰를 구축하기 위해 HTTP(S) URLConnection 개체를 확인하는 개체의 8080 참조 또는 클래스 이름을 지정합니다.

12.2.2.4. client 요소

http-conf:client 요소는 소비자 끝점의 HTTP 연결의 비보안 속성을 구성하는 데 사용됩니다. 표 12.2. “HTTP 소비자 구성 속성” 에 설명된 해당 속성은 연결의 속성을 지정합니다.

Expand
표 12.2. HTTP 소비자 구성 속성
속성설명

ConnectionTimeout

소비자가 시간 초과하기 전에 연결을 설정하려고 시도하는 시간(밀리초)을 지정합니다. 기본값은 30000 입니다.

0 은 소비자가 계속 요청을 무기한 전송하도록 지정합니다.

ReceiveTimeout

소비자가 시간 초과되기 전에 응답을 대기할 시간(밀리초)을 지정합니다. 기본값은 30000 입니다.

0 은 소비자가 무기한 대기하도록 지정합니다.

AutoRedirect

소비자가 서버의 리디렉션을 자동으로 따르는지 여부를 지정합니다. 기본값은 false입니다.

MaxRetransmits

소비자가 리디렉션을 충족하기 위해 요청을 다시 전송하는 최대 횟수를 지정합니다. 기본값은 -1 이며 무제한 재전송이 허용되도록 지정합니다.

AllowChunking

소비자가 청크를 사용하여 요청을 보낼지 여부를 지정합니다. 기본값은 true 로, 소비자가 요청을 보낼 때 청크를 사용하도록 지정합니다.

청크는 다음 중 하나에 해당하는 경우 사용할 수 없습니다.

  • HTTP-conf:basicAuthSupplier 는 선점하여 인증 정보를 제공하도록 구성되어 있습니다.
  • AutoRedirecttrue 로 설정됩니다.

두 경우 모두 AllowChunking 값이 무시되고 청크가 허용되지 않습니다.

accept

소비자가 처리할 준비가 된 미디어 유형을 지정합니다. 이 값은 HTTP Accept 속성의 값으로 사용됩니다. 속성 값은 다양한 용도의 인터넷 메일 확장(MIME) 유형을 사용하여 지정됩니다.

AcceptLanguage

소비자가 응답을 받기 위해 선호하는 언어(예: 미국 영어)를 지정합니다. 이 값은 HTTP AcceptLanguage 속성 값으로 사용됩니다.

언어 태그는 국제 표준 (ISO)에 의해 규제되며 일반적으로 하이픈으로 구분된 ISO-3166 표준에 의해 결정된 ISO-639 표준 및 국가 코드에 의해 결정되는 언어 코드를 결합하여 형성됩니다. 예를 들어 en-US는 미국 영어입니다.

AcceptEncoding

소비자가 처리할 준비가 된 콘텐츠 인코딩을 지정합니다. 컨텐츠 인코딩 라벨은 INA(Internet Assigned Numbers Authority)에 의해 규제됩니다. 이 값은 HTTP AcceptEncoding 속성 값으로 사용됩니다.

ContentType

메시지 본문에서 전송되는 데이터의 미디어 유형을 지정합니다. 미디어 유형은 다용도 인터넷 메일 확장(MIME) 유형을 사용하여 지정됩니다. 값은 HTTP ContentType 속성 값으로 사용됩니다. 기본값은 text/xml 입니다.

웹 서비스의 경우 이 값을 text/xml 로 설정해야 합니다. 클라이언트가 HTML 양식 데이터를 CGI 스크립트에 보내는 경우 application/x-www-form-urlencoded 로 설정해야 합니다. HTTP POST 요청이 고정된 페이로드 형식에 바인딩되는 경우 콘텐츠 유형은 일반적으로 application/octet-stream 으로 설정됩니다.

호스트

요청이 호출되는 리소스의 인터넷 호스트 및 포트 번호를 지정합니다. 이 값은 HTTP Host 속성 값으로 사용됩니다.

일반적으로 이 속성은 필요하지 않습니다. 이는 특정 DNS 시나리오 또는 애플리케이션 설계에만 필요합니다. 예를 들어 클라이언트가 클러스터의 호스트(즉, 동일한 인터넷 프로토콜(IP) 주소에 매핑되는 가상 서버의 경우)를 나타냅니다.

연결

각 요청/응답 대화 상자 후에 특정 연결을 열린 상태로 유지하거나 닫을지 여부를 지정합니다. 유효한 값은 다음 두 가지가 있습니다.

  • keep-Alive(기본값) - 초기 요청/응답 시퀀스 후에 소비자가 연결을 계속 열도록 지정합니다. 서버가 이를 준수하면 소비자가 닫을 때까지 연결이 열린 상태로 유지됩니다.
  • close - 각 요청/응답 시퀀스 후에 서버에 대한 연결이 닫혀 있음을 지정합니다.

CacheControl

소비자에서 서비스 공급자로의 요청을 구성하는 체인과 관련된 캐시에서 준수해야 하는 동작에 대한 지시문을 지정합니다. 12.2.4절. “소비자 캐시 제어 부여”을 참조하십시오.

쿠키

모든 요청과 함께 보낼 정적 쿠키를 지정합니다.

BrowserType

요청이 시작된 브라우저에 대한 정보를 지정합니다. W3C(World Wide Web Consortium)의 HTTP 사양에서 이 기능을 user-agent 라고도 합니다. 일부 서버는 요청을 전송하는 클라이언트에 따라 최적화됩니다.

Referer

소비자가 특정 서비스에 대한 요청을 수행하도록 지시하는 리소스의 URL을 지정합니다. 값은 HTTP Referer 속성의 값으로 사용됩니다.

이 HTTP 속성은 요청이 URL을 입력하는 대신 하이퍼링크를 클릭하는 브라우저의 결과일 때 사용됩니다. 이를 통해 서버에서 이전 작업 흐름을 기반으로 처리를 최적화하고 로깅, 최적화된 캐싱, 더 이상 사용되지 않는 링크 추적 등을 위해 리소스에 대한 백 링크 목록을 생성할 수 있습니다. 그러나 일반적으로 웹 서비스 애플리케이션에서는 사용되지 않습니다.

AutoRedirect 속성이 true 로 설정되고 요청이 리디렉션되는 경우 Referer 속성에 지정된 모든 값이 재정의됩니다. HTTP Referer 속성 값은 소비자의 원래 요청을 리디렉션하는 서비스의 URL로 설정됩니다.

DecoupledEndpoint

별도의 providerconsumer 연결을 통해 응답을 수신하기 위해 분리된 끝점의 URL을 지정합니다. 분리된 끝점 사용에 대한 자세한 내용은 12.6절. “Decoupled 모드에서 HTTP 전송 사용” 을 참조하십시오.

분리된 엔드포인트에 WS-Addressing을 사용하도록 소비자 끝점과 서비스 공급자 끝점을 모두 구성해야 합니다.

ProxyServer

요청을 라우팅하는 프록시 서버의 URL을 지정합니다.

ProxyServerPort

요청이 라우팅되는 프록시 서버의 포트 번호를 지정합니다.

ProxyServerType

요청을 라우팅하는 데 사용되는 프록시 서버의 유형을 지정합니다. 유효한 값은 다음과 같습니다.

  • HTTP(기본값)
  • SOCKS
12.2.2.5. 예제

예 12.6. “HTTP 소비자 끝점 구성” 요청 간에 열린 공급자를 유지하고, 호출당 한 번만 다시 전송되며 청크 스트림을 사용할 수 없는 HTTP 소비자 끝점의 구성이 표시됩니다.

예 12.6. HTTP 소비자 끝점 구성

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

  <http-conf:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit">
    <http-conf:client Connection="Keep-Alive"
                      MaxRetransmits="1"
                      AllowChunking="false" />
  </http-conf:conduit>
</beans>
Copy to Clipboard Toggle word wrap
12.2.2.6. 더 많은 정보

HTTP conduits에 대한 자세한 내용은 16장. conduits 을 참조하십시오.

12.2.3. WSDL 사용

12.2.3.1. 네임스페이스

HTTP 소비자 끝점을 구성하는 데 사용되는 WSDL 확장 요소는 http://cxf.apache.org/transports/http/configuration 네임스페이스에 정의됩니다. 일반적으로 접두사 http-conf 를 사용합니다. HTTP 구성 요소를 사용하려면 예 12.7. “HTTP Consumer WSDL Element의 네임스페이스” 에 표시된 행을 끝점의 WSDL 문서의 definitions 요소에 추가해야 합니다.

예 12.7. HTTP Consumer WSDL Element의 네임스페이스

<definitions ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
Copy to Clipboard Toggle word wrap
12.2.3.2. Cryostat 런타임 또는 Netty 런타임

http-conf 네임스페이스의 요소를 사용하여 Cryostat 런타임 또는 Netty 런타임을 구성할 수 있습니다.

12.2.3.3. client 요소

http-conf:client 요소는 WSDL 문서에서 HTTP 소비자의 연결 속성을 지정하는 데 사용됩니다. http-conf:client 요소는 WSDL 포트 요소의 자식입니다. 구성 파일에 사용된 클라이언트 요소와 동일한 특성을 갖습니다. 속성은 표 12.2. “HTTP 소비자 구성 속성” 에 설명되어 있습니다.

12.2.3.4. 예제

예 12.8. “HTTP 소비자 끝점을 구성하는 WSDL” 은 캐시와 상호 작용하지 않도록 HTTP 소비자 끝점을 구성하는 WSDL 조각을 표시합니다.

예 12.8. HTTP 소비자 끝점을 구성하는 WSDL

<service ... >
  <port ... >
    <soap:address ... />
    <http-conf:client CacheControl="no-cache" />
  </port>
</service>
Copy to Clipboard Toggle word wrap

12.2.4. 소비자 캐시 제어 부여

표 12.3. “HTTP-conf:클라이언트 캐시 제어 부여” HTTP 소비자가 지원하는 캐시 제어 지시문을 나열합니다.

Expand
표 12.3. HTTP-conf:클라이언트 캐시 제어 부여
지시문동작

no-cache

캐시는 먼저 서버와 해당 응답을 재평가하지 않고 후속 요청을 충족하기 위해 특정 응답을 사용할 수 없습니다. 이 값으로 특정 응답 헤더 필드를 지정하는 경우 제한은 응답 내의 해당 헤더 필드에만 적용됩니다. 응답 헤더 필드를 지정하지 않으면 제한 사항이 전체 응답에 적용됩니다.

no-store

캐시는 응답의 일부 또는 이를 호출한 요청의 일부를 저장하지 않아야 합니다.

max-age

사용자는 나이가 지정된 시간(초)보다 큰 응답을 허용할 수 있습니다.

max-stale

소비자는 만료 시간을 초과한 응답을 허용할 수 있습니다. max-stale에 값이 할당되면 소비자가 여전히 해당 응답을 허용할 수 있는 응답의 만료 시간 이후의 시간(초)을 나타냅니다. 값이 할당되지 않은 경우 소비자는 나이의 오래된 응답을 허용할 수 있습니다.

min-fresh

소비자는 표시된 지정된 시간(초) 동안 여전히 새로워진 응답을 원합니다.

no-transform

캐시는 공급자와 소비자 간 응답에서 콘텐츠의 미디어 유형 또는 위치를 수정하지 않아야 합니다.

only-if-cached

캐시는 현재 캐시에 저장된 응답만 반환해야 하며 다시 로드하거나 무효화해야 하는 응답은 반환해서는 안 됩니다.

cache-extension

다른 캐시 지시문에 대한 추가 확장을 지정합니다. 확장 기능은 정보 또는 동작일 수 있습니다. 확장된 지시문은 표준 지시문의 컨텍스트에서 지정되므로 확장된 지시문을 인식하지 못하는 애플리케이션에서 표준 지시문에서 요구하는 동작을 준수할 수 있습니다.

12.3. 서비스 공급자 구성

12.3.1. HTTP 서비스 공급자의 메커니즘

HTTP 서비스 공급자 끝점은 활성 요청을 계속 유지하는지, 캐시와 상호 작용하는 방법, 소비자와 통신할 때 오류임을 허용하는 방법을 포함하여 다수의 HTTP 연결 속성을 지정할 수 있습니다.

서비스 공급자 끝점은 다음 두 가지 메커니즘을 사용하여 구성할 수 있습니다.

12.3.2. 설정 사용

12.3.2.1. 네임스페이스

HTTP 공급자 끝점을 구성하는 데 사용되는 요소는 네임스페이스 http://cxf.apache.org/transports/http/configuration 에 정의되어 있습니다. 일반적으로 접두사 http-conf 를 사용합니다. HTTP 구성 요소를 사용하려면 예 12.9. “HTTP 공급자 구성 네임스페이스” 에 표시된 행을 끝점 구성 파일의 요소에 추가해야 합니다. 또한 구성 요소의 네임스페이스를 xsi:schemaLocation 속성에 추가해야 합니다.

예 12.9. HTTP 공급자 구성 네임스페이스

<beans ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       ...
       xsi:schemaLocation="...
                           http://cxf.apache.org/transports/http/configuration
                              http://cxf.apache.org/schemas/configuration/http-conf.xsd
                          ...">
Copy to Clipboard Toggle word wrap
12.3.2.2. Cryostat 런타임 또는 Netty 런타임

http-conf 네임스페이스의 요소를 사용하여 Cryostat 런타임 또는 Netty 런타임을 구성할 수 있습니다.

12.3.2.3. 대상 요소

http-conf:destination 요소 및 해당 하위 요소를 사용하여 HTTP 서비스 공급자 끝점을 구성합니다. http-conf:destination 요소는 엔드포인트에 해당하는 WSDL 포트 요소를 지정하는 단일 속성 name 을 사용합니다. name 속성 값은 portQName'.http-destination' 형식을 사용합니다. 예 12.10. “HTTP-conf:destination 요소” 끝점의 대상 네임스페이스가 http://widgets.widgetvendor.net인 경우 WSDL 조각 < port binding="widgetSOAPBinding" name="widgetSOAPPort >에서 지정하는 끝점에 대한 구성을 추가하는 데 사용되는 http-conf:destination 요소를 표시합니다.

예 12.10. HTTP-conf:destination 요소

...
  <http-conf:destination name="{http://widgets/widgetvendor.net}widgetSOAPPort.http-destination">
    ...
  </http-conf:destination>
...
Copy to Clipboard Toggle word wrap

http-conf:destination 요소에는 구성 정보를 지정하는 여러 하위 요소가 있습니다. 해당 내용은 표 12.4. “HTTP 서비스 공급자 끝점을 구성하는 데 사용되는 요소” 에 설명되어 있습니다.

Expand
표 12.4. HTTP 서비스 공급자 끝점을 구성하는 데 사용되는 요소
element설명

http-conf:server

HTTP 연결 속성을 지정합니다. “server 요소”을 참조하십시오.

http-conf:contextMatchStrategy

HTTP 요청을 처리하기 위한 컨텍스트 일치 전략을 구성하는 매개변수를 지정합니다.

http-conf:fixedParameterOrder

이 대상이 처리하는 HTTP 요청의 매개변수 순서가 수정되었는지 여부를 지정합니다.

12.3.2.4. server 요소

http-conf:server 요소는 서비스 공급자 끝점의 HTTP 연결의 속성을 구성하는 데 사용됩니다. 표 12.5. “HTTP 서비스 공급자 구성 속성” 에 설명된 해당 속성은 연결의 속성을 지정합니다.

Expand
표 12.5. HTTP 서비스 공급자 구성 속성
속성설명

ReceiveTimeout

연결 시간이 초과되기 전에 서비스 공급자가 요청을 수신하려고 시도하는 시간(밀리초)을 설정합니다. 기본값은 30000 입니다.

0 은 공급자가 시간 초과되지 않도록 지정합니다.

SuppressClientSendErrors

요청을 수신할 때 오류가 발생할 때 예외가 throw되는지 여부를 지정합니다. 기본값은 false 입니다. 오류가 발생할 때 예외가 발생합니다.

SuppressClientReceiveErrors

소비자에게 응답을 보낼 때 오류가 발생할 때 예외가 throw되는지 여부를 지정합니다. 기본값은 false 입니다. 오류가 발생할 때 예외가 발생합니다.

HonorKeepAlive

응답이 전송된 후 서비스 공급자가 연결에 대한 요청을 열린 상태로 유지할지 여부를 지정합니다. 기본값은 false 입니다. keep-alive 요청은 무시됩니다.

RedirectURL

클라이언트 요청에 지정된 URL이 요청된 리소스에 더 이상 적합하지 않은 경우 클라이언트 요청을 리디렉션해야 하는 URL을 지정합니다. 이 경우 서버 응답의 첫 번째 줄에서 상태 코드가 자동으로 설정되지 않으면 상태 코드가 302로 설정되고 상태 설명은 Object Moved로 설정됩니다. 이 값은 HTTP RedirectURL 속성 값으로 사용됩니다.

CacheControl

서비스 공급자에서 소비자로의 응답을 포함하는 체인과 관련된 캐시에서 준수해야 하는 동작에 대한 지시문을 지정합니다. 12.3.4절. “서비스 공급자 캐시 제어 방식”을 참조하십시오.

ContentLocation

응답에서 리소스를 보내는 URL을 설정합니다.

ContentType

응답에서 전송되는 정보의 미디어 유형을 지정합니다. 미디어 유형은 다용도 인터넷 메일 확장(MIME) 유형을 사용하여 지정됩니다. 이 값은 HTTP ContentType 위치 값으로 사용됩니다.

ContentEncoding

서비스 공급자가 보내는 정보에 적용된 추가 콘텐츠 인코딩을 지정합니다. 컨텐츠 인코딩 라벨은 INA(Internet Assigned Numbers Authority)에 의해 규제됩니다. 가능한 콘텐츠 인코딩 값에는 zip, gzip, compress, deflate, identity가 포함됩니다. 이 값은 HTTP ContentEncoding 속성 값으로 사용됩니다.

콘텐츠 인코딩의 주요 용도는 zip 또는 gzip과 같은 일부 인코딩 메커니즘을 사용하여 문서를 압축할 수 있도록 하는 것입니다. Apache CXF는 콘텐츠 코딩에 대한 유효성 검사를 수행하지 않습니다. 애플리케이션 수준에서 지정된 콘텐츠 코딩이 지원되도록 하는 것은 사용자의 책임이 있습니다.

ServerType

응답을 전송하는 서버 유형을 지정합니다. 값은 프로그램 이름/버전(예: Apache/ 1.2.5 )을 사용합니다.

12.3.2.5. 예제

예 12.11. “HTTP 서비스 공급자 끝점 구성” keep-alive 요청을 준수하고 모든 통신 오류를 비활성화하는 HTTP 서비스 공급자 끝점의 구성을 표시합니다.

예 12.11. HTTP 서비스 공급자 끝점 구성

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

  <http-conf:destination name="{http://apache.org/hello_world_soap_http}SoapPort.http-destination">
    <http-conf:server SuppressClientSendErrors="true"
                      SuppressClientReceiveErrors="true"
                      HonorKeepAlive="true" />
  </http-conf:destination>
</beans>
Copy to Clipboard Toggle word wrap

12.3.3. WSDL 사용

12.3.3.1. 네임스페이스

HTTP 공급자 끝점을 구성하는 데 사용되는 WSDL 확장 요소는 http://cxf.apache.org/transports/http/configuration 네임스페이스에 정의됩니다. 일반적으로 접두사 http-conf 를 사용합니다. HTTP 구성 요소를 사용하려면 예 12.12. “HTTP 공급자 WSDL 요소의 네임스페이스” 에 표시된 행을 끝점의 WSDL 문서의 definitions 요소에 추가해야 합니다.

예 12.12. HTTP 공급자 WSDL 요소의 네임스페이스

<definitions ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
Copy to Clipboard Toggle word wrap
12.3.3.2. Cryostat 런타임 또는 Netty 런타임

http-conf 네임스페이스의 요소를 사용하여 Cryostat 런타임 또는 Netty 런타임을 구성할 수 있습니다.

12.3.3.3. server 요소

http-conf:server 요소는 WSDL 문서에서 HTTP 서비스 공급자의 연결 속성을 지정하는 데 사용됩니다. http-conf:server 요소는 WSDL 포트 요소의 자식입니다. 구성 파일에 사용된 server 요소와 동일한 특성을 갖습니다. 속성은 표 12.5. “HTTP 서비스 공급자 구성 속성” 에 설명되어 있습니다.

12.3.3.4. 예제

예 12.13. “HTTP 서비스 공급자 끝점을 구성하는 WSDL” 은 캐시와 상호 작용하지 않도록 지정하는 HTTP 서비스 공급자 끝점을 구성하는 WSDL 조각을 표시합니다.

예 12.13. HTTP 서비스 공급자 끝점을 구성하는 WSDL

<service ... >
  <port ... >
    <soap:address ... />
    <http-conf:server CacheControl="no-cache" />
  </port>
</service>
Copy to Clipboard Toggle word wrap

12.3.4. 서비스 공급자 캐시 제어 방식

표 12.6. “HTTP-conf:서버 캐시 제어ights” HTTP 서비스 공급자가 지원하는 캐시 제어 지시문을 나열합니다.

Expand
표 12.6. HTTP-conf:서버 캐시 제어ights
지시문동작

no-cache

캐시는 먼저 서버와 해당 응답을 재평가하지 않고 후속 요청을 충족하기 위해 특정 응답을 사용할 수 없습니다. 이 값으로 특정 응답 헤더 필드를 지정하는 경우 제한은 응답 내의 해당 헤더 필드에만 적용됩니다. 응답 헤더 필드를 지정하지 않으면 제한 사항이 전체 응답에 적용됩니다.

공개

모든 캐시는 응답을 저장할 수 있습니다.

비공개

응답은 단일 사용자를 위한 것이므로 공용(공유) 캐시는 응답을 저장할 수 없습니다. 이 값으로 특정 응답 헤더 필드를 지정하는 경우 제한은 응답 내의 해당 헤더 필드에만 적용됩니다. 응답 헤더 필드를 지정하지 않으면 제한 사항이 전체 응답에 적용됩니다.

no-store

캐시는 응답의 일부 또는 이를 호출한 요청의 일부를 저장하지 않아야 합니다.

no-transform

캐시는 서버와 클라이언트 간의 응답에서 콘텐츠의 미디어 유형 또는 위치를 수정하지 않아야 합니다.

must-revalidate

캐시는 후속 응답에서 해당 항목을 사용하기 전에 응답과 관련된 만료된 항목을 다시 검증해야 합니다.

proxy-revalidate

공유 캐시에서만 적용할 수 있고 비공개 비공유 캐시에서 무시할 수 있다는 점을 제외하고 must-revalidate와 동일합니다. 이 지시문을 사용하는 경우 공용 cache 지시문도 사용해야 합니다.

max-age

클라이언트는 지정된 시간(초)보다 경과하지 않는 응답을 허용할 수 있습니다.

s-max-age

공유 캐시에만 적용할 수 있고 비공개 비공유 캐시에서 무시된다는 점을 제외하고 max-age와 동일합니다. s-max-age로 지정된 기간은 max-age로 지정된 기간을 재정의합니다. 이 지시문을 사용하는 경우 proxy-revalidate 지시문도 사용해야 합니다.

cache-extension

다른 캐시 지시문에 대한 추가 확장을 지정합니다. 확장 기능은 정보 또는 동작일 수 있습니다. 확장된 지시문은 표준 지시문의 컨텍스트에서 지정되므로 확장된 지시문을 인식하지 못하는 애플리케이션에서 표준 지시문에서 요구하는 동작을 준수할 수 있습니다.

12.4. Cryostat 런타임 구성

12.4.1. 개요

Cryostat 런타임은 분리된 엔드포인트를 사용하는 HTTP 서비스 공급자 및 HTTP 소비자가 사용합니다. 런타임의 스레드 풀을 구성할 수 있으며, Cryostat 런타임을 통해 HTTP 서비스 공급자에 대한 여러 보안 설정을 설정할 수도 있습니다.

12.4.2. Maven 종속성

Apache Maven을 빌드 시스템으로 사용하는 경우 프로젝트의 pom.xml 파일에 다음 종속성을 포함하여 프로젝트에 Cryostat 런타임을 추가할 수 있습니다.

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-undertow</artifactId>
    <version>${cxf-version}</version>
</dependency>
Copy to Clipboard Toggle word wrap

12.4.3. 네임스페이스

Cryostat 런타임을 구성하는 데 사용되는 요소는 네임스페이스 http://cxf.apache.org/transports/http-undertow/configuration 에 정의되어 있습니다. Cryostat 구성 요소를 사용하려면 예 12.14. “Cryostat 런타임 구성 네임스페이스” 에 표시된 행을 끝점 구성 파일의 beans 요소에 추가해야 합니다. 이 예에서는 네임스페이스에 httpu 접두사가 할당됩니다. 또한 구성 요소의 네임스페이스를 xsi:schemaLocation 속성에 추가해야 합니다.

예 12.14. Cryostat 런타임 구성 네임스페이스

<beans ...
       xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration"
       ...
       xsi:schemaLocation="...
                           http://cxf.apache.org/transports/http-undertow/configuration
                              http://cxf.apache.org/schemas/configuration/http-undertow.xsd
                          ...">
Copy to Clipboard Toggle word wrap

12.4.4. engine-factory 요소

httpu:engine-factory 요소는 애플리케이션에서 사용하는 Cryostat 런타임을 구성하는 데 사용되는 root 요소입니다. 여기에는 구성 중인 Cryostat 인스턴스를 관리하는 버스 의 이름이 값이 되는 단일 필수 속성 bus가 있습니다.

참고

값은 일반적으로 기본 버스 인스턴스의 이름인 cxf 입니다.

http:engine-factory 요소에는 Cryostat 런타임 팩토리에서 인스턴스화한 HTTP 포트를 구성하는 데 사용되는 정보가 포함된 세 개의 자식이 있습니다. 하위 항목은 표 12.7. “Cryostat 런타임을 구성하는 요소” 에 설명되어 있습니다.

Expand
표 12.7. Cryostat 런타임을 구성하는 요소
element설명

httpu:engine

특정 Cryostat 런타임 인스턴스에 대한 구성을 지정합니다. “engine 요소”을 참조하십시오.

httpu:identifiedTLSServerParameters

HTTP 서비스 공급자의 보안을 위해 재사용 가능한 속성 집합을 지정합니다. 속성 집합을 참조할 수 있는 고유 식별자를 지정하는 단일 속성 id 가 있습니다.

httpu:identifiedThreadingParameters

Cryostat 인스턴스의 스레드 풀을 제어하기 위한 재사용 가능한 속성 세트를 지정합니다. 속성 집합을 참조할 수 있는 고유 식별자를 지정하는 단일 속성 id 가 있습니다.

“스레드 풀 구성”을 참조하십시오.

12.4.5. engine 요소

httpu:engine 요소는 Cryostat 런타임의 특정 인스턴스를 구성하는 데 사용됩니다. 이 속성에는 undertow 및 port 가 포함된 글로벌 IP 주소를 지정하는 host 라는 두 가지 속성이 있으며, 이 속성은 Cryostat 인스턴스에서 관리하는 포트의 수를 지정합니다.

참고

port 특성에 값을 0 으로 지정할 수 있습니다. port 속성이 0 으로 설정된 httpu:engine 요소에 지정된 스레딩 속성은 명시적으로 구성되지 않은 모든 Cryostat 리스너의 구성으로 사용됩니다.

httpu:engine 요소에는 두 개의 하위 요소가 있을 수 있습니다. 하나는 보안 속성 구성용이고 다른 하나는 instance의 스레드 풀을 구성하기 위한 것입니다. 각 유형의 구성에 대해 구성 정보를 직접 제공하거나 상위 httpu:engine-factory 요소에 정의된 구성 속성 집합에 대한 참조를 제공할 수 있습니다.

구성 속성을 제공하는 데 사용되는 하위 요소는 표 12.8. “Cryostat 런타임 인스턴스 구성을 위한 요소” 에 설명되어 있습니다.

Expand
표 12.8. Cryostat 런타임 인스턴스 구성을 위한 요소
element설명

httpu:tlsServerParameters

특정 Cryostat 인스턴스에 사용되는 보안을 구성하기 위한 속성 세트를 지정합니다.

httpu:tlsServerParametersRef

identifiedTLSServerParameters 요소에서 정의한 보안 속성 세트를 나타냅니다. id 속성은 참조된 identifiedTLSServerParameters 요소의 ID를 제공합니다.

httpu:threadingParameters

특정 Cryostat 인스턴스에서 사용하는 스레드 풀의 크기를 지정합니다. “스레드 풀 구성”을 참조하십시오.

httpu:threadingParametersRef

identifiedThreadingParameters 요소에 의해 정의된 속성 세트를 나타냅니다. id 속성은 참조된 identifiedThreadingParameters 요소의 id를 제공합니다.

12.4.6. 스레드 풀 구성

다음 중 하나를 통해 Cryostat 인스턴스의 스레드 풀 크기를 구성할 수 있습니다.

  • engine-factory 요소에서 identifiedThreadingParameters 요소를 사용하여 스레드 풀의 크기를 지정합니다. 그런 다음 threadingParametersRef 요소를 사용하여 요소를 참조합니다.
  • threadingParameters 요소를 사용하여 스레드 풀의 크기를 직접 지정합니다.

threadingParameters 에는 스레드 풀의 크기를 지정하는 두 가지 특성이 있습니다. 속성은 표 12.9. “Cryostat 스레드 풀 구성의 속성” 에 설명되어 있습니다.

참고

httpu:identifiedThreadingParameters 요소에는 단일 하위 스레딩 매개 변수가 있습니다.

Expand
표 12.9. Cryostat 스레드 풀 구성의 속성
속성설명

workerIOThreads

작업자에 대해 생성할 I/O 스레드 수를 지정합니다. 지정하지 않으면 dafult 값이 선택됩니다. 기본값은 CPU 코어당 하나의 I/O 스레드입니다.

minThreads

요청을 처리하는 데 사용할 수 있는 최소 스레드 수를 지정합니다.

maxThreads

요청을 처리하는 데 사용할 수 있는 최대 스레드 수를 지정합니다.

12.4.7. 예제

예 12.15. “Cryostat 인스턴스 구성” 는 포트 번호 9001에서 Cryostat 인스턴스를 구성하는 구성 조각을 표시합니다.

예 12.15. Cryostat 인스턴스 구성

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:sec="http://cxf.apache.org/configuration/security"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration"
  xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
  xsi:schemaLocation="http://cxf.apache.org/configuration/security
  		      http://cxf.apache.org/schemas/configuration/security.xsd
            http://cxf.apache.org/transports/http/configuration
            http://cxf.apache.org/schemas/configuration/http-conf.xsd
            http://cxf.apache.org/transports/http-undertow/configuration
            http://cxf.apache.org/schemas/configuration/http-undertow.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  ...

  <httpu:engine-factory bus="cxf">
    <httpu:identifiedTLSServerParameters id="secure">
      <sec:keyManagers keyPassword="password">
        <sec:keyStore type="JKS" password="password"
                      file="certs/cherry.jks"/>
      </sec:keyManagers>
    </httpu:identifiedTLSServerParameters>

    <httpu:engine port="9001">
      <httpu:tlsServerParametersRef id="secure" />
      <httpu:threadingParameters minThreads="5"
                                 maxThreads="15" />
    </httpu:engine>
  </httpu:engine-factory>
 </beans>
Copy to Clipboard Toggle word wrap

12.4.8. 동시 요청 및 큐 크기 제한

최대 동시 연결 요청 수 및 Cryostat 서버 인스턴스에서 처리할 수 있는 큐 크기에 대한 제한을 설정하는 Request Limiting Handler를 구성할 수 있습니다. 이 구성의 예는 다음과 같습니다. 예 12.16. “연결 요청 및 큐 크기 제한”

Expand
표 12.10. 요청 제한 처리기 구성을 위한 속성
속성설명

maximumConcurrentRequests

Cryostat 인스턴스에서 처리할 수 있는 최대 동시 요청 수를 지정합니다. 요청 수가 이 제한을 초과하면 요청이 대기열에 추가됩니다.

queueSize

Cryostat 인스턴스에서 처리하기 위해 대기열에 포함될 수 있는 총 요청 수를 지정합니다. 요청 수가 이 제한을 초과하면 요청이 거부됩니다.

예 12.16. 연결 요청 및 큐 크기 제한

<httpu:engine-factory>
     <httpu:engine port="8282">
         <httpu:handlers>
             <bean class="org.jboss.fuse.quickstarts.cxf.soap.CxfRequestLimitingHandler">
                 <property name="maximumConcurrentRequests" value="1" />
                 <property name="queueSize" value="1"/>
             </bean>
         </httpu:handlers>
     </httpu:engine>
</httpu:engine-factory>
Copy to Clipboard Toggle word wrap

12.5. Netty Runtime 구성

12.5.1. 개요

Netty 런타임은 분리된 엔드포인트를 사용하는 HTTP 서비스 공급자 및 HTTP 소비자가 사용합니다. 런타임의 스레드 풀을 구성할 수 있으며 Netty 런타임을 통해 HTTP 서비스 공급자에 대한 여러 보안 설정을 설정할 수도 있습니다.

12.5.2. Maven 종속 항목

Apache Maven을 빌드 시스템으로 사용하는 경우 프로젝트의 pom.xml 파일에 다음 종속성을 포함하여 Netty 런타임(웹 서비스 엔드포인트 정의)의 서버 측 구현을 프로젝트에 추가할 수 있습니다.

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-netty-server</artifactId>
    <version>${cxf-version}</version>
</dependency>
Copy to Clipboard Toggle word wrap

프로젝트의 pom.xml 파일에 다음 종속성을 포함하여 Netty 런타임의 클라이언트 측 구현을 프로젝트에 추가할 수 있습니다.

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-netty-client</artifactId>
    <version>${cxf-version}</version>
</dependency>
Copy to Clipboard Toggle word wrap

12.5.3. 네임스페이스

Netty 런타임을 구성하는 데 사용되는 요소는 네임스페이스 http://cxf.apache.org/transports/http-netty-server/configuration 에 정의되어 있습니다. 일반적으로 httpn 접두사를 사용합니다. Netty 구성 요소를 사용하려면 예 12.17. “Netty 런타임 구성 네임스페이스” 에 표시된 행을 끝점 구성 파일의 요소에 추가해야 합니다. 또한 구성 요소의 네임스페이스를 xsi:schemaLocation 속성에 추가해야 합니다.

예 12.17. Netty 런타임 구성 네임스페이스

<beans ...
       xmlns:httpn="http://cxf.apache.org/transports/http-netty-server/configuration"
       ...
       xsi:schemaLocation="...
               http://cxf.apache.org/transports/http-netty-server/configuration
            http://cxf.apache.org/schemas/configuration/http-netty-server.xsd
               ...">
Copy to Clipboard Toggle word wrap

12.5.4. engine-factory 요소

httpn:engine-factory 요소는 애플리케이션에서 사용하는 Netty 런타임을 구성하는 데 사용되는 root 요소입니다. 여기에는 설정 중인 Netty 인스턴스를 관리하는 Bus 의 이름이 값이 되는 단일 필수 속성 bus 가 있습니다.

참고

값은 일반적으로 기본 버스 인스턴스의 이름인 cxf 입니다.

httpn:engine-factory 요소에는 Netty 런타임 팩토리에서 인스턴스화한 HTTP 포트를 구성하는 데 사용되는 정보가 포함된 세 개의 자식 요소가 있습니다. 하위 항목은 표 12.11. “Netty Runtime Cryostat 구성 요소” 에 설명되어 있습니다.

Expand
표 12.11. Netty Runtime Cryostat 구성 요소
element설명

httpn:engine

특정 Netty 런타임 인스턴스에 대한 구성을 지정합니다. “engine 요소”을 참조하십시오.

httpn:identifiedTLSServerParameters

HTTP 서비스 공급자의 보안을 위해 재사용 가능한 속성 집합을 지정합니다. 속성 집합을 참조할 수 있는 고유 식별자를 지정하는 단일 속성 id 가 있습니다.

httpn:identifiedThreadingParameters

Netty 인스턴스의 스레드 풀을 제어하기 위한 재사용 가능한 속성 집합을 지정합니다. 속성 집합을 참조할 수 있는 고유 식별자를 지정하는 단일 속성 id 가 있습니다.

“스레드 풀 구성”을 참조하십시오.

12.5.5. engine 요소

httpn:engine 요소는 Netty 런타임의 특정 인스턴스를 구성하는 데 사용됩니다. 표 12.12. “Netty Runtime 인스턴스 구성을 위한 속성” httpn:engine 요소에서 지원하는 속성을 표시합니다.

Expand
표 12.12. Netty Runtime 인스턴스 구성을 위한 속성
속성설명

port

Netty HTTP 서버 인스턴스에서 사용하는 포트를 지정합니다. port 특성에 값을 0 으로 지정할 수 있습니다. port 속성이 0 으로 설정된 엔진 요소에 지정된 스레딩 속성은 명시적으로 구성되지 않은 모든 Netty 리스너의 구성으로 사용됩니다.

host

Netty HTTP 서버 인스턴스에서 사용하는 수신 주소를 지정합니다. 값은 호스트 이름 또는 IP 주소일 수 있습니다. 지정하지 않으면 Netty HTTP 서버가 모든 로컬 주소에서 수신 대기합니다.

readIdleTime

Netty 연결의 최대 읽기 유휴 시간을 지정합니다. 기본 스트림에 읽기 작업이 있을 때마다 타이머가 재설정됩니다.

writeIdleTime

Netty 연결의 최대 쓰기 유휴 시간을 지정합니다. 기본 스트림에 쓰기 작업이 있을 때마다 타이머가 재설정됩니다.

maxChunkContentSize

Netty 연결의 최대 집계된 콘텐츠 크기를 지정합니다. 기본값은 10MB입니다.

httpn:engine 요소에는 보안 속성을 구성하기 위한 하나의 하위 요소와 Netty 인스턴스의 스레드 풀을 구성하기 위한 하나의 하위 요소가 있습니다. 각 유형의 구성에 대해 구성 정보를 직접 제공하거나 상위 httpn:engine-factory 요소에 정의된 구성 속성 집합에 대한 참조를 제공할 수 있습니다.

httpn:engine 에서 지원되는 하위 요소는 표 12.13. “Netty 런타임 인스턴스 구성을 위한 요소” 에 표시됩니다.

Expand
표 12.13. Netty 런타임 인스턴스 구성을 위한 요소
element설명

httpn:tlsServerParameters

특정 Netty 인스턴스에 사용되는 보안을 구성하기 위한 속성 세트를 지정합니다.

httpn:tlsServerParametersRef

identifiedTLSServerParameters 요소에서 정의한 보안 속성 세트를 나타냅니다. id 속성은 참조된 identifiedTLSServerParameters 요소의 ID를 제공합니다.

httpn:threadingParameters

특정 Netty 인스턴스에서 사용하는 스레드 풀의 크기를 지정합니다. “스레드 풀 구성”을 참조하십시오.

httpn:threadingParametersRef

identifiedThreadingParameters 요소에 의해 정의된 속성 세트를 나타냅니다. id 속성은 참조된 identifiedThreadingParameters 요소의 id를 제공합니다.

httpn:sessionSupport

true 인 경우 HTTP 세션에 대한 지원을 활성화합니다. 기본값은 false 입니다.

httpn:reuseAddress

ReuseAddress TCP 소켓 옵션을 설정하는 부울 값을 지정합니다. 기본값은 false 입니다.

12.5.6. 스레드 풀 구성

다음 중 하나를 통해 Netty 인스턴스의 스레드 풀 크기를 구성할 수 있습니다.

  • engine-factory 요소에서 identifiedThreadingParameters 요소를 사용하여 스레드 풀의 크기를 지정합니다. 그런 다음 threadingParametersRef 요소를 사용하여 요소를 참조합니다.
  • threadingParameters 요소를 사용하여 스레드 풀의 크기를 직접 지정합니다.

threadingParameters 요소에는 표 12.14. “Netty Thread Pool 구성의 속성” 에 설명된 대로 스레드 풀의 크기를 지정하는 하나의 속성이 있습니다.

참고

httpn:identifiedThreadingParameters 요소에는 단일 하위 스레딩 매개 변수가 있습니다.

Expand
표 12.14. Netty Thread Pool 구성의 속성
속성설명

threadPoolSize

요청을 처리하기 위해 Netty 인스턴스에서 사용할 수 있는 스레드 수를 지정합니다.

12.5.7. 예제

예 12.18. “Netty 인스턴스 구성” 다양한 Netty 포트를 구성하는 구성 조각을 표시합니다.

예 12.18. Netty 인스턴스 구성

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:h="http://cxf.apache.org/transports/http/configuration"
       xmlns:httpn="http://cxf.apache.org/transports/http-netty-server/configuration"
       xmlns:sec="http://cxf.apache.org/configuration/security"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/configuration/security
            http://cxf.apache.org/schemas/configuration/security.xsd
        http://cxf.apache.org/transports/http/configuration
            http://cxf.apache.org/schemas/configuration/http-conf.xsd
        http://cxf.apache.org/transports/http-netty-server/configuration
            http://cxf.apache.org/schemas/configuration/http-netty-server.xsd"
>
    ...
    <httpn:engine-factory bus="cxf">
       <httpn:identifiedTLSServerParameters id="sample1">
         <httpn:tlsServerParameters jsseProvider="SUN" secureSocketProtocol="TLS">
            <sec:clientAuthentication want="false" required="false"/>
         </httpn:tlsServerParameters>
       </httpn:identifiedTLSServerParameters>

       <httpn:identifiedThreadingParameters id="sampleThreading1">
          <httpn:threadingParameters threadPoolSize="120"/>
       </httpn:identifiedThreadingParameters>

       <httpn:engine port="9000" readIdleTime="30000" writeIdleTime="90000">
          <httpn:threadingParametersRef id="sampleThreading1"/>
       </httpn:engine>

       <httpn:engine port="0">
          <httpn:threadingParameters threadPoolSize="400"/>
       </httpn:engine>

       <httpn:engine port="9001" readIdleTime="40000" maxChunkContentSize="10000">
         <httpn:threadingParameters threadPoolSize="99" />
         <httpn:sessionSupport>true</httpn:sessionSupport>
       </httpn:engine>

       <httpn:engine port="9002">
         <httpn:tlsServerParameters>
           <sec:clientAuthentication want="true" required="true"/>
         </httpn:tlsServerParameters>
       </httpn:engine>

       <httpn:engine port="9003">
          <httpn:tlsServerParametersRef id="sample1"/>
       </httpn:engine>

    </httpn:engine-factory>
</beans>
Copy to Clipboard Toggle word wrap

12.6. Decoupled 모드에서 HTTP 전송 사용

12.6.1. 개요

일반적인 HTTP 요청/응답 시나리오에서는 요청과 응답이 동일한 HTTP 연결을 사용하여 전송됩니다. 서비스 공급자는 요청을 처리하고 적절한 HTTP 상태 코드 및 응답 내용을 포함하는 응답으로 응답합니다. 요청이 성공하면 HTTP 상태 코드가 200으로 설정됩니다.

WS-RM을 사용하거나 요청을 실행하는 데 시간이 오래 걸리는 경우와 같은 일부 경우 요청 및 응답 메시지를 분리하는 것이 좋습니다. 이 경우 서비스 공급자는 요청이 수신된 HTTP 연결의 백채널을 통해 소비자에게 202 Accepted 응답을 보냅니다. 그런 다음 요청을 처리하고 새 분리된 서버를 사용하여 응답을 다시 소비자로 보냅니다. 소비자 런타임은 들어오는 응답을 수신하고 애플리케이션 코드로 돌아가기 전에 적절한 요청과 관련이 있습니다.

12.6.2. 분리된 상호 작용 구성

분리된 모드에서 HTTP 전송을 사용하려면 다음을 수행해야 합니다.

  1. WS-Addressing을 사용하도록 소비자를 구성합니다.

    “WS-Addressing을 사용하도록 끝점 구성”을 참조하십시오.

  2. 분리된 엔드포인트를 사용하도록 소비자를 구성합니다.

    “소비자 구성”을 참조하십시오.

  3. 소비자가 WS-Addressing을 사용하도록 상호 작용하는 모든 서비스 공급자를 구성합니다.

    “WS-Addressing을 사용하도록 끝점 구성”을 참조하십시오.

12.6.3. WS-Addressing을 사용하도록 끝점 구성

소비자가 WS-Addressing을 사용하는 소비자 및 모든 서비스 공급자를 지정합니다.

끝점에서 WS-Addressing을 두 가지 방법 중 하나로 사용하도록 지정할 수 있습니다.

  • 예 12.19. “WSDL을 사용하여 WS-Addressing 활성화” 에 표시된 대로 wswa:UsingAddressing 요소를 끝점의 WSDL 포트 요소에 추가합니다.

    예 12.19. WSDL을 사용하여 WS-Addressing 활성화

    ...
    <service name="WidgetSOAPService">
      <port name="WidgetSOAPPort" binding="tns:WidgetSOAPBinding">
        <soap:address="http://widgetvendor.net/widgetSeller" />
        <wswa:UsingAddressing xmlns:wswa="http://www.w3.org/2005/02/addressing/wsdl"/>
      </port>
    </service>
    ...
    Copy to Clipboard Toggle word wrap
  • 예 12.20. “정책을 사용하여 WS-Addressing 활성화” 와 같이 끝점의 WSDL 포트 요소에 WS-Addressing 정책을 추가합니다.

    예 12.20. 정책을 사용하여 WS-Addressing 활성화

    ...
    <service name="WidgetSOAPService">
      <port name="WidgetSOAPPort" binding="tns:WidgetSOAPBinding">
        <soap:address="http://widgetvendor.net/widgetSeller" />
        <wsp:Policy xmlns:wsp="http://www.w3.org/2006/07/ws-policy"> <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata"> <wsp:Policy/> </wsam:Addressing> </wsp:Policy>
      </port>
    </service>
    ...
    Copy to Clipboard Toggle word wrap
참고

WS-Addressing 정책은 wswa:UsingAddressing WSDL 요소를 대체합니다.

12.6.4. 소비자 구성

http-conf:conduit 요소의 DecoupledEndpoint 특성을 사용하여 분리된 엔드포인트를 사용하도록 소비자 끝점을 구성합니다.

예 12.21. “Decoupled HTTP Endpoint를 사용하도록 소비자 구성” 분리된 끝점을 사용하도록 예 12.19. “WSDL을 사용하여 WS-Addressing 활성화” 에 정의된 끝점을 설정하는 구성을 표시합니다. 이제 소비자는 http://widgetvendor.net/widgetSellerInbox 에서 모든 응답을 수신합니다.

예 12.21. Decoupled HTTP Endpoint를 사용하도록 소비자 구성

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

  <http:conduit name="{http://widgetvendor.net/services}WidgetSOAPPort.http-conduit">
    <http:client DecoupledEndpoint="http://widgetvendor.net:9999/decoupled_endpoint" />
  </http:conduit>
</beans>
Copy to Clipboard Toggle word wrap

12.6.5. 메시지가 처리되는 방법

HTTP 전송을 분리된 모드에서 사용하면 HTTP 메시지 처리에 복잡한 추가 계층을 추가합니다. 애플리케이션의 구현 수준 코드에 더 추가된 복잡성은 투명하지만 디버깅 이유로 발생하는 상황을 이해하는 것이 중요할 수 있습니다.

그림 12.1. “분리된 HTTP 전송을 위한 메시지 흐름” 분리된 모드에서 HTTP를 사용할 때 메시지 흐름을 표시합니다.

그림 12.1. 분리된 HTTP 전송을 위한 메시지 흐름

분리된 메시지 교환에는 15단계가 있습니다.

요청은 다음 프로세스를 시작합니다.

  1. 소비자 구현은 작업을 호출하고 요청 메시지가 생성됩니다.
  2. WS-Addressing 계층은 WS-A 헤더를 메시지에 추가합니다.

    분리된 엔드포인트가 소비자 구성에 지정되면 분리된 엔드포인트의 주소가 WS-A ReplyTo 헤더에 배치됩니다.

  3. 메시지가 서비스 공급자에게 전송됩니다.
  4. 서비스 공급자가 메시지를 수신합니다.
  5. 소비자의 요청 메시지는 공급자의 WS-A 계층에 전달됩니다.
  6. WS-A ReplyTo 헤더가 익명으로 설정되지 않았기 때문에 공급자는 HTTP 상태 코드가 202로 설정된 메시지를 다시 보냅니다. 요청이 수신되었음을 확인합니다.
  7. HTTP 계층은 원래 연결의 백 채널을 사용하여 202 Accepted 메시지를 소비자에게 다시 보냅니다.
  8. 소비자는 원래 메시지를 보내는 데 사용된 HTTP 연결의 백채널에서 202 Accepted 응답을 수신합니다.

    소비자가 202 Accepted 응답을 수신하면 HTTP 연결이 종료됩니다.

  9. 요청이 처리된 서비스 공급자의 구현에 전달됩니다.
  10. 응답이 준비되면 WS-A 계층으로 전달됩니다.
  11. WS-A 계층은 WS-Addressing 헤더를 응답 메시지에 추가합니다.
  12. HTTP 전송은 소비자의 분리된 엔드포인트에 응답을 보냅니다.
  13. 소비자의 분리된 엔드포인트는 서비스 공급자로부터 응답을 수신합니다.
  14. 응답은 WS-A RelatesTo 헤더를 사용하여 적절한 요청과 상관 관계가 있는 소비자의 WS-A WS-A 계층에 전달됩니다.
  15. 상관된 응답은 클라이언트 구현으로 반환되고 호출 호출은 차단되지 않습니다.

13장. JMS Over JMS 사용

초록

Apache CXF는 W3C 표준 Cryostat/JMS 전송을 구현합니다. 이 표준은 Cryostat/HTTP 서비스에 대한 보다 강력한 대안을 제공하기 위한 것입니다. 이 전송을 사용하는 Apache CXF 애플리케이션은 Cryostat/JMS 표준을 구현하는 애플리케이션과 상호 운용할 수 있어야 합니다. 전송은 끝점의 WSDL에서 직접 구성됩니다.

참고: JMS 1.0.2 API에 대한 지원이 CXF 3.0에서 제거되었습니다. RedHat JBoss Fuse 6.2 이상을 사용하는 경우(CXF 3.0 포함) JMS 공급자는 JMS 1.1 API를 지원해야 합니다.

13.1. 기본 설정

13.1.1. 개요

JMS 프로토콜을 통한 Cryostat는 대부분의 서비스에서 사용하는 사용자 지정 Cryostat/HTTP 프로토콜에 보다 안정적인 전송 계층을 제공하는 방법으로 W3C(W3C)에서 정의합니다. Apache CXF 구현은 사양을 완전히 준수하며 준수하는 모든 프레임워크와 호환되어야 합니다.

이 전송에서는 JNDI를 사용하여 JMS 대상을 찾습니다. 작업이 호출되면 요청은 Cryostat 메시지로 패키지되고 JMS 메시지의 본문에 지정된 대상으로 전송됩니다.

Cryostat/JMS 전송을 사용하려면 다음을 수행합니다.

  1. 전송 유형이 Cryostat/JMS인지 지정합니다.
  2. JMS URI를 사용하여 대상 대상을 지정합니다.
  3. 선택적으로 JNDI 연결을 구성합니다.
  4. 선택적으로 추가 JMS 구성을 추가합니다.

13.1.2. JMS 전송 유형 지정

WSDL 바인딩을 지정할 때 JMS 전송을 사용하도록 Cryostat 바인딩을 구성합니다. soap:binding 요소의 transport 속성을 http://www.w3.org/2010/soapjms/ 로 설정합니다. 예 13.1. “JMS 바인딩 사양을 통한 Cryostat” Cryostat/JMS를 사용하는 WSDL 바인딩을 표시합니다.

예 13.1. JMS 바인딩 사양을 통한 Cryostat

<wsdl:binding ... >
  <soap:binding style="document"
                transport="http://www.w3.org/2010/soapjms/" />
  ...
</wsdl:binding>
Copy to Clipboard Toggle word wrap

13.1.3. 대상 대상 지정

끝점에 대한 WSDL 포트를 지정할 때 JMS 대상 대상의 주소를 지정합니다. Cryostat/JMS 엔드포인트의 주소 사양은 Cryostat/HTTP 끝점과 동일한 soap:address 요소 및 속성을 사용합니다. 차이점은 주소 사양입니다. JMS 끝점은 JMS 1.0의 URI 스키마에 정의된 대로 JMS URI를 사용합니다. 예 13.2. “JMS URI 구문” JMS URI의 구문을 표시합니다.

예 13.2. JMS URI 구문

jms:variant:destination?options
Copy to Clipboard Toggle word wrap

표 13.1. “JMS URI 변형” JMS URI에 사용 가능한 변형을 설명합니다.

Expand
표 13.1. JMS URI 변형
변형설명

jndi

대상 이름이 JNDI 큐 이름임을 지정합니다. 이 변형을 사용하는 경우 JNDI 공급자에 액세스하기 위한 구성을 제공해야 합니다.

JNDI-topic

대상 이름이 JNDI 주제 이름임을 지정합니다. 이 변형을 사용하는 경우 JNDI 공급자에 액세스하기 위한 구성을 제공해야 합니다.

대기열

대상이 JMS를 사용하여 확인된 큐 이름임을 지정합니다. 제공된 문자열은 Session.createQueue() 로 전달되어 대상의 표현을 만듭니다.

주제

대상이 JMS를 사용하여 확인된 주제 이름임을 지정합니다. 제공된 문자열은 Session.createTopic() 로 전달되어 대상의 표현을 만듭니다.

JMS URI의 옵션 부분은 전송을 구성하는 데 사용되며 13.2절. “JMS URI” 에서 설명합니다.

예 13.3. “Cryostat/JMS 엔드 포인트 주소” JNDI를 사용하여 대상 대상이 조회되는 Cryostat/JMS 끝점에 대한 WSDL 포트 항목을 표시합니다.

예 13.3. Cryostat/JMS 엔드 포인트 주소

<wsdl:port ... >
  ...
  <soap:address location="jms:jndi:dynamicQueues/test.cxf.jmstransport.queue" />
</wsdl:port>
Copy to Clipboard Toggle word wrap

13.1.4. JNDI 및 JMS 전송 구성

Cryostat/JMS는 JNDI 연결 및 JMS 전송을 구성하는 여러 가지 방법을 제공합니다.

13.2. JMS URI

13.2.1. 개요

Cryostat/JMS를 사용하는 경우 JMS URI가 끝점의 대상 대상을 지정하는 데 사용됩니다. JMS URI는 URI에 하나 이상의 옵션을 추가하여 JMS 연결을 구성하는 데도 사용할 수 있습니다. 이러한 옵션은 IETF 표준, Java Message Service 1.0의 URI 스키마에 자세히 설명되어 있습니다. JNDI 시스템, 응답 대상, 사용할 전달 모드 및 기타 JMS 속성을 구성하는 데 사용할 수 있습니다.

13.2.2. 구문

예 13.4. “JMS URI 옵션 구문” 에 표시된 대로 물음표(?)를 사용하여 대상 주소와 분리하여 JMS URI 끝에 하나 이상의 옵션을 추가할 수 있습니다. 여러 옵션은 앰퍼샌드(&amp; )로 구분됩니다. 예 13.4. “JMS URI 옵션 구문” 은 JMS URI에서 여러 옵션을 사용하는 구문을 보여줍니다.

예 13.4. JMS URI 옵션 구문

jms:variant:jmsAddress?option1=value1&option2=value2&_optionN_=valueN
Copy to Clipboard Toggle word wrap

13.2.3. JMS 속성

표 13.2. “URI 옵션으로 JMS 속성 설정 가능” 은 JMS 전송 계층에 영향을 주는 URI 옵션을 표시합니다.

Expand
표 13.2. URI 옵션으로 JMS 속성 설정 가능
속성Default설명

conduitIdSelectorPrefix

 

[선택 사항] conduit에서 생성하는 모든 상관 ID에 접두어가 붙은 문자열 값입니다. 선택기는 응답을 수신 대기하는 데 사용할 수 있습니다.

deliveryMode

PERSISTENT

JMS PERSISTENT 또는 NON_PERSISTENT 메시지 의미 체계 사용 여부를 지정합니다. PERSISTENT 전달 모드의 경우 JMS 브로커는 메시지를 승인하기 전에 영구 스토리지에 저장합니다. 반면 NON_PERSISTENT 메시지는 메모리에만 유지됩니다.

durableSubscriptionClientID

 

[optional] 연결에 대한 클라이언트 ID를 지정합니다. 이 속성은 공급자를 대신하여 유지 관리하는 상태와 연결을 연결하는 데 사용됩니다. 이를 통해 동일한 ID를 가진 후속 구독자는 이전 구독자가 서브스크립션을 종료한 상태에서 서브스크립션을 재개할 수 있습니다.

durableSubscriptionName

 

[선택 사항] 서브스크립션의 이름을 지정합니다.

messageType

byte

CXF에서 사용하는 JMS 메시지 유형을 지정합니다. 유효한 값은 다음과 같습니다.

  • byte
  • text
  • 바이너리

암호

 

[optional] 연결을 생성하기 위한 암호를 지정합니다. 이 속성을 URI에 추가하는 것은 권장되지 않습니다.

priority

4

0(가장 낮음)에서 9(가장 높음)까지의 JMS 메시지 우선 순위를 지정합니다.

receiveTimout

60000

요청/응답 교환이 사용될 때 클라이언트가 응답을 대기할 시간을 지정합니다.

reconnectOnException

true

[CXF 3.0에서 더 이상 사용되지 않음] 예외가 발생할 때 전송이 다시 연결해야 하는지 여부를 지정합니다.

3.0부터 예외가 발생할 때 전송이 항상 다시 연결됩니다.

replyToName

 

[optional] 큐 메시지의 응답 대상을 지정합니다. reply 대상은 JMSReplyTo 헤더에 표시됩니다. 이 속성을 설정하면 JMS 공급자가 지정되지 않은 경우 임시 응답 큐를 할당하므로 요청별 의미 체계가 있는 애플리케이션에 권장됩니다.

이 속성의 값은 JMS URI에 지정된 변형에 따라 해석됩니다.

  • JNDI 변형 - JNDI로 확인되는 대상 큐의 이름입니다.
  • 변형 - JMS를 사용하여 확인된 대상 큐의 이름입니다.

sessionTransacted

false

트랜잭션 유형을 지정합니다. 유효한 값은 다음과 같습니다.

  • true-리소스 로컬 트랜잭션
  • False-JTA 트랜잭션

timeToLive

0

JMS 공급자가 메시지를 삭제하는 시간(밀리초)을 지정합니다. 값이 0이면 무한 수명입니다.A value of 0 indicates an infinite lifetime.

topicReplyToName

 

[선택 사항] 주제 메시지에 대한 응답 대상을 지정합니다. 이 속성의 값은 JMS URI에 지정된 변형에 따라 해석됩니다.

  • JNDI-topic- JNDI로 확인되는 대상 주제의 이름입니다.
  • topic- JMS에서 해결한 대상 주제의 이름입니다.

useConduitIdSelector

true

conduit의 UUID가 모든 상관관계 ID의 접두사로 사용되는지 여부를 지정합니다.

모든 Conduits에는 고유한 UUID가 할당되므로 이 속성을 true 로 설정하면 여러 끝점이 JMS 큐 또는 주제를 공유할 수 있습니다.

사용자 이름

 

[optional] 연결을 만드는 데 사용할 사용자 이름을 지정합니다.

13.2.4. JNDI 속성

표 13.3. “URI 옵션으로 JNDI 속성 설정 가능” 에는 이 엔드포인트에 대한 JNDI를 구성하는 데 사용할 수 있는 URI 옵션이 표시됩니다.

Expand
표 13.3. URI 옵션으로 JNDI 속성 설정 가능
속성설명

jndiConnectionFactoryName

JMS 연결 팩토리의 JNDI 이름을 지정합니다.

jndiInitialContextFactory

JNDI 공급자의 정규화된 Java 클래스 이름을 지정합니다(Java x.jms.InitialContextFactory 유형). java.naming.factory.initial Java 시스템 속성을 설정하는 것과 동일합니다.

jndiTransactionManagerName

Spring, 블루프린트 또는 JNDI에서 검색할 JTA 트랜잭션 관리자의 이름을 지정합니다. 트랜잭션 관리자가 발견되면 JTA 트랜잭션이 활성화됩니다. session#159ed JMS 속성을 참조하십시오.

jndiURL

JNDI 공급자를 초기화하는 URL을 지정합니다. java.naming.provider.url Java 시스템 속성을 설정하는 것과 동일합니다.

13.2.5. 추가 JNDI 속성

속성인 java.naming.factory.initialjava.naming.provider.url 은 JNDI 공급자를 초기화하는 데 필요한 표준 속성입니다. 그러나 경우에 따라 JNDI 공급자가 표준 속성 외에도 사용자 지정 속성을 지원할 수 있습니다. 이 경우 jndi-PropertyName 형식의 URI 옵션을 설정하여 임의의 JNDI 속성을 설정할 수 있습니다.

예를 들어, SUN's LDAP implementation of JNDI를 사용하는 경우 예 13.5. “JMS URI에서 JNDI 속성 설정” 에 표시된 대로 JMS URI에서 JNDI 속성인 java.naming.factory.control 을 설정할 수 있습니다.

예 13.5. JMS URI에서 JNDI 속성 설정

jms:queue:FOO.BAR?jndi-java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory
Copy to Clipboard Toggle word wrap

13.2.6. 예제

JMS 공급자가 아직 구성되지 않은 경우 옵션을 사용하여 URI에 필요한 JNDI 구성 세부 정보를 제공할 수 있습니다( 표 13.3. “URI 옵션으로 JNDI 속성 설정 가능”참조). 예를 들어 Apache ActiveMQ JMS 공급자를 사용하도록 끝점을 구성하고 test.cxf.jmstransport.queue 라는 큐에 연결하려면 예 13.6. “JNDI 연결을 구성하는 JMS URI” 에 표시된 URI를 사용합니다.

예 13.6. JNDI 연결을 구성하는 JMS URI

jms:jndi:dynamicQueues/test.cxf.jmstransport.queue
?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory
&jndiConnectionFactoryName=ConnectionFactory
&jndiURL=tcp://localhost:61616
Copy to Clipboard Toggle word wrap

13.2.7. 서비스 게시

Cryostat-WS 표준 publish() 메서드는 Cryostat/JMS 서비스를 게시하는 데 사용할 수 없습니다. 대신 예 13.7. “Cryostat/JMS 서비스 게시” 에 표시된 대로 Apache CXF의 JaxWsServerFactoryBean 클래스를 사용해야 합니다.

예 13.7. Cryostat/JMS 서비스 게시

String address = "jms:jndi:dynamicQueues/test.cxf.jmstransport.queue3"
    + "?jndiInitialContextFactory"
    + "=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
    + "&jndiConnectionFactoryName=ConnectionFactory"
    + "&jndiURL=tcp://localhost:61500";
Hello implementor = new HelloImpl();
JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(Hello.class);
svrFactory.setAddress(address);
svrFactory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICIATION_TRANSPORTID);
svrFactory.setServiceBean(implementor);
svrFactory.create();
Copy to Clipboard Toggle word wrap

예 13.7. “Cryostat/JMS 서비스 게시” 의 코드는 다음을 수행합니다.

엔드포인트의 주소를 나타내는 JMS URI를 생성합니다.

JaxWsServerFactoryBean 을 인스턴스화하여 서비스를 게시합니다.

서비스의 JMS URI를 사용하여 팩토리 빈의 주소 필드를 설정합니다.

팩토리에서 생성한 서비스가 Cryostat/JMS 전송을 사용하도록 지정합니다.

13.2.8. 서비스 사용

표준 Cryostat-WS API는 Cryostat/JMS 서비스를 사용하는 데 사용할 수 없습니다. 대신 예 13.8. “Cryostat/JMS 서비스 사용” 에 표시된 대로 Apache CXF의 JaxWsProxyFactoryBean 클래스를 사용해야 합니다.

예 13.8. Cryostat/JMS 서비스 사용

// Java
public void invoke() throws Exception {
    String address = "jms:jndi:dynamicQueues/test.cxf.jmstransport.queue3"
        + "?jndiInitialContextFactory"
        + "=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
        + "&jndiConnectionFactoryName=ConnectionFactory&jndiURL=tcp://localhost:61500";
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setAddress(address);
    factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICIATION_TRANSPORTID);
    factory.setServiceClass(Hello.class);
    Hello client = (Hello)factory.create();
    String reply = client.sayHi(" HI");
    System.out.println(reply);
}
Copy to Clipboard Toggle word wrap

예 13.8. “Cryostat/JMS 서비스 사용” 의 코드는 다음을 수행합니다.

엔드포인트의 주소를 나타내는 JMS URI를 생성합니다.

JaxWsProxyFactoryBean 을 인스턴스화하여 프록시를 생성합니다.

서비스의 JMS URI를 사용하여 팩토리 빈의 주소 필드를 설정합니다.

팩토리에서 생성한 프록시가 Cryostat/JMS 전송을 사용하도록 지정합니다.

13.3. WSDL 확장

13.3.1. 개요

WSDL 확장 요소를 바인딩 범위, 서비스 범위 또는 포트 범위에서 계약에 삽입하여 JMS 전송의 기본 구성을 지정할 수 있습니다. WSDL 확장을 사용하면 JNDI InitialContext 를 부트 스트랩하기 위한 속성을 지정할 수 있으며, 이를 사용하여 JMS 대상을 조회할 수 있습니다. JMS 전송 계층의 동작에 영향을 주는 일부 속성을 설정할 수도 있습니다.

13.3.2. Cryostat/JMS 네임스페이스

Cryostat/JMS WSDL 확장은 http://www.w3.org/2010/soapjms/ 네임스페이스에 정의됩니다. WSDL 계약에서 사용하려면 wsdl:definitions 요소에 다음 설정을 추가합니다.

<wsdl:definitions ...
    xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  ... >
Copy to Clipboard Toggle word wrap

13.3.3. WSDL 확장 요소

표 13.4. “Cryostat/JMS WSDL 확장 요소” JMS 전송을 구성하는 데 사용할 수 있는 모든 WSDL 확장 요소를 표시합니다.

Expand
표 13.4. Cryostat/JMS WSDL 확장 요소
elementDefault설명

soapjms:jndiInitialContextFactory

 

JNDI 공급자의 정규화된 Java 클래스 이름을 지정합니다. java.naming.factory.initial Java 시스템 속성을 설정하는 것과 동일합니다.

soapjms:jndiURL

 

JNDI 공급자를 초기화하는 URL을 지정합니다. java.naming.provider.url Java 시스템 속성을 설정하는 것과 동일합니다.

soapjms:jndiContextParameter

 

JNDI InitialContext 를 생성하기 위한 추가 속성을 지정합니다. namevalue 속성을 사용하여 속성을 지정합니다.

soapjms:jndiConnectionFactoryName

 

JMS 연결 팩토리의 JNDI 이름을 지정합니다.

soapjms:deliveryMode

PERSISTENT

JMS PERSISTENT 또는 NON_PERSISTENT 메시지 의미 체계 사용 여부를 지정합니다. PERSISTENT 전달 모드의 경우 JMS 브로커는 메시지를 승인하기 전에 영구 스토리지에 저장합니다. 반면 NON_PERSISTENT 메시지는 메모리에만 유지됩니다.

soapjms:replyToName

 

[optional] 큐 메시지의 응답 대상을 지정합니다. reply 대상은 JMSReplyTo 헤더에 표시됩니다. 이 속성을 설정하면 JMS 공급자가 지정되지 않은 경우 임시 응답 큐를 할당하므로 요청별 의미 체계가 있는 애플리케이션에 권장됩니다.

이 속성의 값은 JMS URI에 지정된 변형에 따라 해석됩니다.

  • JNDI 변형 - JNDI로 확인되는 대상 큐의 이름입니다.
  • 변형 - JMS를 사용하여 확인된 대상 큐의 이름입니다.

soapjms:priority

4

0(가장 낮음)에서 9(가장 높음)까지의 JMS 메시지 우선 순위를 지정합니다.

soapjms:timeToLive

0

JMS 공급자가 메시지를 삭제할 시간(밀리초)입니다. 값 0은 무한 수명입니다.A value of 0 represents an infinite lifetime.

13.3.4. 구성 범위

WSDL 계약에 배치된 WSDL 요소는 구성 범위가 계약에 정의된 끝점에 변경되는 영향을 미칩니다. Cryostat/JMS WSDL 요소는 wsdl:binding 요소, wsdl:service 요소 또는 wsdl:port 요소의 하위 요소로 배치할 수 있습니다. Cryostat/JMS 요소의 상위는 다음 범위 중 구성에 배치되는 범위를 결정합니다.

바인딩 범위
wsdl: binding 요소 내에 확장 요소를 배치하여 바인딩 범위에서 JMS 전송을 구성할 수 있습니다. 이 범위의 요소는 이 바인딩을 사용하는 모든 끝점에 대한 기본 구성을 정의합니다. 바인딩 범위의 모든 설정은 서비스 범위 또는 포트 범위에서 재정의할 수 있습니다.
서비스 범위
wsdl: service 요소 내에 확장 요소를 배치하여 서비스 범위에서 JMS 전송을 구성할 수 있습니다. 이 범위의 요소는 이 서비스의 모든 끝점에 대한 기본 구성을 정의합니다. 서비스 범위의 모든 설정은 포트 범위에서 재정의할 수 있습니다.
포트 범위
wsdl: port 요소 내에 확장 요소를 배치하여 포트 범위에서 JMS 전송을 구성할 수 있습니다. 포트 범위의 요소는 이 포트에 대한 구성을 정의합니다. 서비스 범위 또는 바인딩 범위에서 정의된 동일한 확장 요소의 기본값을 재정의합니다.

13.3.5. 예제

예 13.9. “Cryostat/JMS 구성과의 WSDL 계약” 에는 Cryostat/JMS 서비스에 대한 WSDL 계약이 표시됩니다. 바인딩 범위, 서비스 범위에서 메시지 전달 세부 정보, 포트 범위에서 응답 대상을 구성합니다.

예 13.9. Cryostat/JMS 구성과의 WSDL 계약

<wsdl:definitions ...
    xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  ... >
  ...
  <wsdl:binding name="JMSGreeterPortBinding" type="tns:JMSGreeterPortType">
    ...
    <soapjms:jndiInitialContextFactory>
      org.apache.activemq.jndi.ActiveMQInitialContextFactory
    </soapjms:jndiInitialContextFactory>
    <soapjms:jndiURL>tcp://localhost:61616</soapjms:jndiURL>
    <soapjms:jndiConnectionFactoryName>
      ConnectionFactory
    </soapjms:jndiConnectionFactoryName>
    ...
  </wsdl:binding>
  ...
  <wsdl:service name="JMSGreeterService">
    ...
    <soapjms:deliveryMode>NON_PERSISTENT</soapjms:deliveryMode>
    <soapjms:timeToLive>60000</soapjms:timeToLive>
    ...
    <wsdl:port binding="tns:JMSGreeterPortBinding" name="GreeterPort">
      <soap:address location="jms:jndi:dynamicQueues/test.cxf.jmstransport.queue" />
      <soapjms:replyToName>
        dynamicQueues/greeterReply.queue
      </soapjms:replyToName>
      ...
    </wsdl:port>
    ...
  </wsdl:service>
  ...
</wsdl:definitions>
Copy to Clipboard Toggle word wrap

예 13.9. “Cryostat/JMS 구성과의 WSDL 계약” 의 WSDL은 다음을 수행합니다.

Cryostat/JMS 확장에 대한 네임스페이스를 선언합니다.

바인딩 범위에서 JNDI 연결을 구성합니다.

JMS 전달 스타일을 비영구적으로 설정하고 각 메시지는 1분 동안 활성화되도록 설정합니다.

대상 대상을 지정합니다.

응답 메시지가 >&# erReply.queue 큐에 전달되도록 JMS 전송을 구성합니다.

14장. Generic JMS 사용

초록

Apache CXF는 JMS 전송의 일반적인 구현을 제공합니다. 일반 JMS 전송은 Cryostat 메시지를 사용하도록 제한되지 않으며 JMS를 사용하는 모든 애플리케이션에 연결할 수 있습니다.

참고: JMS 1.0.2 API에 대한 지원이 CXF 3.0에서 제거되었습니다. RedHat JBoss Fuse 6.2 이상을 사용하는 경우(CXF 3.0 포함) JMS 공급자는 JMS 1.1 API를 지원해야 합니다.

14.1. JMS 구성 방법

Apache CXF 일반 JMS 전송은 모든 JMS 공급자에 연결하고 JMS 메시지를 textMessage 또는 CryostatMessage 의 본문과 교환하는 애플리케이션에 사용할 수 있습니다.

JMS 전송을 활성화하고 구성하는 방법은 다음 두 가지가 있습니다.

14.2. JMS 구성 8080 사용

14.2.1. 개요

JMS 구성을 단순화하고 보다 강력하게 만들기 위해 Apache CXF는 단일 JMS 구성 빈을 사용하여 JMS 엔드포인트를 구성합니다. Cryostat는 org.apache.cxf.transport.jms.JMSConfiguration 클래스에 의해 구현됩니다. 끝점을 직접 구성하거나 JMS conduits 및 대상을 구성하는 데 사용할 수 있습니다.

14.2.2. 구성 네임스페이스

JMS 구성 빈은 Spring p-namespace 를 사용하여 구성을 최대한 간단하게 만듭니다. 이 네임스페이스를 사용하려면 예 14.1. “Spring p-namespace 선언” 와 같이 구성의 root 요소에서 선언해야 합니다.

예 14.1. Spring p-namespace 선언

<beans ...
  xmlns:p="http://www.springframework.org/schema/p"
  ... >
  ...
</beans>
Copy to Clipboard Toggle word wrap

14.2.3. 구성 지정

org.apache.cxf.transport.jms.JMSConfiguration 클래스의 8080을 정의하여 JMS 구성을 지정합니다. 8080의 속성은 전송에 대한 구성 설정을 제공합니다.

중요

CXF 3.0에서는 JMS 전송에 더 이상 Spring JMS에 종속되지 않으므로 일부 Spring JMS 관련 옵션이 제거되었습니다.

표 14.1. “일반 JMS 구성 속성” 공급자와 소비자 모두에 공통된 속성을 나열합니다.

Expand
표 14.1. 일반 JMS 구성 속성
속성Default설명

connectionFactory

 

[required] JMS ConnectionFactory를 정의하는 Cryostat에 대한 참조를 지정합니다.

wrapInSingleConnectionFactory

true [pre v3.0]

CXF 3.0에서 삭제

CXF 3.0 이전 버전에서는 Spring SingleConnectionFactory 를 사용하여 ConnectionFactory를 래핑할지 여부를 지정합니다.

JMS 전송의 성능이 향상되므로 연결을 풀지 않는 ConnectionFactory를 사용할 때 이 속성을 활성화합니다. 이는 JMS 전송에서 각 메시지에 대한 새 연결을 생성하고 SingleConnectionFactory 가 연결을 캐시하는 데 필요하므로 재사용할 수 있기 때문입니다.

reconnectOnException

false

CXF 3.0 CXF에서는 예외가 발생할 때 항상 다시 연결됩니다.

CXF 3.0 이전 예외가 발생할 때 새 연결을 만들지 여부를 지정합니다.

Spring SingleConnectionFactory 를 사용하여 ConnectionFactory를 래핑하는 경우:

  • true Cryostat-단어 예외, 새 연결을 생성

    PooledConnectionFactory를 사용할 때는 이 옵션을 활성화하지 마십시오. 이 옵션은 풀링된 연결만 반환하지만 다시 연결하지 않습니다.

  • false 인터페이스와- exception을 다시 연결하려고 하지 마십시오.

targetDestination

 

대상의 JNDI 이름 또는 공급자별 이름을 지정합니다.

replyDestination

 

응답이 전송되는 JMS 대상의 JMS 이름을 지정합니다. 이 속성을 사용하면 응답에 사용자 정의 대상을 사용할 수 있습니다. 자세한 내용은 14.6절. “이름이 지정된 대상 사용” 에서 참조하십시오.

destinationResolver

DynamicDestinationResolver

Spring DestinationResolver 에 대한 참조를 지정합니다.

이 속성을 사용하면 대상 이름이 JMS 대상으로 해석되는 방법을 정의할 수 있습니다. 유효한 값은 다음과 같습니다.

  • JMS 공급자의 기능을 사용하여 DynamicDestinationResolver Cryostat- Cryostatresolve 대상 이름입니다.
  • JNDI를 사용하여 JndiDestinationResolver Cryostat- Cryostatresolve 대상 이름

transactionManager

 

Spring 트랜잭션 관리자에 대한 참조를 지정합니다. 이를 통해 서비스는 JTA 트랜잭션에 참여할 수 있습니다.

taskExecutor

SimpleAsyncTaskExecutor

CXF 3.0에서 삭제

CXF 3.0 이전 TaskExecutor에 대한 참조를 지정합니다. 리스너에서 수신되는 메시지를 처리하는 방법을 결정하는 데 사용됩니다.

useJms11

false

CXF 3.0에서 제거된 CXF 3.0은 JMS 1.1 기능만 지원합니다.

CXF 3.0 이전 에서는 JMS 1.1 기능이 사용되는지 여부를 지정합니다. 유효한 값은 다음과 같습니다.

  • True Cryo stat->-<JMS 1.1 기능
  • false Cryostat- CryostatJMS 1.0.2 기능

messageIdEnabled

true

CXF 3.0에서 삭제

CXF 3.0 이전 에서는 JMS 전송에서 JMS 브로커가 메시지 ID를 제공할지 여부를 지정합니다. 유효한 값은 다음과 같습니다.

  • true Cryostat- Cryostatbroker는 메시지 ID를 제공해야 합니다.
  • false Cryostat- Cryostatbroker는 메시지 ID를 제공할 필요가 없습니다.

    이 경우 엔드포인트는 true 값이 있는 메시지 생산자의 setDisableMessageID() 메서드를 호출합니다. 그러면 브로커에 메시지 ID를 생성하거나 엔드포인트의 메시지에 추가할 필요가 없다는 힌트가 제공됩니다. 브로커는 힌트를 수락하거나 무시합니다.

messageTimestampEnabled

true

CXF 3.0에서 삭제

CXF 3.0 이전 에서는 JMS 전송에서 JMS 브로커가 메시지 타임스탬프를 제공할지 여부를 지정합니다. 유효한 값은 다음과 같습니다.

  • true Cryostat- Cryostatbroker는 메시지 타임스탬프를 제공해야 합니다.
  • false Cryostat- Cryostatbroker는 메시지 타임스탬프를 제공할 필요가 없습니다.

    이 경우 엔드포인트는 message producer의 setDisableMessageTimestamp() 메서드를 true 값으로 호출합니다. 그러면 브로커에 타임스탬프를 생성하거나 엔드포인트의 메시지에 추가할 필요가 없다는 힌트가 제공됩니다. 브로커는 힌트를 수락하거나 무시합니다.

cacheLevel

-1 (feature disabled)

CXF 3.0에서 삭제

CXF 3.0 이전 에서는 JMS 리스너 컨테이너가 적용할 수 있는 캐싱 수준을 지정합니다. 유효한 값은 다음과 같습니다.

  • 0 — CACHE_NONE
  • 1 — CACHE_CONNECTION
  • 2 — CACHE_SESSION
  • 3 — CACHE_CONSUMER
  • 4 — CACHE_AUTO

자세한 내용은 DefaultMessageListenerContainer를 참조하십시오.

pubSubNoLocal

false

주제를 사용할 때 자신의 메시지를 받을지 여부를 지정합니다.

  • true - - 자체 메시지를 수신하지 마십시오.
  • false - 자체 메시지를 수신

receiveTimeout

60000

응답 메시지를 대기하는 시간(밀리초)을 지정합니다.

explicitQosEnabled

false

QoS 설정(예: priority, persistence, live)이 각 메시지에 대해 명시적으로 설정되어 있는지(true) 또는 기본값(false)을 사용하도록 지정합니다.

deliveryMode

2

메시지가 영구적인지 여부를 지정합니다. 유효한 값은 다음과 같습니다.

  • 1 (NON_PERSISTENT)-메시지는 메모리만 유지됩니다.
  • 2 (PERSISTENT)-메시지는 디스크에 유지됩니다.

priority

4

메시지 우선 순위를 지정합니다. JMS 우선순위 값의 범위는 0 (가장 낮음)에서 9 (가장 높음) 사이입니다. 자세한 내용은 JMS 공급자의 설명서를 참조하십시오.

timeToLive

0 (definitely)

전송된 메시지가 삭제되기 전에 시간(밀리초)을 지정합니다.

sessionTransacted

false

JMS 트랜잭션이 사용되는지 여부를 지정합니다.

concurrentConsumers

1

CXF 3.0에서 삭제

CXF 3.0 이전 에서는 리스너에 대한 최소 동시 소비자 수를 지정합니다.

maxConcurrentConsumers

1

CXF 3.0에서 삭제

CXF 3.0 이전 에서는 리스너에 대한 최대 동시 소비자 수를 지정합니다.

messageSelector

 

수신 메시지를 필터링하는 데 사용되는 선택기의 문자열 값을 지정합니다. 이 속성을 사용하면 여러 연결이 큐를 공유할 수 있습니다. 메시지 선택기를 지정하는 데 사용되는 구문에 대한 자세한 내용은 JMS 1.1 사양 을 참조하십시오.

subscriptionDurable

false

서버의 subscriptions를 사용할지 여부를 지정합니다.

durableSubscriptionName

 

Cryostat 서브스크립션을 등록하는 데 사용되는 이름(문자열)을 지정합니다.

messageType

text

메시지 데이터를 JMS 메시지로 패키징하는 방법을 지정합니다. 유효한 값은 다음과 같습니다.

  • data가 text text로 패키지될 것임을 나타냅니다 .
  • 데이터는 바이트 배열( byte [])으로 패키징됨을 나타냅니다.
  • binary Cryostat->-<specifies that the data will be packaged as an CryostatMessage

pubSubDomain

false

대상 대상이 주제인지 또는 큐인지를 지정합니다. 유효한 값은 다음과 같습니다.

  • true Cryostat- Cryostattopic
  • false Cryostat- Cryostatqueue

jmsProviderTibcoEms

false

JMS 공급자가 Tibco Cryostat인지 여부를 지정합니다.

true 로 설정하면 보안 컨텍스트의 주체가 JMS_TIBCO_SENDER 헤더에서 채워집니다.

useMessageIDAsCorrelationID

false

CXF 3.0에서 삭제

JMS에서 메시지 ID를 사용하여 메시지 상관 관계를 설정할지 여부를 지정합니다.

true 로 설정하면 클라이언트는 생성된 상관 관계 ID를 설정합니다.

maxSuspendedContinuations

-1 (feature disabled)

CXF 3.0 JMS 대상에서 보유할 수 있는 일시 중지된 최대 연속 수를 지정합니다. 현재 번호가 지정된 최대값을 초과하면 JMSListenerContainer가 중지됩니다.

reconnectPercentOfMax

70

CXF 3.0maxSuspendedContinuations 를 초과하기 위해 JMSListenerContainer를 다시 시작할 시기를 지정합니다.

현재 일시 중단된 연속 수가 값 (maxSuspendedContinuations * reconnectPercentOfMax/100) 아래에 있으면 리스너 컨테이너가 재시작됩니다.

예 14.2. “JMS 구성 Cryostat” 에 표시된 것처럼, 빈의 속성은 8080 요소에 대한 속성으로 지정됩니다. 모두 Spring p 네임 스페이스에 선언되어 있습니다.

예 14.2. JMS 구성 Cryostat

<bean id="jmsConfig"
      class="org.apache.cxf.transport.jms.JMSConfiguration"
      p:connectionFactory="jmsConnectionFactory"
      p:targetDestination="dynamicQueues/greeter.request.queue"
      p:pubSubDomain="false" />
Copy to Clipboard Toggle word wrap

14.2.4. 끝점에 구성 적용

JMSConfiguration 8080은 Apache CXF 기능 메커니즘을 사용하여 서버 및 클라이언트 끝점 모두에 직접 적용할 수 있습니다. 이렇게 하려면 다음을 수행합니다.

  1. 끝점의 address 속성을 jms:// 로 설정합니다.
  2. 엔드포인트 구성에 jaxws:feature 요소를 추가합니다.
  3. org.apache.cxf.transport.jms.JMSConfigFeature 유형의 Cryostat를 기능에 추가합니다.
  4. 8080 요소의 p:jmsConfig-ref 속성을 JMSConfiguration 8080의 ID로 설정합니다.

예 14.3. “Cryostat-WS 클라이언트에 JMS 구성 추가” 예 14.2. “JMS 구성 Cryostat” 의 JMS 구성을 사용하는 Cryostat-WS 클라이언트를 표시합니다.

예 14.3. Cryostat-WS 클라이언트에 JMS 구성 추가

<jaxws:client id="CustomerService"
              xmlns:customer="http://customerservice.example.com/"
              serviceName="customer:CustomerServiceService"
              endpointName="customer:CustomerServiceEndpoint"
              address="jms://"
              serviceClass="com.example.customerservice.CustomerService">
  <jaxws:features>
    <bean xmlns="http://www.springframework.org/schema/beans"
          class="org.apache.cxf.transport.jms.JMSConfigFeature"
          p:jmsConfig-ref="jmsConfig"/>
  </jaxws:features>
</jaxws:client>
Copy to Clipboard Toggle word wrap

14.2.5. 전송에 구성 적용

JMSConfiguration 8080은 jms:jmsConfig-ref 요소를 사용하여 JMS conduits 및 JMS 대상에 적용할 수 있습니다. jms:jmsConfig-ref 요소의 값은 JMSConfiguration 8080의 ID입니다.

예 14.4. “JMS conduit에 JMS 구성 추가” 예 14.2. “JMS 구성 Cryostat” 의 JMS 구성을 사용하는 JMS 연속을 표시합니다.

예 14.4. JMS conduit에 JMS 구성 추가

<jms:conduit name="{http://cxf.apache.org/jms_conf_test}HelloWorldQueueBinMsgPort.jms-conduit">
  ...
  <jms:jmsConfig-ref>jmsConf</jms:jmsConfig-ref>
</jms:conduit>
Copy to Clipboard Toggle word wrap

14.3. 클라이언트-Side JMS 성능 최적화

14.3.1. 개요

클라이언트의 JMS 성능에 영향을 미치는 두 가지 주요 설정은 풀링 및 동기 수신입니다.

14.3.2. 풀링

클라이언트 측에서 CXF는 각 메시지에 대해 새 JMS 세션 및 JMS 생산자를 생성합니다. 이는 세션이나 프로듀서 오브젝트가 스레드로부터 안전하지 않기 때문입니다. 생산자를 생성하는 것은 서버와 통신해야 하므로 특히 시간이 많이 걸립니다.

연결 팩토리를 풀링하면 연결, 세션 및 생산자를 캐싱하여 성능이 향상됩니다.

ActiveMQ의 경우 풀링 구성은 간단합니다. 예를 들면 다음과 같습니다.

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;

ConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
PooledConnectionFactory pcf = new PooledConnectionFactory();

//Set expiry timeout because the default (0) prevents reconnection on failure
pcf.setExpiryTimeout(5000);
pcf.setConnectionFactory(cf);

JMSConfiguration jmsConfig = new JMSConfiguration();

jmsConfig.setConnectionFactory(pdf);
Copy to Clipboard Toggle word wrap

풀링에 대한 자세한 내용은 Red Hat JBoss Fuse 트랜잭션 가이드의 "Appendix A Optimizing Performance of JMS Single- and Multiple-Resource Transactions"를 참조하십시오.

14.3.3. 동기 수신 방지

요청/거동의 경우 JMS 전송은 요청을 보낸 다음 응답을 기다립니다. 가능한 경우 JMS MessageListener 를 사용하여 요청/응답 메시징이 비동기적으로 구현됩니다.

그러나 CXF는 끝점 간에 큐를 공유해야 하는 경우 동기 consumers .receive() 메서드를 사용해야 합니다. 이 시나리오에서는 MessageListener 가 메시지 선택기를 사용하여 메시지를 필터링해야 합니다. 메시지 선택기를 미리 알아야 하므로 MessageListener 는 한 번만 열립니다.

메시지 선택기를 미리 알 수 없는 두 가지 경우를 피해야 합니다.

  • JMSMessageIDJMSCorrelationID로 사용하는 경우

    JMS 속성 useConduitIdSelectorconduitSelectorPrefix 가 JMS 전송에 설정되지 않은 경우 클라이언트는 JMSCorrelationId 를 설정하지 않습니다. 이로 인해 서버가 요청 메시지의 JMSMessageIdJMSCorrelationId 로 사용합니다. JMSMessageID 를 미리 알 수 없으므로 클라이언트는 동기 Consumer.receive() 메서드를 사용해야 합니다.

    IBM JMS 끝점(기본값)과 함께 Consumer.receive() 메서드를 사용해야 합니다.

  • 사용자는 요청 메시지에서 JMStype 을 설정한 다음 사용자 지정 JMSCorrelationID 를 설정합니다.

    사용자 지정 JMSCorrelationID 를 미리 알 수 없으므로 클라이언트는 동기식 Consumer.receive() 메서드를 사용해야 합니다.

따라서 일반적인 규칙은 동기 수신을 사용해야 하는 설정을 사용하지 않는 것입니다.

14.4. JMS 트랜잭션 구성

14.4.1. 개요

CXF 3.0은 단방향 메시징을 사용할 때 CXF 끝점에서 로컬 JMS 트랜잭션 및 JTA 트랜잭션을 모두 지원합니다.

14.4.2. 로컬 트랜잭션

로컬 리소스를 사용하는 트랜잭션은 예외가 발생하는 경우에만 JMS 메시지를 롤백합니다. 데이터베이스 트랜잭션과 같은 다른 리소스를 직접 조정하지 않습니다.

로컬 트랜잭션을 설정하려면 일반적으로 끝점을 구성하고 sessionTrasnsacted 속성을 true 로 설정합니다.

참고

트랜잭션 및 풀링에 대한 자세한 내용은 Red Hat JBoss Fuse 트랜잭션 가이드를 참조하십시오.

14.4.3. JTA 트랜잭션

JTA 트랜잭션을 사용하면 원하는 수의 XA 리소스를 조정할 수 있습니다. CXF 엔드포인트가 JTA 트랜잭션에 대해 구성된 경우 서비스 구현을 호출하기 전에 트랜잭션을 시작합니다. 예외가 발생하지 않으면 트랜잭션이 커밋됩니다. 그렇지 않으면 롤백됩니다.

JTA 트랜잭션에서는 JMS 메시지를 사용하고 데이터베이스에 기록된 데이터를 사용합니다. 예외가 발생하면 두 리소스가 모두 롤백되므로 메시지가 사용되고 데이터가 데이터베이스에 기록되거나 메시지가 롤백되고 데이터가 데이터베이스에 기록되지 않습니다.

JTA 트랜잭션을 구성하려면 다음 두 단계가 필요합니다.

  1. 트랜잭션 관리자 정의

    • Cryostat 메서드

      • 트랜잭션 관리자 정의

        <bean id="transactionManager"
           class="org.apache.geronimo.transaction.manager.GeronimoTransactionManager"/>
        Copy to Clipboard Toggle word wrap
      • JMS URI에서 트랜잭션 관리자의 이름 설정

        jms:queue:myqueue?jndiTransactionManager=TransactionManager
        Copy to Clipboard Toggle word wrap

        이 예에서는 ID TransactionManager 가 있는 8080을 찾습니다.

    • OSGi 참조 방법

      • 블루프린트를 사용하여 트랜잭션 관리자를 OSGi 서비스로 검색

        <reference id="TransactionManager" interface="javax.transaction.TransactionManager"/>
        Copy to Clipboard Toggle word wrap
      • JMS URI에서 트랜잭션 관리자의 이름 설정

        jms:jndi:myqueue?jndiTransactionManager=java:comp/env/TransactionManager
        Copy to Clipboard Toggle word wrap

        이 예에서는 JNDI에서 트랜잭션 관리자를 조회합니다.

  2. JCA 풀링된 연결 팩토리 구성

    Spring을 사용하여 JCA 풀링된 연결 팩토리를 정의합니다.

    <bean id="xacf" class="org.apache.activemq.ActiveMQXAConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
    </bean>
    
    <bean id="ConnectionFactory" class="org.apache.activemq.jms.pool.JcaPooledConnectionFactory">
      <property name="transactionManager" ref="transactionManager" />
      <property name="connectionFactory" ref="xacf" />
    </bean>
    Copy to Clipboard Toggle word wrap

    이 예제에서 첫 번째 Cryostat는 JcaPooledConnectionFactory 에 제공되는 ActiveMQ XA 연결 팩토리를 정의합니다. 그런 다음 JcaPooledConnectionFactory 가 ID ConnectionFactory 를 사용하여 기본 8080으로 제공됩니다.

    JcaPooledConnectionFactory 는 일반 ConnectionFactory와 같습니다. 그러나 새 연결 및 세션이 열리면 XA 트랜잭션을 확인하고, 발견되면 JMS 세션을 XA 리소스로 자동으로 등록합니다. 이를 통해 JMS 세션은 JMS 트랜잭션에 참여할 수 있습니다.

    중요

    JMS 전송에 XA ConnectionFactory를 직접 설정하면 작동하지 않습니다!

14.5. WSDL을 사용하여 JMS 구성

14.5.1. JMS WSDL 확장 Namespance

JMS 끝점을 정의하는 WSDL 확장은 네임스페이스 http://cxf.apache.org/transports/jms 에 정의되어 있습니다. JMS 확장을 사용하려면 예 14.5. “JMS WSDL 확장 네임스페이스” 에 표시된 행을 계약 정의 요소에 추가해야 합니다.

예 14.5. JMS WSDL 확장 네임스페이스

xmlns:jms="http://cxf.apache.org/transports/jms"
Copy to Clipboard Toggle word wrap

14.5.2. 기본 JMS 구성

14.5.2.1. 개요

JMS 주소 정보는 jms:address 요소와 해당 하위 요소인 jms:JMSNamingProperties 요소를 사용하여 제공됩니다. jms:address 요소의 속성은 JMS 브로커와 대상을 식별하는 데 필요한 정보를 지정합니다. jms:JMSNamingProperties 요소는 JNDI 서비스에 연결하는 데 사용되는 Java 속성을 지정합니다.

중요

JMS 기능을 사용하여 지정된 정보는 끝점의 WSDL 파일의 정보를 재정의합니다.

14.5.2.2. JMS 주소 지정

JMS 엔드포인트의 기본 구성은 jms:address 요소를 서비스 포트 요소의 자식으로 사용하여 수행됩니다. WSDL에서 사용되는 jms:address 요소는 구성 파일에서 사용되는 것과 동일합니다. 해당 속성은 표 14.2. “JMS 끝점 속성” 에 나열됩니다.

Expand
표 14.2. JMS 끝점 속성
속성설명

destinationStyle

JMS 대상이 JMS 대기열인지 또는 JMS 주제인지 여부를 지정합니다.

jndiConnectionFactoryName

JMS 대상에 연결할 때 사용할 JMS 연결 팩토리에 바인딩된 JNDI 이름을 지정합니다.

jmsDestinationName

요청이 전송되는 JMS 대상의 JMS 이름을 지정합니다.

jmsReplyDestinationName

응답이 전송되는 JMS 대상의 JMS 이름을 지정합니다. 이 속성을 사용하면 응답에 사용자 정의 대상을 사용할 수 있습니다. 자세한 내용은 14.6절. “이름이 지정된 대상 사용” 에서 참조하십시오.

jndiDestinationName

요청이 전송되는 JMS 대상에 바인딩된 JNDI 이름을 지정합니다.

jndiReplyDestinationName

응답이 전송되는 JMS 대상에 바인딩된 JNDI 이름을 지정합니다. 이 속성을 사용하면 응답에 사용자 정의 대상을 사용할 수 있습니다. 자세한 내용은 14.6절. “이름이 지정된 대상 사용” 에서 참조하십시오.

connectionUserName

JMS 브로커에 연결할 때 사용할 사용자 이름을 지정합니다.

connectionPassword

JMS 브로커에 연결할 때 사용할 암호를 지정합니다.

jms:address WSDL 요소는 jms:JMSNamingProperties 하위 요소를 사용하여 JNDI 공급자에 연결하는 데 필요한 추가 정보를 지정합니다.

14.5.2.3. JNDI 속성 지정

JMS 및 JNDI 공급자와의 상호 운용성을 높이기 위해 jms:address 요소에는 JNDI 공급자에 연결할 때 사용되는 속성을 채우는 데 사용되는 값을 지정하는 데 사용되는 값을 지정할 수 있는 하위 요소 jms:JMSNamingProperties 가 있습니다. jms:JMSNamingProperties 요소에는 namevalue 의 두 가지 속성이 있습니다. 설정할 속성의 이름을 지정합니다. value 속성은 지정된 속성의 값을 지정합니다. JMS:JMSNamingProperties 요소는 공급자 특정 속성의 사양에 사용할 수도 있습니다.

다음은 설정할 수 있는 일반적인 JNDI 속성 목록입니다.

  1. java.naming.factory.initial
  2. java.naming.provider.url
  3. java.naming.factory.object
  4. java.naming.factory.state
  5. java.naming.factory.url.pkgs
  6. java.naming.dns.url
  7. java.naming.authoritative
  8. java.naming.batchsize
  9. java.naming.referral
  10. java.naming.security.protocol
  11. java.naming.security.authentication
  12. java.naming.security.principal
  13. java.naming.security.credentials
  14. java.naming.language
  15. java.naming.applet

이러한 속성에 사용할 정보에 대한 자세한 내용은 JNDI 공급자의 설명서를 확인하고 Java API 참조 자료를 참조하십시오.

14.5.2.4. 예제

예 14.6. “JMS WSDL 포트 사양” JMS WSDL 포트 사양의 예를 보여줍니다.

예 14.6. JMS WSDL 포트 사양

<service name="JMSService">
  <port binding="tns:Greeter_SOAPBinding" name="SoapPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/test.Celtix.jmstransport" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
  </port>
</service>
Copy to Clipboard Toggle word wrap

14.5.3. JMS 클라이언트 구성

14.5.3.1. 개요

JMS 소비자 끝점은 사용하는 메시지 유형을 지정합니다. JMS 소비자 끝점은 JMS Cryostat Message 또는 JMS text Message 를 사용할 수 있습니다.

consumer endpoint는 byte[] 를 사용하여 데이터를 저장하고 JMS 메시지 본문에서 데이터를 검색하는 방법으로 사용합니다. 메시지가 전송되면 포맷된 정보를 포함한 메시지 데이터가 byte[] 로 패키지되고 message body에 배치되기 전에 패키지됩니다. 메시지가 수신되면 소비자 끝점은 바이트[] 에 팩된 것처럼 메시지 본문에 저장된 데이터를 차단 해제하려고 합니다.

textMessage 를 사용하는 경우 소비자 끝점은 메시지 본문에서 데이터를 저장하고 검색하는 방법으로 문자열을 사용합니다. 메시지가 전송되면 형식별 정보를 포함한 메시지 정보가 문자열로 변환되어 JMS 메시지 본문에 배치됩니다. 메시지가 수신되면 소비자 끝점은 JMS 메시지 본문에 저장된 데이터를 문자열로 압축 해제하려고 합니다.

네이티브 JMS 애플리케이션이 Apache CXF 소비자와 상호 작용할 때 JMS 애플리케이션은 메시지 및 포멧 정보를 해석합니다. 예를 들어 Apache CXF 계약이 JMS 끝점에 사용된 바인딩이 Cryostat이고 메시지가 text Message 로 패키지되도록 지정하는 경우 수신 JMS 애플리케이션은 모든 Cryostat 조각 정보를 포함하는 텍스트 메시지를 가져옵니다.

14.5.3.2. 메시지 유형 지정

JMS 소비자 엔드포인트에서 허용하는 메시지 유형은 선택 사항 jms:client 요소를 사용하여 구성됩니다. jms:client 요소는 WSDL 포트 요소의 자식이며 하나의 속성이 있습니다.

Expand
표 14.3. JMS 클라이언트 WSDL 확장

messageType

메시지 데이터를 JMS 메시지로 패키징하는 방법을 지정합니다. text 는 데이터가 text Message 로 패키지되도록 지정합니다. 바이너리 는 데이터가 Cryostat Message 로 패키징되도록 지정합니다.

14.5.3.3. 예제

예 14.7. “JMS 소비자 끝점용 WSDL” 은 JMS 소비자 엔드포인트를 구성하기 위한 WSDL을 보여줍니다.

예 14.7. JMS 소비자 끝점용 WSDL

<service name="JMSService">
  <port binding="tns:Greeter_SOAPBinding" name="SoapPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/test.Celtix.jmstransport" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
    <jms:client messageType="binary" />
  </port>
</service>
Copy to Clipboard Toggle word wrap

14.5.4. JMS 공급자 구성

14.5.4.1. 개요

JMS 공급자 끝점에는 구성 가능한 여러 동작이 있습니다. 여기에는 다음이 포함됩니다.

  • 메시지가 상관되는 방법
  • Cryostat 서브스크립션 사용
  • 서비스에서 로컬 JMS 트랜잭션을 사용하는 경우
  • 끝점에서 사용하는 메시지 선택기
14.5.4.2. 구성 지정

공급자 끝점 동작은 선택적 jms:server 요소를 사용하여 구성됩니다. jms:server 요소는 WSDL wsdl:port 요소의 자식이며 다음과 같은 특성을 갖습니다.

Expand
표 14.4. JMS 공급자 끝점 WSDL 확장
속성설명

useMessageIDAsCorrealationID

JMS에서 메시지 ID를 사용하여 메시지 상관 관계를 설정할지 여부를 지정합니다. 기본값은 false입니다.

durableSubscriberName

Cryostat 서브스크립션을 등록하는 데 사용되는 이름을 지정합니다.

messageSelector

사용할 메시지 선택기의 문자열 값을 지정합니다. 메시지 선택기를 지정하는 데 사용되는 구문에 대한 자세한 내용은 JMS 1.1 사양을 참조하십시오.

트랜잭션

로컬 JMS 브로커가 메시지 처리에 대한 트랜잭션을 생성할지 여부를 지정합니다. 기본값은 false입니다. [a]

[a] 현재는 트랜잭션 특성을 true 로 설정하는 것은 런타임에서 지원되지 않습니다.
14.5.4.3. 예제

예 14.8. “JMS 공급자 엔드 포인트용 WSDL” 은 JMS 공급자 엔드포인트를 구성하기 위한 WSDL을 보여줍니다.

예 14.8. JMS 공급자 엔드 포인트용 WSDL

<service name="JMSService">
  <port binding="tns:Greeter_SOAPBinding" name="SoapPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/test.Celtix.jmstransport" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
    <jms:server messageSelector="cxf_message_selector"
                useMessageIDAsCorrelationID="true"
                transactional="true"
                durableSubscriberName="cxf_subscriber" />
  </port>
</service>
Copy to Clipboard Toggle word wrap

14.6. 이름이 지정된 대상 사용

14.6.1. 개요

기본적으로 JMS를 사용하는 Apache CXF 끝점은 다시 응답을 전송하기 위한 임시 큐를 생성합니다. 이름이 지정된 큐를 사용하려면 엔드포인트의 JMS 구성의 일부로 응답을 보내는 데 사용되는 큐를 구성할 수 있습니다.

14.6.2. 응답 대상 이름 설정

엔드포인트의 JMS 구성에서 jmsReplyDestinationName 속성 또는 jndiReplyDestinationName 특성을 사용하여 응답 대상을 지정합니다. 클라이언트 끝점은 지정된 대상에서 응답을 수신 대기하고 나가는 모든 요청의 ReplyTo 필드에 속성 값을 지정합니다. 서비스 끝점은 요청의 ReplyTo 필드에 지정된 대상이 없는 경우 응답을 배치할 위치로 jndiReplyDestinationName 속성 값을 사용합니다.

14.6.3. 예제

예 14.9. “이름이 지정된 응답 대기열을 사용한 JMS 소비자 사양” JMS 클라이언트 엔드포인트에 대한 구성을 보여줍니다.

예 14.9. 이름이 지정된 응답 대기열을 사용한 JMS 소비자 사양

<jms:conduit name="{http://cxf.apache.org/jms_endpt}HelloWorldJMSPort.jms-conduit">
    <jms:address destinationStyle="queue"
                 jndiConnectionFactoryName="myConnectionFactory"
                 jndiDestinationName="myDestination"
                 jndiReplyDestinationName="myReplyDestination" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.apache.cxf.transport.jms.MyInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
  </jms:conduit>
Copy to Clipboard Toggle word wrap

15장. Apache ActiveMQ와 통합

15.1. 개요

Apache ActiveMQ를 JMS 공급자로 사용하는 경우 대상의 JNDI 이름을 대기열 또는 주제에 대한 JNDI 바인딩을 동적으로 생성하는 특수 형식으로 지정할 수 있습니다. 즉, 대기열 또는 주제의 JNDI 바인딩을 미리 JMS 공급자를 구성할 필요가 없습니다.

15.2. 초기 컨텍스트 팩토리

Apache ActiveMQ와 JNDI를 통합하는 핵심은 ActiveMQInitialContextFactory 클래스입니다. 이 클래스는 JNDI InitialContext 인스턴스를 생성하는 데 사용되며, 이를 사용하여 JMS 브로커의 JMS 대상에 액세스할 수 있습니다.

예 15.1. “Apache ActiveMQ에 연결하기 위한 Cryostat/JMS WSDL” Apache ActiveMQ와 통합된 JNDI InitialContext 를 생성하기 위해 Cryostat/JMS WSDL 확장을 표시합니다.

예 15.1. Apache ActiveMQ에 연결하기 위한 Cryostat/JMS WSDL

<soapjms:jndiInitialContextFactory>
  org.apache.activemq.jndi.ActiveMQInitialContextFactory
</soapjms:jndiInitialContextFactory>
<soapjms:jndiURL>tcp://localhost:61616</soapjms:jndiURL>
Copy to Clipboard Toggle word wrap

예 15.1. “Apache ActiveMQ에 연결하기 위한 Cryostat/JMS WSDL” 에서 Apache ActiveMQ 클라이언트는 tcp://localhost:61616 에 있는 브로커 포트에 연결합니다.

15.3. 연결 팩토리 검색

JNDI InitialContext 인스턴스를 생성할 뿐만 아니라 javax.jms.ConnectionFactory 인스턴스에 바인딩된 JNDI 이름을 지정해야 합니다. Apache ActiveMQ의 경우 JNDI 이름 ConnectionFactoryActiveMQConnectionFactory 인스턴스에 매핑하는 InitialContext 인스턴스에 사전 정의된 바인딩이 있습니다. 예 15.2. “Apache ActiveMQ 연결 팩토리를 지정하기 위한 Cryostat/JMS WSDL” Apache ActiveMQ 연결 팩토리를 지정하기 위한 Cryostat/JMS 확장 요소를 shaows합니다.

예 15.2. Apache ActiveMQ 연결 팩토리를 지정하기 위한 Cryostat/JMS WSDL

<soapjms:jndiConnectionFactoryName>
  ConnectionFactory
</soapjms:jndiConnectionFactoryName>
Copy to Clipboard Toggle word wrap

15.4. 동적 대상의 구문

큐 또는 항목에 동적으로 액세스하려면 다음 형식 중 하나에서 대상의 JNDI 이름을 JNDI 복합 이름으로 지정합니다.

dynamicQueues/QueueName
dynamicTopics/TopicName
Copy to Clipboard Toggle word wrap

QueueNameTopicName 은 Apache ActiveMQ 브로커가 사용하는 이름입니다. 이는 추상 JNDI 이름이 아닙니다.

예 15.3. “동적으로 생성된 큐를 사용한 WSDL 포트 사양” 동적으로 생성된 큐를 사용하는 WSDL 포트를 표시합니다.

예 15.3. 동적으로 생성된 큐를 사용한 WSDL 포트 사양

<service name="JMSService">
  <port binding="tns:GreeterBinding" name="JMSPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/greeter.request.queue" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
  </port>
</service>
Copy to Clipboard Toggle word wrap

애플리케이션이 JMS 연결을 열려고 하면 Apache ActiveMQ에서 JNDI 이름 Cryostater .request.queue가 있는 큐 가 있는지 확인합니다. 존재하지 않는 경우 새 큐를 생성하여 JNDI 이름 happy er.request.queue에 바인딩합니다.

16장. conduits

초록

Conduits는 아웃바운드 연결을 구현하는 데 사용되는 낮은 수준의 전송 아키텍처입니다. 해당 동작 및 라이프사이클은 시스템 성능 및 처리 로드에 영향을 미칠 수 있습니다.

16.1. 개요

Conduits는 Apache CXF 런타임의 클라이언트 측 또는 아웃 바운드 세부 정보를 관리합니다. 포트 열기, 아웃바운드 연결 설정, 메시지 전송, 애플리케이션과 단일 외부 끝점 간의 모든 응답을 수신 대기해야 합니다. 애플리케이션이 여러 끝점에 연결하면 각 끝점에 대해 하나의 연속 인스턴스가 생성됩니다.

각 전송 유형은 Conduit 인터페이스를 사용하여 자체 conduit를 구현합니다. 이를 통해 애플리케이션 수준 기능과 전송 간의 표준화된 인터페이스를 사용할 수 있습니다.

일반적으로 클라이언트 측 전송 세부 정보를 구성할 때 애플리케이션에서 사용하는 정체에 대해서만 주의해야 합니다. 런타임에서 conduits를 처리하는 방법의 기본 의미 체계는 일반적으로 개발자가 걱정해야 하는 것이 아닙니다.

그러나 conduit's를 이해하면 도움이 될 수 있는 경우가 있습니다.

  • 사용자 정의 전송 구현
  • 제한된 리소스를 관리하기 위한 고급 애플리케이션 튜닝

16.2. Conduit 라이프 사이클

conduits는 클라이언트 구현 개체에서 관리합니다. 생성되면 클라이언트 구현 오브젝트 기간 동안 연속이 생성됩니다. conduit의 라이프 사이클은 다음과 같습니다.

  1. 클라이언트 구현 오브젝트가 생성되면 ConduitSelector 오브젝트에 대한 참조가 제공됩니다.
  2. 클라이언트가 메시지를 전송해야 하는 경우 메시지가 요청의 conduit 선택기에 대한 참조입니다.

    메시지가 새 엔드포인트에 대한 경우 conduit 선택기는 새 conduit를 생성하여 클라이언트 구현에 전달합니다. 그렇지 않으면 대상 끝점에 대한 요약에 대한 참조를 클라이언트에 전달합니다.

  3. 동의어는 필요에 따라 메시지를 보냅니다.
  4. 클라이언트 구현 개체가 삭제되면 연결된 모든 연속이 삭제됩니다.

16.3. Conduit weight

conduit 오브젝트의 가중치는 전송 구현에 따라 다릅니다. HTTP 접합은 매우 간단한 가중치입니다. JMS 연속은 JMS Session 오브젝트 및 하나 이상의 JMSListenerContainer 오브젝트와 연결되어 있기 때문에 무관합니다.

IV 부. 웹 서비스 엔드 포인트 구성

이 가이드에서는 Red Hat Fuse에서 Apache CXF 엔드포인트를 생성하는 방법을 설명합니다.

17장. Cryostat-WS 끝점 구성

초록

Cryostat-WS 끝점은 3개의 Spring 구성 요소 중 하나를 사용하여 구성됩니다. 올바른 요소는 구성하려는 끝점 유형과 사용하려는 기능에 따라 달라집니다. 소비자의 경우 jaxws:client 요소를 사용합니다. 서비스 공급자의 경우 jaxws:endpoint 요소 또는 jaxws:server 요소를 사용할 수 있습니다.

엔드포인트를 정의하는 데 사용되는 정보는 일반적으로 엔드 포인트의 계약에 정의되어 있습니다. 구성 요소를 사용하여 계약의 정보를 덮어쓸 수 있습니다. 구성 요소를 사용하여 계약에 제공되지 않는 정보를 제공할 수도 있습니다.

구성 요소를 사용하여 WS-RM과 같은 고급 기능을 활성화해야 합니다. 이 작업은 하위 요소를 끝점의 구성 요소에 제공하여 수행됩니다. Java 우선 접근 방식을 사용하여 개발된 끝점을 처리할 때는 엔드포인트 계약 역할을 하는 SEI에 바인딩 및 전송 유형에 대한 정보가 없을 가능성이 큽니다.

17.1. 서비스 공급자 구성

17.1.1. 서비스 공급자 구성을 위한 요소

Apache CXF에는 서비스 공급자를 구성하는 데 사용할 수 있는 두 가지 요소가 있습니다.

두 요소의 차이점은 대부분 런타임 내부에 있습니다. jaxws:endpoint 요소는 서비스 엔드포인트를 지원하기 위해 생성된 org.apache.cxf.jaxws.EndpointImpl 개체에 속성을 삽입합니다. jaxws:server 요소는 엔드포인트를 지원하기 위해 생성된 org.apache.cxf.jaxws.support.JaxWsServerFactoryBean 오브젝트에 속성을 삽입합니다. EndpointImpl 오브젝트는 구성 데이터를 JaxWsServerFactoryBean 오브젝트에 전달합니다. JaxWsServerFactoryBean 오브젝트는 실제 서비스 오브젝트를 생성하는 데 사용됩니다. 구성 요소 중 하나가 서비스 끝점을 구성하므로 원하는 구문을 기반으로 선택할 수 있습니다.

17.1.2. jaxws:endpoint Element 사용

17.1.2.1. 개요

jaxws:endpoint 요소는 Cryostat-WS 서비스 공급자를 구성하는 기본 요소입니다. 해당 속성 및 하위는 서비스 공급자를 인스턴스화하는 데 필요한 모든 정보를 지정합니다. 많은 특성은 서비스 계약의 정보에 매핑됩니다. 하위 항목은 인터셉터 및 기타 고급 기능을 구성하는 데 사용됩니다.

17.1.2.2. 구성 중인 끝점 식별

런타임에서 구성을 적절한 서비스 공급자에 적용하려면 해당 구성을 식별할 수 있어야 합니다. 서비스 공급자를 식별하는 기본 방법은 끝점을 구현하는 클래스를 지정하는 것입니다. 이 작업은 jaxws:endpoint 요소의 implementor 특성을 사용하여 수행됩니다.

다른 끝점이 공통 구현을 공유하는 인스턴스의 경우 각 끝점에 대해 다른 구성을 제공할 수 있습니다. 구성에서 특정 끝점을 구분하는 방법은 다음 두 가지가 있습니다.

  • serviceName 속성 및 endpointName 속성의 조합

    serviceName 속성은 서비스의 엔드포인트를 정의하는 wsdl:service 요소를 지정합니다. endpointName 속성은 서비스의 엔드포인트를 정의하는 특정 wsdl:port 요소를 지정합니다. 두 속성은 모두 ns:name형식을 사용하여 QNames 로 지정됩니다. NS 는 요소의 네임스페이스이고 name 은 요소의 name 속성 값입니다.

    참고

    wsdl:service 요소에 wsdl:port 요소가 하나만 있는 경우 endpointName 속성을 생략할 수 있습니다.

  • name 속성

    name 속성은 서비스의 엔드포인트를 정의하는 특정 wsdl:port 요소의 QName을 지정합니다. QName 형식은 {ns}localPart 형식으로 제공됩니다. NS는 ws dl:port 요소의 네임스페이스이며 localPartwsdl:port 요소의 name 속성 값입니다.

17.1.2.3. 속성

jaxws:endpoint 요소의 속성은 끝점의 기본 속성을 구성합니다. 이러한 속성에는 끝점의 주소, 엔드포인트를 구현하는 클래스 및 엔드포인트를 호스팅하는 버스가 포함됩니다.

표 17.1. “jaxws:endpoint Element를 사용하여 Cryostat-WS 서비스 공급자 구성의 속성” jaxws:endpoint 요소의 속성을 설명합니다.

Expand
표 17.1. jaxws:endpoint Element를 사용하여 Cryostat-WS 서비스 공급자 구성의 속성
속성설명

id

다른 구성 요소가 끝점을 참조하는 데 사용할 수 있는 고유 식별자를 지정합니다.

구현자

서비스를 구현하는 클래스를 지정합니다. 클래스 이름 또는 구현 클래스를 구성하는 Spring 빈에 대한 ID 참조를 사용하여 구현 클래스를 지정할 수 있습니다. 이 클래스는 classpath에 있어야 합니다.

implementorClass

서비스를 구현하는 클래스를 지정합니다. 이 속성은 구현 자 속성에 제공된 값이 Spring AOP를 사용하여 래핑되는ans에 대한 참조인 경우 유용합니다.

address

HTTP 끝점의 주소를 지정합니다. 이 값은 서비스 계약에 지정된 값을 재정의합니다.

wsdlLocation

끝점의 WSDL 계약 위치를 지정합니다. WSDL 계약의 위치는 서비스가 배포된 폴더를 기준으로 합니다.

endpointName

서비스의 wsdl:port 요소의 name 속성 값을 지정합니다. ns:name 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:port 요소의 네임스페이스입니다.

serviceName

서비스의 wsdl:service 요소의 name 특성 값을 지정합니다. ns:name 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:service 요소의 네임스페이스입니다.

publish

서비스를 자동으로 게시해야 하는지 여부를 지정합니다. 이 값이 false 로 설정된 경우 개발자는 31장. 서비스 게시 에 설명된 끝점을 명시적으로 게시해야 합니다.

버스

서비스 엔드포인트를 관리하는 데 사용되는 버스를 구성하는 Spring 8080의 ID를 지정합니다. 이는 공통 기능 세트를 사용하도록 여러 끝점을 구성할 때 유용합니다.

bindingUri

서비스에서 사용하는 메시지 바인딩의 ID를 지정합니다. 유효한 바인딩 ID 목록은 23장. Apache CXF 바인딩 ID 에 제공됩니다.

name

서비스의 wsdl:port 요소의 문자열화된 QName을 지정합니다. {ns}localPart 형식을 사용하여 QName으로 지정됩니다. NS는 ws dl:port 요소의 네임스페이스이며 localPartwsdl:port 요소의 name 속성 값입니다.

abstract

8080이 추상 8080인지 여부를 지정합니다. 추상 빈은 구체적인 8080 정의에 대해 상위 역할을 하며 인스턴스화되지 않습니다. 기본값은 false입니다. true 로 설정하면 Cryostat 팩토리에서 8080을 인스턴스화하지 않도록 지시합니다.

depends-on

끝점이 인스턴스화되기 전에 인스턴스화되는 경우 종속되는 빈 목록을 지정합니다.

createdFromAPI

사용자가 Apache CXF API(예: Endpoint.publish() 또는 Service.getPort() )를 사용하여 해당 8080을 만들도록 지정합니다.

기본값은 false입니다.

이 값을 true 로 설정하면 다음이 수행됩니다.

  • .jaxws-endpoint 를 ID에 추가하여 빈의 내부 이름 변경
  • 8080을 추상화합니다.

publishedEndpointUrl

생성된 WSDL의 address 요소에 배치되는 URL입니다. 이 값을 지정하지 않으면 address 속성 값이 사용됩니다. 이 속성은 "public" URL이 서비스가 배포된 URL과 동일하지 않을 때 유용합니다.

표 17.1. “jaxws:endpoint Element를 사용하여 Cryostat-WS 서비스 공급자 구성의 속성” 에 나열된 속성 외에도 여러 xmlns:shortName특성을 사용하여 endpointName serviceName 속성에서 사용하는 네임스페이스를 선언해야 할 수 있습니다.

17.1.2.4. 예제

예 17.1. “간단한 Cryostat-WS 끝점 구성” 엔드포인트가 게시되는 주소를 지정하는 a Cryostat-WS 엔드포인트에 대한 구성이 표시됩니다. 이 예제에서는 다른 모든 값에 기본값을 사용하거나 구현에 주석에 지정된 값이 있다고 가정합니다.

예 17.1. 간단한 Cryostat-WS 끝점 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:endpoint id="example"
                  implementor="org.apache.cxf.example.DemoImpl"
                  address="http://localhost:8080/demo" />
</beans>
Copy to Clipboard Toggle word wrap

예 17.2. “서비스 이름을 사용한 Cryostat-WS 끝점 구성” 계약에는 두 개의 서비스 정의가 포함된 엔드포인트 구성이 표시됩니다. 이 경우 serviceName 특성을 사용하여 인스턴스화할 서비스 정의를 지정해야 합니다.

예 17.2. 서비스 이름을 사용한 Cryostat-WS 끝점 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">

  <jaxws:endpoint id="example2"
                  implementor="org.apache.cxf.example.DemoImpl"
                  serviceName="samp:demoService2"
                  xmlns:samp="http://org.apache.cxf/wsdl/example" />

</beans>
Copy to Clipboard Toggle word wrap

xmlns:samp 속성은 WSDL service 요소가 정의된 네임스페이스를 지정합니다.

예 17.3. “HTTP/2가 활성화된 Cryostat-WS 끝점 구성” HTTP/2가 활성화된 주소를 지정하는 another-WS 끝점에 대한 구성을 표시합니다.

Apache CXF용 HTTP/2 구성

HTTP/2는 Apache Karaf에서 독립 실행형 Apache CXF Cryostat 전송(http-undertow)을 사용하는 경우 지원됩니다. HTTP/2 프로토콜을 활성화하려면 jaxws:endpoint 요소의 address 속성을 절대 URL로 설정하고 org.apache.cxf.transports.http_undertow.EnableHttp2 속성을 true 로 설정해야 합니다.

참고

이 HTTP/2 구현은 일반 HTTP 또는 HTTPS를 사용하는 서버 측 HTTP/2 전송만 지원합니다.

예 17.3. HTTP/2가 활성화된 Cryostat-WS 끝점 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
  http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
  ...">

  <cxf:bus>
    <cxf:properties>
        <entry key="org.apache.cxf.transports.http_undertow.EnableHttp2" value="true"/>
    </cxf:properties>
  </cxf:bus>

  <jaxws:endpoint id="example3"
                implementor="org.apache.cxf.example.DemoImpl"
                address="http://localhost:8080/demo" />
  </jaxws:endpoint>

</beans>
Copy to Clipboard Toggle word wrap
참고

성능 향상을 위해 Red Hat은 웹 컨테이너의 중앙 집중식 구성 및 튜닝을 활성화하는 Apache Karaf(pax-web-undertow)에서 서블릿 전송을 사용할 것을 권장하지만 pax-web-undertow 는 HTTP/2 전송 프로토콜을 지원하지 않습니다.

17.1.3. jaxws:server Element 사용

17.1.3.1. 개요

jaxws:server 요소는 Cryostat-WS 서비스 공급자를 구성하는 요소입니다. 구성 정보를 org.apache.cxf.jaxws.support.JaxWsServerFactoryBean 에 삽입합니다. 이는 Apache CXF 특정 오브젝트입니다. 서비스를 구축하기 위해 순수한 Spring 접근 방식을 사용하는 경우 Apache CXF 특정 API를 사용하여 서비스와 상호 작용할 필요가 없습니다.

jaxws:server 요소의 속성 및 하위 요소는 서비스 공급자를 인스턴스화하는 데 필요한 모든 정보를 지정합니다. 속성은 끝점을 인스턴스화하는 데 필요한 정보를 지정합니다. 하위 항목은 인터셉터 및 기타 고급 기능을 구성하는 데 사용됩니다.

17.1.3.2. 구성 중인 끝점 식별

런타임에서 구성을 적절한 서비스 공급자에 적용하려면 해당 구성을 식별할 수 있어야 합니다. 서비스 공급자를 식별하는 기본 방법은 끝점을 구현하는 클래스를 지정하는 것입니다. 이 작업은 jaxws:server 요소의 serviceBean 특성을 사용하여 수행됩니다.

다른 끝점이 공통 구현을 공유하는 인스턴스의 경우 각 끝점에 대해 다른 구성을 제공할 수 있습니다. 구성에서 특정 끝점을 구분하는 방법은 다음 두 가지가 있습니다.

  • serviceName 속성 및 endpointName 속성의 조합

    serviceName 속성은 서비스의 엔드포인트를 정의하는 wsdl:service 요소를 지정합니다. endpointName 속성은 서비스의 엔드포인트를 정의하는 특정 wsdl:port 요소를 지정합니다. 두 속성은 모두 ns:name형식을 사용하여 QNames 로 지정됩니다. NS 는 요소의 네임스페이스이고 name 은 요소의 name 속성 값입니다.

    참고

    wsdl:service 요소에 wsdl:port 요소가 하나만 있는 경우 endpointName 속성을 생략할 수 있습니다.

  • name 속성

    name 속성은 서비스의 엔드포인트를 정의하는 특정 wsdl:port 요소의 QName을 지정합니다. QName 형식은 {ns}localPart 형식으로 제공됩니다. NS는 ws dl:port 요소의 네임스페이스이며 localPartwsdl:port 요소의 name 속성 값입니다.

17.1.3.3. 속성

jaxws:server 요소의 속성은 끝점의 기본 속성을 구성합니다. 이러한 속성에는 끝점의 주소, 엔드포인트를 구현하는 클래스 및 엔드포인트를 호스팅하는 버스가 포함됩니다.

표 17.2. “jaxws:server Element를 사용하여 Cryostat-WS 서비스 공급자 구성의 속성” jaxws:server 요소의 속성을 설명합니다.

Expand
표 17.2. jaxws:server Element를 사용하여 Cryostat-WS 서비스 공급자 구성의 속성
속성설명

id

다른 구성 요소가 끝점을 참조하는 데 사용할 수 있는 고유 식별자를 지정합니다.

serviceBean

서비스를 구현하는 클래스를 지정합니다. 클래스 이름 또는 구현 클래스를 구성하는 Spring 빈에 대한 ID 참조를 사용하여 구현 클래스를 지정할 수 있습니다. 이 클래스는 classpath에 있어야 합니다.

serviceClass

서비스를 구현하는 클래스를 지정합니다. 이 속성은 구현 자 속성에 제공된 값이 Spring AOP를 사용하여 래핑되는ans에 대한 참조인 경우 유용합니다.

address

HTTP 끝점의 주소를 지정합니다. 이 값은 서비스 계약에 지정된 값을 재정의합니다.

wsdlLocation

끝점의 WSDL 계약 위치를 지정합니다. WSDL 계약의 위치는 서비스가 배포된 폴더를 기준으로 합니다.

endpointName

서비스의 wsdl:port 요소의 name 속성 값을 지정합니다. ns:name 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:port 요소의 네임스페이스입니다.

serviceName

서비스의 wsdl:service 요소의 name 특성 값을 지정합니다. ns:name 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:service 요소의 네임스페이스입니다.

publish

서비스를 자동으로 게시해야 하는지 여부를 지정합니다. 이 값이 false 로 설정된 경우 개발자는 31장. 서비스 게시 에 설명된 끝점을 명시적으로 게시해야 합니다.

버스

서비스 엔드포인트를 관리하는 데 사용되는 버스를 구성하는 Spring 8080의 ID를 지정합니다. 이는 공통 기능 세트를 사용하도록 여러 끝점을 구성할 때 유용합니다.

bindingId

서비스에서 사용하는 메시지 바인딩의 ID를 지정합니다. 유효한 바인딩 ID 목록은 23장. Apache CXF 바인딩 ID 에 제공됩니다.

name

서비스의 wsdl:port 요소의 문자열화된 QName을 지정합니다. {ns}localPart 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:port 요소의 네임스페이스이고 localPartwsdl:port 요소의 name 속성 값입니다.

abstract

8080이 추상 8080인지 여부를 지정합니다. 추상 빈은 구체적인 8080 정의에 대해 상위 역할을 하며 인스턴스화되지 않습니다. 기본값은 false입니다. true 로 설정하면 Cryostat 팩토리에서 8080을 인스턴스화하지 않도록 지시합니다.

depends-on

엔드포인트를 인스턴스화하기 전에 끝점이 인스턴스화되는 데 따라 달라지는 빈 목록을 지정합니다.

createdFromAPI

사용자가 Apache CXF API(예: Endpoint.publish() 또는 Service.getPort() )를 사용하여 해당 8080을 만들도록 지정합니다.

기본값은 false입니다.

이 값을 true 로 설정하면 다음이 수행됩니다.

  • .jaxws-endpoint 를 ID에 추가하여 빈의 내부 이름 변경
  • 8080을 추상화합니다.

표 17.2. “jaxws:server Element를 사용하여 Cryostat-WS 서비스 공급자 구성의 속성” 에 나열된 속성 외에도 여러 xmlns:shortName특성을 사용하여 endpointName serviceName 속성에서 사용하는 네임스페이스를 선언해야 할 수 있습니다.

17.1.3.4. 예제

예 17.4. “간단한 Cryostat-WS 서버 구성” 엔드포인트가 게시되는 주소를 지정하는 a Cryostat-WS 엔드포인트에 대한 구성이 표시됩니다.

예 17.4. 간단한 Cryostat-WS 서버 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:server id="exampleServer"
                  serviceBean="org.apache.cxf.example.DemoImpl"
                  address="http://localhost:8080/demo" />
</beans>
Copy to Clipboard Toggle word wrap

17.1.4. 서비스 공급자에 기능 추가

17.1.4.1. 개요

jaxws:endpointjaxws:server 요소는 서비스 공급자를 인스턴스화하는 데 필요한 기본 구성 정보를 제공합니다. 서비스 공급자에 기능을 추가하거나 고급 구성을 수행하려면 구성에 하위 요소를 추가해야 합니다.

자식 요소는 다음을 수행할 수 있도록 합니다.

17.1.4.2. 요소

표 17.3. “Cryostat-WS 서비스 공급자 구성에 사용되는 요소” jaxws:endpoint 가 지원하는 하위 요소를 설명합니다.

Expand
표 17.3. Cryostat-WS 서비스 공급자 구성에 사용되는 요소
element설명

jaxws:handlers

메시지 처리를 위한 Cryostat-WS Handler 구현 목록을 지정합니다. Cryostat-WS Handler 구현에 대한 자세한 내용은 43장. 처리기 작성 에서 참조하십시오.

jaxws:inInterceptors

인바운드 요청을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:inFaultInterceptors

인바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:outInterceptors

아웃바운드 응답을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:outFaultInterceptors

아웃바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:binding

엔드포인트에서 사용하는 메시지 바인딩을 구성하는 polkit을 지정합니다. 메시지 바인딩은 org.apache.cxf.binding.Binding factory 인터페이스의 구현을 사용하여 구성됩니다.[a]

jaxws:dataBinding [b]

끝점에서 사용하는 데이터 바인딩을 구현하는 클래스를 지정합니다. 포함된 빈 정의를 사용하여 지정됩니다.

jaxws:executor

서비스에 사용되는 Java executor를 지정합니다. 포함된 빈 정의를 사용하여 지정됩니다.

jaxws:features

Apache CXF의 고급 기능을 구성하는 빈 목록을 지정합니다. Quarkus 참조 목록 또는 포함된 빈 목록을 제공할 수 있습니다.

jaxws:invoker

서비스에서 사용하는 org.apache.cxf.service.Invoker 인터페이스의 구현을 지정합니다. [c]

jaxws:properties

끝점에 전달되는 속성의 Spring map을 지정합니다. 이러한 속성은 MTOM 지원 활성화와 같은 기능을 제어하는 데 사용할 수 있습니다.

jaxws:serviceFactory

서비스를 인스턴스화하는 데 사용되는 JaxWsServiceFactoryBean 오브젝트를 구성합니다.

[a] Cryostat 바인딩은 soap:soapBinding 8080을 사용하여 구성됩니다.
[b] jaxws:endpoint 요소는 jaxws:dataBinding 요소를 지원하지 않습니다.
[c] Invoker 구현에서는 서비스 호출 방법을 제어합니다. 예를 들어 서비스 구현의 새 인스턴스에서 각 요청을 처리할지 또는 호출 간에 state가 보존되는지 여부를 제어합니다.

17.1.5. Cryostat-WS 끝점에서 스키마 유효성 검사 활성화

17.1.5.1. 개요

schema-validation-enabled 속성을 설정하여 jaxws:endpoint 요소 또는 jaxws:server 요소에 대한 스키마 검증을 활성화할 수 있습니다. 스키마 유효성 검사가 활성화되면 클라이언트와 서버 간에 전송된 메시지가 스키마에 대한 적합성을 확인합니다. 성능에 심각한 영향을 미치므로 기본적으로 스키마 유효성 검사가 꺼집니다.

17.1.5.2. 예제

Cryostat-WS 엔드포인트에서 스키마 검증을 활성화하려면 jaxws:properties 하위 요소 또는 jaxws:server 요소의 jaxws: properties 하위 요소에서 schema-validation-enabled 속성을 설정합니다. 예를 들어 jaxws:endpoint 요소에서 스키마 유효성 검사를 활성화하려면 다음을 수행합니다.

<jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
    wsdlLocation="wsdl/hello_world.wsdl"
    createdFromAPI="true">
    <jaxws:properties>
        <entry key="schema-validation-enabled" value="BOTH" />
    </jaxws:properties>
</jaxws:endpoint>
Copy to Clipboard Toggle word wrap

schema-validation-enabled 속성의 허용된 값 목록은 24.3.4.7절. “스키마 유효성 검사 유형 값” 를 참조하십시오.

17.2. 소비자 끝점 구성

17.2.1. 개요

Cryostat-WS 소비자 끝점은 jaxws:client 요소를 사용하여 구성됩니다. 요소의 속성은 소비자를 생성하는 데 필요한 기본 정보를 제공합니다.

WS-RM과 같은 다른 기능을 소비자에 추가하려면 jaxws:client 요소에 하위 기능을 추가합니다. 하위 요소는 끝점의 로깅 동작을 구성하고 다른 속성을 끝점 구현에 삽입하는 데도 사용됩니다.

17.2.2. 기본 구성 속성

표 17.4. “Cryostat-WS 소비자를 구성하는 데 사용되는 속성” 에 설명된 속성은 Cryostat-WS 소비자를 구성하는 데 필요한 기본 정보를 제공합니다. 구성할 특정 속성에 대한 값만 제공해야 합니다. 대부분의 속성에는 합리적인 기본값이 있거나 끝점 계약에서 제공하는 정보를 사용합니다.

Expand
표 17.4. Cryostat-WS 소비자를 구성하는 데 사용되는 속성
속성설명

address

소비자가 요청할 끝점의 HTTP 주소를 지정합니다. 이 값은 계약에 설정된 값을 재정의합니다.

bindingId

소비자가 사용하는 메시지 바인딩의 ID를 지정합니다. 유효한 바인딩 ID 목록은 23장. Apache CXF 바인딩 ID 에 제공됩니다.

버스

엔드포인트를 관리하는 버스를 구성하는 Spring 8080의 ID를 지정합니다.

endpointName

소비자가 요청하는 서비스에 대한 wsdl:port 요소의 name 특성 값을 지정합니다. ns:name 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:port 요소의 네임스페이스입니다.

serviceName

소비자가 요청하는 서비스에 대한 wsdl:service 요소의 name 특성 값을 지정합니다. ns:name 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:service 요소의 네임스페이스입니다.

사용자 이름

간단한 사용자 이름/암호 인증에 사용되는 사용자 이름을 지정합니다.

암호

간단한 사용자 이름/암호 인증에 사용되는 암호를 지정합니다.

serviceClass

서비스 엔드포인트 인터페이스(SEI)의 이름을 지정합니다.

wsdlLocation

끝점의 WSDL 계약 위치를 지정합니다. WSDL 계약의 위치는 클라이언트가 배포된 폴더를 기준으로 합니다.

name

소비자가 요청하는 서비스에 대한 wsdl:port 요소의 문자열 QName을 지정합니다. {ns}localPart 형식을 사용하여 QName으로 지정됩니다. 여기서 nswsdl:port 요소의 네임스페이스이고 localPartwsdl:port 요소의 name 속성 값입니다.

abstract

8080이 추상 8080인지 여부를 지정합니다. 추상 빈은 구체적인 8080 정의에 대해 상위 역할을 하며 인스턴스화되지 않습니다. 기본값은 false입니다. true 로 설정하면 Cryostat 팩토리에서 8080을 인스턴스화하지 않도록 지시합니다.

depends-on

끝점이 인스턴스화되기 전에 인스턴스화되는 경우 종속되는 빈 목록을 지정합니다.

createdFromAPI

사용자가 Service.getPort() 와 같은 Apache CXF API를 사용하여 빈이 생성되도록 지정합니다.

기본값은 false입니다.

이 값을 true 로 설정하면 다음이 수행됩니다.

  • .jaxws-client 를 ID에 추가하여 빈의 내부 이름을 변경합니다.
  • 8080을 추상화합니다.

표 17.4. “Cryostat-WS 소비자를 구성하는 데 사용되는 속성” 에 나열된 속성 외에도 여러 xmlns:shortName속성을 사용하여 endpointNameserviceName 속성에 사용되는 네임스페이스를 선언해야 할 수 있습니다.

17.2.3. 기능 추가

기능을 소비자에 추가하거나 고급 구성을 수행하려면 구성에 하위 요소를 추가해야 합니다.

자식 요소는 다음을 수행할 수 있도록 합니다.

표 17.5. “소비자 끝점 구성을 위한 요소” Cryostat-WS 소비자를 구성하는 데 사용할 수 있는 하위 요소에 대해 설명합니다.

Expand
표 17.5. 소비자 끝점 구성을 위한 요소
element설명

jaxws:binding

엔드포인트에서 사용하는 메시지 바인딩을 구성하는 polkit을 지정합니다. 메시지 바인딩은 org.apache.cxf.binding.Binding factory 인터페이스의 구현을 사용하여 구성됩니다.[a]

jaxws:dataBinding

끝점에서 사용하는 데이터 바인딩을 구현하는 클래스를 지정합니다. 포함된 8080 정의를 사용하여 이를 지정합니다. CryostatB 데이터 바인딩을 구현하는 클래스는 org.apache.cxf.jaxb.JAXBDataBinding 입니다.

jaxws:features

Apache CXF의 고급 기능을 구성하는 빈 목록을 지정합니다. Quarkus 참조 목록 또는 포함된 빈 목록을 제공할 수 있습니다.

jaxws:handlers

메시지 처리를 위한 Cryostat-WS Handler 구현 목록을 지정합니다. Cryostat-WS Handler 구현의 자세한 내용은 43장. 처리기 작성 에서 참조하십시오.

jaxws:inInterceptors

인바운드 응답을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:inFaultInterceptors

인바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:outInterceptors

아웃바운드 요청을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:outFaultInterceptors

아웃바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxws:properties

끝점에 전달되는 속성의 맵을 지정합니다.

jaxws:conduitSelector

클라이언트가 사용할 org.apache.cxf.endpoint.ConduitSelector 구현을 지정합니다. ConduitSelector 구현에서는 아웃바운드 요청을 처리하는 데 사용되는 Conduit 개체를 선택하는 데 사용되는 기본 프로세스를 재정의합니다.

[a] Cryostat 바인딩은 soap:soapBinding 8080을 사용하여 구성됩니다.

17.2.4. 예제

예 17.5. “간단한 소비자 구성” 간단한 소비자 구성을 표시합니다.

예 17.5. 간단한 소비자 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:client id="bookClient"
                serviceClass="org.apache.cxf.demo.BookClientImpl"
                address="http://localhost:8080/books"/>
  ...
</beans>
Copy to Clipboard Toggle word wrap

17.2.5. Cryostat-WS 소비자에서 스키마 유효성 검사를 활성화

Cryostat-WS 소비자에서 스키마 검증을 활성화하려면 jaxws:properties 하위 요소에서 schema-validation-enabled 속성을 설정합니다. 예를 들면 다음과 같습니다.

<jaxws:client name="{http://apache.org/hello_world_soap_http}SoapPort"
    createdFromAPI="true">
    <jaxws:properties>
        <entry key="schema-validation-enabled" value="BOTH" />
    </jaxws:properties>
</jaxws:client>
Copy to Clipboard Toggle word wrap

schema-validation-enabled 속성의 허용된 값 목록은 24.3.4.7절. “스키마 유효성 검사 유형 값” 를 참조하십시오.

18장. Cryostat-RS 끝점 구성

초록

이 장에서는 블루프린트 XML 및 Spring XML에서 Cryostat-RS 서버 끝점을 인스턴스화하고 구성하는 방법과 XML에서 Cryostat-RS 클라이언트 끝점(클라이언트 프록시 빈)을 인스턴스화하고 구성하는 방법을 설명합니다.

18.1. Cryostat-RS 서버 끝점 구성

18.1.1. Cryostat-RS 서버 끝점 정의

18.1.1.1. 기본 서버 끝점 정의

XML에서 Cryostat-RS 서버 끝점을 정의하려면 최소한 다음을 지정해야 합니다.

  1. XML로 엔드포인트를 정의하는 데 사용되는 jaxrs:server 요소입니다. jaxrs: namespace 접두사는 블루프린트 및 Spring의 다른 네임스페이스에 각각 매핑됩니다.
  2. jaxrs:server 요소의 address 특성을 사용하여 Cryostat-RS 서비스의 기본 URL입니다. 주소 URL을 지정하는 방법에는 엔드포인트 배포 방식에 영향을 미치는 두 가지 방법이 있습니다.

    • 상대 URL-예: /customers. 이 경우 끝점은 기본 HTTP 컨테이너에 배포되고 엔드포인트의 기본 URL은 CXF 서블릿 기본 URL과 지정된 상대 URL을 결합하여 암시적으로 가져옵니다.

      예를 들어, Fuse 컨테이너에 Cryostat-RS 끝점을 배포하는 경우 지정된 /customers URL이 URL인 http://Hostname:8181/cxf/customers 로 확인됩니다(컨테이너가 기본 8181 포트를 사용 중이라고 가정).

    • 절대 URL로, 예를 들면 http://0.0.0.0:8200/cxf/customers 입니다. 이 경우 Cryostat-RS 엔드포인트(아직 열려 있지 않은 경우)에 대해 새 HTTP 리스너 포트가 열립니다. 예를 들어 Fuse의 컨텍스트에서 새 Cryostat 컨테이너가 암시적으로 생성되어 Cryostat-RS 엔드포인트를 호스팅할 수 있습니다. 특수 IP 주소 0.0.0.0 은 현재 호스트에 할당된 호스트 이름 중 하나와 일치하는 와일드카드 역할을 합니다(multi-homed 호스트 시스템에서 유용할 수 있음).
  3. Cryostat-RS 서비스의 구현을 제공하는 하나 이상의 Cryostat-RS 루트 리소스 클래스입니다. 리소스 클래스를 지정하는 가장 간단한 방법은 jaxrs:serviceBeans 요소 내에 나열하는 것입니다.
18.1.1.2. 블루프린트 예

다음 블루프린트 XML 예제에서는 상대 주소, /customers (기본 HTTP 컨테이너에 배포됨)를 지정하고 service.CustomerService 리소스 클래스에 의해 구현되는 Cryostat-RS 엔드포인트를 정의하는 방법을 보여줍니다.

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
    xmlns:cxf="http://cxf.apache.org/blueprint/core"
    xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
">

    <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus>

     <jaxrs:server id="customerService" address="/customers">
        <jaxrs:serviceBeans>
           <ref component-id="serviceBean" />
        </jaxrs:serviceBeans>
     </jaxrs:server>

     <bean id="serviceBean" class="service.CustomerService"/>
</blueprint>
Copy to Clipboard Toggle word wrap
18.1.1.3. 블루프린트 XML 네임스페이스

블루프린트에 Cryostat-RS 끝점을 정의하려면 일반적으로 다음 XML 네임스페이스가 필요합니다.

18.1.1.4. Spring 예

다음 Spring XML 예제에서는 상대 주소, /customers (기본 HTTP 컨테이너에 배포됨)를 지정하고 service.CustomerService 리소스 클래스에 의해 구현되는 Cryostat-RS 엔드포인트를 정의하는 방법을 보여줍니다.

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxrs="http://cxf.apache.org/jaxrs"
      xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

     <jaxrs:server id="customerService" address="/customers">
        <jaxrs:serviceBeans>
           <ref bean="serviceBean"/>
        </jaxrs:serviceBeans>
     </jaxrs:server>

     <bean id="serviceBean" class="service.CustomerService"/>
</beans>
Copy to Clipboard Toggle word wrap
18.1.1.5. Spring XML 네임스페이스

Spring에서 Cryostat-RS 끝점을 정의하려면 일반적으로 다음 XML 네임스페이스가 필요합니다.

Expand
접두사네임스페이스

(기본값)

http://www.springframework.org/schema/beans

cxf

http://cxf.apache.org/core

jaxrs

http://cxf.apache.org/jaxrs

18.1.1.6. Spring XML 자동 검색

(spring only) 대신 Cryostat-RS 루트 리소스 클래스를 명시적으로 지정하면 Spring XML을 사용하면 자동 검색을 구성할 수 있으므로 특정 Java 패키지가 리소스 클래스( @Path에서 주석 처리됨)를 검색하고 검색된 모든 리소스 클래스가 엔드포인트에 자동으로 연결됩니다. 이 경우 jaxrs:server 요소에서 address 속성 및 basePackages 속성만 지정해야 합니다.

예를 들어 a.b.c Java 패키지 아래에 있는 모든 Cryostat-RS 리소스 클래스를 사용하는 Cryostat-RS 끝점을 정의하려면 다음과 같이 Spring XML에서 끝점을 정의할 수 있습니다.

<jaxrs:server address="/customers" basePackages="a.b.c"/>
Copy to Clipboard Toggle word wrap

자동 검색 메커니즘은 지정된 Java 패키지에서 찾을 수 있는 모든 Cryostat-RS 공급자 클래스를 검색하고 엔드포인트에 설치합니다.

18.1.1.7. Spring XML의 라이프사이클 관리

(spring only) Spring XML을 사용하면 8080 요소에서 scope 특성을 설정하여 의 라이프사이클을 제어할 수 있습니다. 다음 범위 값은 Spring에서 지원합니다.

싱글톤
(기본값) 어디에서나 사용되며 Spring 컨테이너의 전체 수명 동안 지속되는 단일 8080 인스턴스를 만듭니다.
프로토타입
빈이 다른 빈에 삽입될 때마다 또는 8080 레지스트리에서 getBean() 을 호출하여 빈을 가져올 때마다 새 8080 인스턴스를 만듭니다.
request
(웹 인식 컨테이너에서만 사용 가능) 8080에서 호출된 모든 요청에 대해 새 8080 인스턴스를 만듭니다.
세션
(웹 인식 컨테이너에서만 사용 가능) 단일 HTTP 세션의 수명 동안 새 빈을 만듭니다.
globalSession
(웹 인식 컨테이너에서만 사용 가능) 포틀릿 간에 공유되는 단일 HTTP 세션의 수명 동안 새 빈을 만듭니다.

Spring 범위에 대한 자세한 내용은 Cryostat 범위에 대한 Spring 프레임워크 설명서 를 참조하십시오.

jaxrs:serviceBeans 요소를 통해 Cryostat-RS 리소스 빈을 지정하는 경우 Spring 범위가 제대로 작동하지 않습니다. 이 경우 리소스 빈에 scope 속성을 지정하면 scope 속성이 효과적으로 무시됩니다.

Cryostat-RS 서버 엔드포인트 내에서 8080 범위가 제대로 작동하도록 하려면 서비스 팩토리에서 제공하는 간접 수준이 필요합니다. Quarkus 범위를 구성하는 가장 간단한 방법은 다음과 같이 jaxrs:server 요소에서 8080 Names 속성을 사용하여 리소스 빈 을 지정하는 것입니다.

<beans ... >
  <jaxrs:server id="customerService" address="/service1"
    beanNames="customerBean1 customerBean2"/>

  <bean id="customerBean1" class="demo.jaxrs.server.CustomerRootResource1" scope="prototype"/>
  <bean id="customerBean2" class="demo.jaxrs.server.CustomerRootResource2"  scope="prototype"/>
</beans>
Copy to Clipboard Toggle word wrap

위 예제에서 두 개의 리소스 빈, customerBean1customerBean2 를 구성합니다. Cryo statNames 속성은 공백으로 구분된 리소스 8080 ID 목록으로 지정됩니다.

궁극적인 유연성 수준을 위해 jaxrs:serviceFactories 요소를 사용하여 Cryostat-RS 서버 엔드포인트를 구성할 때 서비스 팩토리 오브젝트를 명시적으로 정의할 수 있는 옵션이 있습니다. 이 보다 자세한 접근 방식은 기본 서비스 팩토리 구현을 사용자 지정 구현으로 대체할 수 있다는 장점이 있으므로, Cryostat 라이프사이클을 완벽하게 제어할 수 있습니다. 다음 예제에서는 다음 방법을 사용하여 두 개의 리소스 빈, customerBean1customerBean2 를 구성하는 방법을 보여줍니다.

<beans ... >
  <jaxrs:server id="customerService" address="/service1">
    <jaxrs:serviceFactories>
      <ref bean="sfactory1" />
      <ref bean="sfactory2" />
    </jaxrs:serviceFactories>
  </jaxrs:server>

  <bean id="sfactory1" class="org.apache.cxf.jaxrs.spring.SpringResourceFactory">
     <property name="beanId" value="customerBean1"/>
  </bean>
  <bean id="sfactory2" class="org.apache.cxf.jaxrs.spring.SpringResourceFactory">
     <property name="beanId" value="customerBean2"/>
  </bean>

  <bean id="customerBean1" class="demo.jaxrs.server.CustomerRootResource1" scope="prototype"/>
  <bean id="customerBean2" class="demo.jaxrs.server.CustomerRootResource2"  scope="prototype"/>
</beans>
Copy to Clipboard Toggle word wrap
참고

단일톤이 아닌 라이프사이클을 지정하는 경우 org.apache.cxf.service.Invoker Ignition을 구현하고 등록하는 것이 좋습니다. jaxrs:server/jaxrs:invoker 요소에서 인스턴스를 확인하여 등록할 수 있습니다.

18.1.1.8. WADL 문서 첨부

선택적으로 jaxrs:server 요소에서 docLocation 특성을 사용하여 WADL 문서를 Cryostat-RS 서버 끝점과 연결할 수 있습니다. 예를 들면 다음과 같습니다.

<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl">
   <jaxrs:serviceBeans>
      <bean class="org.bar.generated.BookStore"/>
   </jaxrs:serviceBeans>
</jaxrs:server>
Copy to Clipboard Toggle word wrap
18.1.1.9. 스키마 검증

Cryostat-B 형식의 메시지 콘텐츠를 설명하기 위해 일부 외부 XML 스키마가 있는 경우 jaxrs:schemaLocations 요소를 통해 이러한 외부 스키마를 Cryostat-RS 서버 끝점과 연결할 수 있습니다.

예를 들어 WADL 문서와 서버 끝점을 연결하고 들어오는 메시지에 스키마 유효성 검사를 활성화하려는 경우 다음과 같이 관련 XML 스키마 파일을 지정할 수 있습니다.

<jaxrs:server address="/rest"
              docLocation="wadl/bookStore.wadl">
   <jaxrs:serviceBeans>
     <bean class="org.bar.generated.BookStore"/>
   </jaxrs:serviceBeans>
   <jaxrs:schemaLocations>
     <jaxrs:schemaLocation>classpath:/schemas/a.xsd</jaxrs:schemaLocation>
     <jaxrs:schemaLocation>classpath:/schemas/b.xsd</jaxrs:schemaLocation>
   </jaxrs:schemaLocations>
</jaxrs:server>
Copy to Clipboard Toggle word wrap

또는 지정된 디렉터리에 모든 스키마 파일 *.xsd 를 포함하려는 경우 다음과 같이 디렉터리 이름을 지정할 수 있습니다.

<jaxrs:server address="/rest"
              docLocation="wadl/bookStore.wadl">
   <jaxrs:serviceBeans>
     <bean class="org.bar.generated.BookStore"/>
   </jaxrs:serviceBeans>
   <jaxrs:schemaLocations>
     <jaxrs:schemaLocation>classpath:/schemas/</jaxrs:schemaLocation>
   </jaxrs:schemaLocations>
</jaxrs:server>
Copy to Clipboard Toggle word wrap

이러한 방식으로 스키마를 지정하는 것은 일반적으로 Cryostat-B 스키마에 액세스해야 하는 모든 종류의 기능에 유용합니다.

18.1.1.10. 데이터 바인딩 지정

jaxrs:dataBinding 요소를 사용하여 요청 및 응답 메시지에서 메시지 본문을 인코딩하는 데이터 바인딩을 지정할 수 있습니다. 예를 들어 Cryostat-B 데이터 바인딩을 지정하려면 다음과 같이 Cryostat-RS 끝점을 구성할 수 있습니다.

<jaxrs:server id="jaxbbook" address="/jaxb">
  <jaxrs:serviceBeans>
    <ref bean="serviceBean" />
  </jaxrs:serviceBeans>
  <jaxrs:dataBinding>
    <bean class="org.apache.cxf.jaxb.JAXBDataBinding"/>
  </jaxrs:dataBinding>
</jaxrs:server>>
Copy to Clipboard Toggle word wrap

또는 Aegis 데이터 바인딩을 지정하려면 다음과 같이 Cryostat-RS 끝점을 구성할 수 있습니다.

<jaxrs:server id="aegisbook" address="/aegis">
  <jaxrs:serviceBeans>
    <ref bean="serviceBean" />
  </jaxrs:serviceBeans>
  <jaxrs:dataBinding>
    <bean class="org.apache.cxf.aegis.databinding.AegisDatabinding">
      <property name="aegisContext">
        <bean class="org.apache.cxf.aegis.AegisContext">
          <property name="writeXsiTypes" value="true"/>
        </bean>
      </property>
    </bean>
  </jaxrs:dataBinding>
</jaxrs:server>
Copy to Clipboard Toggle word wrap
18.1.1.11. JMS 전송 사용

HTTP 대신 JMS 메시징 라이브러리를 전송 프로토콜로 사용하도록 Cryostat-RS를 구성할 수 있습니다. JMS 자체는 전송 프로토콜이 아니므로 실제 메시징 프로토콜은 구성하는 특정 JMS 구현에 따라 다릅니다.

예를 들어 다음 Spring XML 예제에서는 JMS 전송 프로토콜을 사용하도록 Cryostat-RS 서버 끝점을 구성하는 방법을 보여줍니다.

<?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:jms="http://cxf.apache.org/transports/jms"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="
http://cxf.apache.org/transports/jms http://cxf.apache.org/schemas/configuration/jms.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
    <bean id="ConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:${testutil.ports.EmbeddedJMSBrokerLauncher}" />
    </bean>

    <jaxrs:server xmlns:s="http://books.com"
    	serviceName="s:BookService"
    	transportId= "http://cxf.apache.org/transports/jms"
    	address="jms:queue:test.jmstransport.text?replyToName=test.jmstransport.response">
        <jaxrs:serviceBeans>
            <bean class="org.apache.cxf.systest.jaxrs.JMSBookStore"/>
        </jaxrs:serviceBeans>
    </jaxrs:server>

</beans>
Copy to Clipboard Toggle word wrap

이전 예에 대해서는 다음 사항에 유의하십시오.

  • JMS 구현- JMS 구현은 Apache ActiveMQ 연결 팩토리 오브젝트를 인스턴스화하는 ConnectionFactory 8080에서 제공합니다. 연결 팩토리를 인스턴스화한 후 기본 JMS 구현 계층으로 자동으로 설치됩니다.
  • JMS 연속 또는 대상 오브젝트-Apache CXF는 JMS 소비자를 나타내는 JMS conduit 오브젝트 또는 JMS 대상 오브젝트( JMS 공급자를 표현하기 위해)를 암시적으로 인스턴스화합니다. 이 오브젝트는 setttings xmlns:s="http://books.com" (네임스 접두사 정의) 및 serviceName="s:keygenService"(QName 정의)를 통해 정의된 QName으로 고유하게 식별해야 합니다.
  • Transport ID-to select the JMS transport, the transportId attribute must be set to http://cxf.apache.org/transports/jms.
  • JMS 주소- jaxrs:server/@address 속성은 표준화된 구문을 사용하여 보낼 JMS 큐 또는 JMS 주제를 지정합니다. 이 구문에 대한 자세한 내용은 https://tools.ietf.org/id/draft-merrick-jms-uri-06.txt 을 참조하십시오.
18.1.1.12. 확장 매핑 및 언어 매핑

Cryostat-RS 서버 끝점은 파일 접미사(URL에 표시되는)를 MIME 콘텐츠 유형 헤더에 자동으로 매핑하고 언어 접미사를 언어 유형 헤더에 매핑하도록 구성할 수 있습니다. 예를 들어 다음 양식의 HTTP 요청을 고려하십시오.

GET /resource.xml
Copy to Clipboard Toggle word wrap

다음과 같이 .xml 접미사를 자동으로 매핑하도록 Cryostat-RS 서버 끝점을 구성할 수 있습니다.

<jaxrs:server id="customerService" address="/">
  <jaxrs:serviceBeans>
    <bean class="org.apache.cxf.jaxrs.systests.CustomerService" />
  </jaxrs:serviceBeans>
  <jaxrs:extensionMappings>
    <entry key="json" value="application/json"/>
    <entry key="xml" value="application/xml"/>
  </jaxrs:extensionMappings>
</jaxrs:server>
Copy to Clipboard Toggle word wrap

이전 서버 끝점에서 HTTP 요청을 수신하면 type, application/xml 의 새 콘텐츠 유형 헤더를 자동으로 생성하고 리소스 URL에서 .xml 접미사를 제거합니다.

언어 매핑의 경우 다음 양식의 HTTP 요청을 고려하십시오.

GET /resource.en
Copy to Clipboard Toggle word wrap

다음과 같이 .en 접미사를 자동으로 매핑하도록 Cryostat-RS 서버 끝점을 구성할 수 있습니다.

<jaxrs:server id="customerService" address="/">
  <jaxrs:serviceBeans>
    <bean class="org.apache.cxf.jaxrs.systests.CustomerService" />
  </jaxrs:serviceBeans>
  <jaxrs:languageMappings>
     <entry key="en" value="en-gb"/>
  </jaxrs:languageMappings>
</jaxrs:server>
Copy to Clipboard Toggle word wrap

이전 서버 끝점에서 HTTP 요청을 수신하면 en-gb.en 접미사를 사용하여 새 수락 언어 헤더를 자동으로 생성하고 리소스 URL에서 .en 접미사를 제거합니다.

18.1.2. jaxrs:server 속성

18.1.2.1. 속성

표 18.1. “Cryostat-RS Server 끝점 속성” jaxrs:server 요소에서 사용할 수 있는 특성에 대해 설명합니다.

Expand
표 18.1. Cryostat-RS Server 끝점 속성
속성설명

id

다른 구성 요소가 끝점을 참조하는 데 사용할 수 있는 고유 식별자를 지정합니다.

address

HTTP 끝점의 주소를 지정합니다. 이 값은 서비스 계약에 지정된 값을 재정의합니다.

basePackages

(아동만 해당) 검색되는 Java 패키지 목록을 쉼표로 구분된 Java 패키지 목록을 지정하여 자동 검색을 활성화합니다. 이 목록은 Cryostat-RS 루트 리소스 클래스 및/또는 Cryostat-RS 공급자 클래스를 검색할 수 있습니다.

beanNames

Cryostat-RS 루트 리소스 빈의 빈으로 구분된 빈 목록을 지정합니다. Spring XML 컨텍스트에서 루트 리소스 빈의 라이프사이클을 정의할 수 있습니다. 루트 리소스 요소의 scope 속성을 설정합니다.

bindingId

서비스에서 사용하는 메시지 바인딩의 ID를 지정합니다. 유효한 바인딩 ID 목록은 23장. Apache CXF 바인딩 ID 에 제공됩니다.

버스

서비스 엔드포인트를 관리하는 데 사용되는 버스를 구성하는 Spring 8080의 ID를 지정합니다. 이는 공통 기능 세트를 사용하도록 여러 끝점을 구성할 때 유용합니다.

docLocation

외부 WADL 문서의 위치를 지정합니다.

modelRef

모델 스키마를 클래스 경로 리소스로 지정합니다(예: 양식 classpath:/path/to/model.xml의 URL). Cryostat-RS 모델 스키마를 정의하는 방법에 대한 자세한 내용은 18.3절. “모델 스키마를 사용하여 REST 서비스 정의” 을 참조하십시오.

publish

서비스를 자동으로 게시해야 하는지 여부를 지정합니다. false 로 설정하면 개발자가 엔드포인트를 명시적으로 게시해야 합니다.

publishedEndpointUrl

자동 생성 WADL 인터페이스의 wadl:resources/@base 속성에 삽입되는 URL 기본 주소를 지정합니다.

serviceAnnotation

(spring only) Spring 에서 자동 검색에 대한 서비스 주석 클래스 이름을 지정합니다. basePackages 속성과 함께 사용할 때 이 옵션은 이 주석 유형으로 주석이 달린 클래스 포함하도록 자동 검색 클래스 컬렉션을 제한합니다. guess! 이 문제가 맞습니까?

serviceClass

Cryostat-RS 루트 리소스 클래스의 이름을 지정합니다 (이는 Cryostat-RS 서비스를 구현합니다). 이 경우 클래스는 블루프린트 또는 Spring이 아닌 Apache CXF에 의해 인스턴스화됩니다. 블루프린트 또는 Spring에서 클래스를 인스턴스화하려면 jaxrs:serviceBeans 하위 요소를 대신 사용합니다.

serviceName

JMS 전송이 사용되는 특수 경우, QName( format ns:name)에 대한 QName 서비스를 지정합니다. 자세한 내용은 “JMS 전송 사용”의 내용을 참조하십시오.

staticSubresourceResolution

true 인 경우 정적 하위 리소스의 동적 해결을 비활성화합니다. 기본값은 false 입니다.

transportId

비표준 전송 계층(HTTP 대신)을 선택합니다. 특히 이 속성을 http://cxf.apache.org/transports/jms 로 설정하여 JMS 전송을 선택할 수 있습니다. 자세한 내용은 “JMS 전송 사용”의 내용을 참조하십시오.

abstract

(spring만 해당) 빈이 추상 빈인지 여부를 지정합니다. 추상 빈은 구체적인 8080 정의에 대해 상위 역할을 하며 인스턴스화되지 않습니다. 기본값은 false입니다. true 로 설정하면 Cryostat 팩토리에서 8080을 인스턴스화하지 않도록 지시합니다.

depends-on

(spring only) 끝점이 인스턴스화되기 전에 끝점이 인스턴스화되는 경우 종속되는 빈 목록을 지정합니다.

18.1.3. jaxrs:server child Cryostat

18.1.3.1. 하위 요소

표 18.2. “Cryostat-RS Server Endpoint Cryostat” jaxrs:server 요소의 하위 요소를 설명합니다.

Expand
표 18.2. Cryostat-RS Server Endpoint Cryostat
element설명

jaxrs:executor

서비스에 사용되는 Java Executor (스레드 풀 구현)를 지정합니다. 포함된 빈 정의를 사용하여 지정됩니다.

jaxrs:features

Apache CXF의 고급 기능을 구성하는 빈 목록을 지정합니다. Quarkus 참조 목록 또는 포함된 빈 목록을 제공할 수 있습니다.

jaxrs:binding

사용되지 않음.

jaxrs:dataBinding

끝점에서 사용하는 데이터 바인딩을 구현하는 클래스를 지정합니다. 포함된 빈 정의를 사용하여 지정됩니다. 자세한 내용은 “데이터 바인딩 지정” 에서 참조하십시오.

jaxrs:inInterceptors

인바운드 요청을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:inFaultInterceptors

인바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:outInterceptors

아웃바운드 응답을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:outFaultInterceptors

아웃바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:invoker

서비스에서 사용하는 org.apache.cxf.service.Invoker 인터페이스의 구현을 지정합니다. [a]

jaxrs:serviceFactories

이 엔드포인트와 연결된 Cryostat-RS 루트 리소스의 라이프사이클에 대한 최대 제어 수준을 제공합니다. 이 요소의 하위 항목( org.apache.cxf.jaxrs.lifecycle.ResourceProvider 유형의 인스턴스여야 함)은 Cryostat-RS 루트 리소스 인스턴스를 만드는 데 사용됩니다.

jaxrs:properties

끝점에 전달되는 속성의 Spring map을 지정합니다. 이러한 속성은 MTOM 지원 활성화와 같은 기능을 제어하는 데 사용할 수 있습니다.

jaxrs:serviceBeans

이 요소의 하위 항목은 요소의 인스턴스 또는 (참조 요소) Cryostat-RS 루트 리소스에 대한 참조입니다. 이 경우 Quarkus 요소에 있는 경우 scope 속성 (Spring only) 이 무시됩니다.

jaxrs:modelBeans

리소스 모델의 기본 요소인 하나 이상의 org.apache.cxf.jaxrs.model.UserResource 빈에 대한 참조 목록으로 구성됩니다(Jax rs:resource 요소에 해당). 자세한 내용은 18.3절. “모델 스키마를 사용하여 REST 서비스 정의”의 내용을 참조하십시오.

jaxrs:model

이 끝점에서 직접 리소스 모델을 정의합니다(즉, 이 jaxrs:model 요소는 하나 이상의 jaxrs:resource 요소를 포함할 수 있음). 자세한 내용은 18.3절. “모델 스키마를 사용하여 REST 서비스 정의”의 내용을 참조하십시오.

jaxrs:providers

이 엔드포인트에 하나 이상의 사용자 지정 Cryostat-RS 공급자를 등록할 수 있습니다. 이 요소의 하위 항목은 요소의 인스턴스 또는 (ref 요소) Cryostat-RS 공급자에 대한 참조입니다.

jaxrs:extensionMappings

REST 호출의 URL이 파일 확장자로 종료되면 이 요소를 사용하여 자동으로 특정 콘텐츠 유형과 연결할 수 있습니다. 예를 들어 .xml 파일 확장자는 application/xml 콘텐츠 유형과 연결할 수 있습니다. 자세한 내용은 “확장 매핑 및 언어 매핑”의 내용을 참조하십시오.

jaxrs:languageMappings

REST 호출의 URL이 언어 접미사로 종료되면 이 요소를 사용하여 특정 언어에 매핑할 수 있습니다. 예를 들어 .en 언어 접미사는 en-GB 언어와 연결할 수 있습니다. 자세한 내용은 “확장 매핑 및 언어 매핑”의 내용을 참조하십시오.

jaxrs:schemaLocations

XML 메시지 내용을 검증하는 데 사용되는 하나 이상의 XML 스키마를 지정합니다. 이 요소는 각각 XML 스키마 파일의 위치(일반적으로 클래스 경로 URL)를 지정하는 하나 이상의 jaxrs:schemaLocation 요소를 포함할 수 있습니다. 자세한 내용은 “스키마 검증”의 내용을 참조하십시오.

jaxrs:resourceComparator

들어오는 URL 경로를 특정 리소스 클래스 또는 메서드에 일치시키는 데 사용되는 알고리즘을 구현하는 사용자 정의 리소스 비교기를 등록할 수 있습니다.

jaxrs:resourceClasses

(blueprint만 해당) 클래스 이름에서 여러 리소스를 생성하려는 경우 jaxrs:server/@serviceClass 속성 대신 사용할 수 있습니다. jaxrs:resourceClasses 의 하위 항목은 name 속성이 리소스 클래스의 이름으로 설정된 class 요소여야 합니다. 이 경우 클래스는 블루프린트 또는 Spring이 아닌 Apache CXF에 의해 인스턴스화됩니다.

[a] Invoker 구현에서는 서비스 호출 방법을 제어합니다. 예를 들어 서비스 구현의 새 인스턴스에서 각 요청을 처리할지 또는 호출 간에 state가 보존되는지 여부를 제어합니다.

18.2. Cryostat-RS 클라이언트 끝점 구성

18.2.1. Cryostat-RS 클라이언트 끝점 정의

18.2.1.1. 클라이언트 프록시 삽입

XML 언어(Blueprint XML 또는 Spring XML)에서 클라이언트 프록시 빈을 인스턴스화하는 주요 지점은 클라이언트 프록시를 사용하여 REST 서비스를 호출할 수 있는 다른 Quarkus에 삽입하는 것입니다. XML에서 클라이언트 프록시 빈을 생성하려면 jaxrs:client 요소를 사용합니다.

18.2.1.2. 네임스페이스

Cryostat-RS 클라이언트 끝점은 서버 끝점과 다른 XML 네임스페이스를 사용하여 정의됩니다. 다음 표에서는 어떤 XML 언어에 사용할 네임스페이스를 보여줍니다.

Expand
XML 언어클라이언트 끝점의 네임스페이스

Blueprint

http://cxf.apache.org/blueprint/jaxrs-client

Spring

http://cxf.apache.org/jaxrs-client

18.2.1.3. 기본 클라이언트 끝점 정의

다음 예제에서는 블루프린트 XML 또는 Spring XML에서 클라이언트 프록시 빈을 생성하는 방법을 보여줍니다.

<jaxrs:client id="restClient"
       address="http://localhost:8080/test/services/rest"
       serviceClass="org.apache.cxf.systest.jaxrs.BookStoreJaxrsJaxws"/>
Copy to Clipboard Toggle word wrap

기본 클라이언트 끝점을 정의하려면 다음 속성을 설정해야 합니다.

id
클라이언트 프록시의 Cryostat ID를 사용하여 클라이언트 프록시를 XML 구성의 다른 빈에 삽입할 수 있습니다.
address
address 속성은 REST 호출의 기본 URL을 지정합니다.
serviceClass
serviceClass 속성은 루트 리소스 클래스( @Path)를 지정하여 REST 서비스에 대한 설명을 제공합니다. 실제로 이는 서버 클래스이지만 클라이언트에서 직접 사용하지는 않습니다. 지정된 클래스는 클라이언트 프록시를 동적으로 구성하는 데 사용되는 메타데이터(Java reflect 및 Cryostat-RS 주석을 통해)에만 사용됩니다.
18.2.1.4. 헤더 지정

다음과 같이 jaxrs:headers 하위 요소를 사용하여 클라이언트 프록시 호출에 HTTP 헤더를 추가할 수 있습니다.

<jaxrs:client id="restClient"
       address="http://localhost:8080/test/services/rest"
       serviceClass="org.apache.cxf.systest.jaxrs.BookStoreJaxrsJaxws"
       inheritHeaders="true">
       <jaxrs:headers>
           <entry key="Accept" value="text/xml"/>
       </jaxrs:headers>
</jaxrs:client>
Copy to Clipboard Toggle word wrap

18.2.2. jaxrs:client 속성

18.2.2.1. 속성

표 18.3. “Cryostat-RS 클라이언트 끝점 속성” jaxrs:client 요소에서 사용할 수 있는 속성을 설명합니다.

Expand
표 18.3. Cryostat-RS 클라이언트 끝점 속성
속성설명

address

소비자가 요청할 끝점의 HTTP 주소를 지정합니다. 이 값은 계약에 설정된 값을 재정의합니다.

bindingId

소비자가 사용하는 메시지 바인딩의 ID를 지정합니다. 유효한 바인딩 ID 목록은 23장. Apache CXF 바인딩 ID 에 제공됩니다.

버스

엔드포인트를 관리하는 버스를 구성하는 Spring 8080의 ID를 지정합니다.

inheritHeaders

이 프록시에서 하위 리소스 프록시를 생성하는 경우 이 프록시에 설정된 헤더를 상속할지 여부를 지정합니다. 기본값은 false 입니다.

사용자 이름

간단한 사용자 이름/암호 인증에 사용되는 사용자 이름을 지정합니다.

암호

간단한 사용자 이름/암호 인증에 사용되는 암호를 지정합니다.

modelRef

모델 스키마를 클래스 경로 리소스로 지정합니다(예: 양식 classpath:/path/to/model.xml의 URL). Cryostat-RS 모델 스키마를 정의하는 방법에 대한 자세한 내용은 18.3절. “모델 스키마를 사용하여 REST 서비스 정의” 을 참조하십시오.

serviceClass

서비스 인터페이스의 이름 또는 @PATH주석이 달린 리소스 클래스를 지정하고 Cryostat-RS 서버 구현에서 다시 사용합니다. 이 경우 지정된 클래스는 직접 호출되지 않습니다 (실제로 서버 클래스임). 지정된 클래스는 클라이언트 프록시를 동적으로 구성하는 데 사용되는 메타데이터(Java reflect 및 Cryostat-RS 주석을 통해)에만 사용됩니다.

serviceName

JMS 전송이 사용되는 특수 경우, QName( format ns:name)에 대한 QName 서비스를 지정합니다. 자세한 내용은 “JMS 전송 사용”의 내용을 참조하십시오.

threadSafe

클라이언트 프록시가 스레드로부터 안전한지 여부를 지정합니다. 기본값은 false 입니다.

transportId

비표준 전송 계층(HTTP 대신)을 선택합니다. 특히 이 속성을 http://cxf.apache.org/transports/jms 로 설정하여 JMS 전송을 선택할 수 있습니다. 자세한 내용은 “JMS 전송 사용”의 내용을 참조하십시오.

abstract

(spring만 해당) 빈이 추상 빈인지 여부를 지정합니다. 추상 빈은 구체적인 8080 정의에 대해 상위 역할을 하며 인스턴스화되지 않습니다. 기본값은 false입니다. true 로 설정하면 Cryostat 팩토리에서 8080을 인스턴스화하지 않도록 지시합니다.

depends-on

(spring only) 끝점이 인스턴스화되기 전에 인스턴스화되는 빈 목록을 지정합니다.

18.2.3. jaxrs:client child Cryostat

18.2.3.1. 하위 요소

표 18.4. “Cryostat-RS 클라이언트 끝점 child Cryostat” jaxrs:client 요소의 하위 요소를 설명합니다.

Expand
표 18.4. Cryostat-RS 클라이언트 끝점 child Cryostat
element설명

jaxrs:executor

 

jaxrs:features

Apache CXF의 고급 기능을 구성하는 빈 목록을 지정합니다. Quarkus 참조 목록 또는 포함된 빈 목록을 제공할 수 있습니다.

jaxrs:binding

사용되지 않음.

jaxrs:dataBinding

끝점에서 사용하는 데이터 바인딩을 구현하는 클래스를 지정합니다. 포함된 빈 정의를 사용하여 지정됩니다. 자세한 내용은 “데이터 바인딩 지정” 에서 참조하십시오.

jaxrs:inInterceptors

인바운드 응답을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:inFaultInterceptors

인바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:outInterceptors

아웃바운드 요청을 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:outFaultInterceptors

아웃바운드 오류 메시지를 처리하는 인터셉터 목록을 지정합니다. 자세한 내용은 VII 부. Apache CXF Interceptors 개발 에서 참조하십시오.

jaxrs:properties

끝점에 전달되는 속성의 맵을 지정합니다.

jaxrs:providers

이 엔드포인트에 하나 이상의 사용자 지정 Cryostat-RS 공급자를 등록할 수 있습니다. 이 요소의 하위 항목은 요소의 인스턴스 또는 (ref 요소) Cryostat-RS 공급자에 대한 참조입니다.

jaxrs:modelBeans

리소스 모델의 기본 요소인 하나 이상의 org.apache.cxf.jaxrs.model.UserResource 빈에 대한 참조 목록으로 구성됩니다(Jax rs:resource 요소에 해당). 자세한 내용은 18.3절. “모델 스키마를 사용하여 REST 서비스 정의”의 내용을 참조하십시오.

jaxrs:model

이 끝점에서 리소스 모델을 직접 정의합니다(즉, jaxrs:model 요소가 하나 이상 포함된 jaxrs:resource 요소). 자세한 내용은 18.3절. “모델 스키마를 사용하여 REST 서비스 정의”의 내용을 참조하십시오.

jaxrs:headers

발신 메시지의 헤더를 설정하는 데 사용됩니다. 자세한 내용은 “헤더 지정”의 내용을 참조하십시오.

jaxrs:schemaLocations

XML 메시지 내용을 검증하는 데 사용되는 하나 이상의 XML 스키마를 지정합니다. 이 요소는 각각 XML 스키마 파일의 위치(일반적으로 클래스 경로 URL)를 지정하는 하나 이상의 jaxrs:schemaLocation 요소를 포함할 수 있습니다. 자세한 내용은 “스키마 검증”의 내용을 참조하십시오.

18.3. 모델 스키마를 사용하여 REST 서비스 정의

18.3.1. 주석이 없는 RESTful 서비스

Cryostat-RS 모델 스키마를 사용하면 Java 클래스에 주석을 달지 않고도 RESTful 서비스를 정의할 수 있습니다. 즉, @Path 매개 변수,@PathParam,@Consumes,@Produces 와 같은 주석을 Java 클래스(또는 인터페이스)에 직접 추가하는 대신 모델 스키마를 사용하여 별도의 XML 파일에 모든 관련 REST 메타데이터를 제공할 수 있습니다. 예를 들어 서비스를 구현하는 Java 소스를 수정할 수 없는 경우 유용합니다.

18.3.2. 모델 스키마 예

예 18.1. “샘플 Cryostat-RS 모델 스키마” BookStoreNoAnnotations 루트 리소스 클래스에 대한 서비스 메타데이터를 정의하는 모델 스키마의 예를 보여줍니다.

예 18.1. 샘플 Cryostat-RS 모델 스키마

<model xmlns="http://cxf.apache.org/jaxrs">
  <resource name="org.apache.cxf.systest.jaxrs.BookStoreNoAnnotations" path="bookstore"
    produces="application/json" consumes="application/json">
    <operation name="getBook" verb="GET" path="/books/{id}" produces="application/xml">
       <param name="id" type="PATH"/>
    </operation>
    <operation name="getBookChapter" path="/books/{id}/chapter">
       <param name="id" type="PATH"/>
    </operation>
    <operation name="updateBook" verb="PUT">
       <param name="book" type="REQUEST_BODY"/>
    </operation>
  </resource>
  <resource name="org.apache.cxf.systest.jaxrs.ChapterNoAnnotations">
    <operation name="getItself" verb="GET"/>
    <operation name="updateChapter" verb="PUT" consumes="application/xml">
        <param name="content" type="REQUEST_BODY"/>
    </operation>
  </resource>
</model>
Copy to Clipboard Toggle word wrap

18.3.3. 네임스페이스

모델 스키마를 정의하는 데 사용하는 XML 네임스페이스는 블루프린트 XML 또는 Spring XML에서 해당 Cryostat-RS 끝점을 정의하는지 여부에 따라 달라집니다. 다음 표에서는 어떤 XML 언어에 사용할 네임스페이스를 보여줍니다.

Expand
XML 언어네임스페이스

Blueprint

http://cxf.apache.org/blueprint/jaxrs

Spring

http://cxf.apache.org/jaxrs

18.3.4. 모델 스키마를 끝점에 연결하는 방법

모델 스키마를 정의하고 끝점에 연결하려면 다음 단계를 수행합니다.

  1. 선택한 삽입 플랫폼에 적절한 XML 네임스페이스(Blueprint XML 또는 Spring XML)를 사용하여 모델 스키마를 정의합니다.
  2. 최종 패키지(JAR, WAR 또는 OSGi 번들 파일)의 classpath에서 스키마 파일을 사용할 수 있도록 프로젝트 리소스에 모델 스키마 파일을 추가합니다.

    참고

    또는 끝점의 jaxrs:model 하위 요소를 사용하여 model 스키마를 직접 Cryostat-RS 엔드포인트에 포함할 수도 있습니다.

  3. 엔드포인트의 modelRef 속성을 클래스 경로의 모델 스키마 위치로 설정하여 모델 스키마를 사용하도록 엔드포인트를 구성합니다(클래스 경로 URL 사용).
  4. 필요한 경우 jaxrs:serviceBeans 요소를 사용하여 루트 리소스를 명시적으로 인스턴스화합니다. 모델 스키마가 기본 인터페이스를 참조하는 대신 루트 리소스 클래스를 직접 참조하는 경우 이 단계를 건너뛸 수 있습니다.

18.3.5. 클래스를 참조하는 모델 스키마 구성

모델 스키마가 루트 리소스 클래스에 직접 적용되는 경우 모델 스키마가 루트 리소스 빈을 자동으로 인스턴스화하므로 jaxrs:serviceBeans 요소를 사용하여 루트 리소스 빈을 정의할 필요가 없습니다.

예를 들어 customer-resources.xml 이 메타데이터를 고객 리소스 클래스와 연결하는 모델 스키마인 경우 다음과 같이 customerService 서비스 끝점을 인스턴스화할 수 있습니다.

<jaxrs:server id="customerService"
              address="/customers"
              modelRef="classpath:/org/example/schemas/customer-resources.xml" />
Copy to Clipboard Toggle word wrap

18.3.6. 인터페이스를 참조하는 모델 스키마 구성

모델 스키마가 Java 인터페이스(루트 리소스의 기본 인터페이스)에 적용되는 경우 엔드포인트에서 jaxrs:serviceBeans 요소를 사용하여 루트 리소스 클래스를 인스턴스화해야 합니다.

예를 들어 customer-interfaces.xml 이 메타데이터를 고객 인터페이스와 연결하는 모델 스키마인 경우 다음과 같이 customerService 서비스 끝점을 인스턴스화할 수 있습니다.

<jaxrs:server id="customerService"
              address="/customers"
              modelRef="classpath:/org/example/schemas/customer-interfaces.xml">
    <jaxrs:serviceBeans>
       <ref component-id="serviceBean" />
    </jaxrs:serviceBeans>
</jaxrs:server>

<bean id="serviceBean" class="service.CustomerService"/>
Copy to Clipboard Toggle word wrap

18.3.7. 모델 스키마 참조

모델 스키마는 다음 XML 요소를 사용하여 정의됩니다.A model schema is defined using the following XML elements:

model
모델 스키마의 루트 요소입니다. 모델 스키마(예: modelRef 특성을 사용하여 Cryostat-RS 끝점에서)를 참조해야 하는 경우 이 요소에 id 특성을 설정해야 합니다.
model/resource

리소스 요소는 메타데이터를 특정 루트 리소스 클래스(또는 해당 인터페이스와 연결)와 연결하는 데 사용됩니다. 리소스 요소에서 다음 특성을 정의할 수 있습니다.

Expand
속성설명 +

name

이 리소스 모델이 적용되는 리소스 클래스(또는 해당 인터페이스)의 이름입니다.

+

path

이 리소스에 매핑되는 REST URL 경로의 구성 요소입니다.

+

사용

이 리소스에서 사용하는 콘텐츠 유형(예: application/xml 또는 application/json )을 지정합니다.

+

생성

이 리소스에서 생성하는 콘텐츠 유형(예: application/xml 또는 application/json )을 지정합니다.

+

model/resource/operation

작업 요소는 메타데이터를 Java 메서드와 연결하는 데 사용됩니다. 작업 요소에서 다음 특성을 정의할 수 있습니다.

Expand
속성설명 +

name

이 요소가 적용되는 Java 메서드의 이름입니다.

+

path

이 메서드에 매핑되는 REST URL 경로의 구성 요소입니다. 이 속성 값에는 매개변수 참조가 포함될 수 있습니다(예: path="/books/{id}/chapter "). 여기서 {id} 는 경로에서 id 매개변수 값을 추출합니다.

+

verb

이 메서드에 매핑되는 HTTP 동사를 지정합니다. 일반적으로 GET,POST,PUT 또는 DELETE 중 하나입니다. HTTP 동사를 지정하지 않으면 Java 메서드가 하위 리소스 오브젝트에 대한 참조를 반환하는 하위 리소스 locater 라고 가정합니다(리소스 요소를 사용하여 하위 리소스 클래스도 제공되어야 함).

+

사용

이 작업에서 사용하는 콘텐츠 유형(예: application/xml 또는 application/json )을 지정합니다.

+

생성

이 작업에서 생성한 콘텐츠 유형(예: application/xml 또는 application/json )을 지정합니다.

+

OneWay

true 인 경우 작업을 단방향 으로 구성합니다. 즉, 응답 메시지가 필요하지 않음을 의미합니다. 기본값은 false입니다.

+

model/resource/operation/param

param 요소는 REST URL에서 값을 추출하여 메서드 매개변수 중 하나에 삽입합니다. param 요소에서 다음 속성을 정의할 수 있습니다.

Expand
속성설명 +

name

이 요소가 적용되는 Java 메서드 매개 변수의 이름입니다.

+

type

REST URL 또는 메시지에서 매개변수 값을 추출하는 방법을 지정합니다. PATH,QUERY,MATRIX,HEADER,COOKIE,FORM,CONTEXT,REQUEST_BODY 값 중 하나로 설정할 수 있습니다.

+

defaultValue

REST URL 또는 메시지에서 값을 추출할 수 없는 경우 매개 변수에 삽입할 기본값입니다.

+

인코딩된

true 인 경우 매개변수 값은 URI 인코딩 양식(즉, %nn 인코딩 사용)에 삽입됩니다. 기본값은 false 입니다. 예를 들어, URL 경로에서 매개 변수를 추출하는 경우 인코딩된 설정이 true 로 설정된 /name/ Joe%20Bloggs 가 있는 매개변수는 Cryostat%20Bloggs로 삽입됩니다. 그렇지 않으면 매개변수가 bloggs로 삽입됩니다.

+

19장. Apache CXF Logging

초록

이 장에서는 Apache CXF 런타임에서 로깅을 구성하는 방법을 설명합니다.

19.1. Apache CXF Logging 개요

19.1.1. 개요

Apache CXF는 Java 로깅 유틸리티인 java.util.logging 을 사용합니다. 로깅은 표준 java.util.Properties 형식을 사용하여 작성된 로깅 구성 파일로 구성됩니다. 애플리케이션에서 로깅을 실행하려면 프로그래밍 방식으로 로깅을 지정하거나 애플리케이션을 시작할 때 로깅 구성 파일을 가리키는 명령에서 속성을 정의하여 지정할 수 있습니다.

19.1.2. 기본 속성 파일

Apache CXF에는 InstallDir/etc 디렉터리에 있는 기본 logging.properties 파일이 포함되어 있습니다. 이 파일은 로그 메시지의 출력 대상과 게시된 메시지 수준을 모두 구성합니다. 기본 구성은 WARNING 수준이 있는 메시지를 콘솔에 출력하도록 로거를 설정합니다. 구성 설정을 변경하지 않고 기본 파일을 사용하거나 특정 애플리케이션에 맞게 구성 설정을 변경할 수 있습니다.

19.1.3. 로깅 기능

Apache CXF에는 로깅을 활성화하기 위해 클라이언트 또는 서비스에 연결할 수 있는 로깅 기능이 포함되어 있습니다. 예 19.1. “로깅 활성화 구성” 로깅 기능을 활성화하는 구성을 표시합니다.

예 19.1. 로깅 활성화 구성

<jaxws:endpoint...>
  <jaxws:features>
    <bean class="org.apache.cxf.feature.LoggingFeature"/>
  </jaxws:features>
</jaxws:endpoint>
Copy to Clipboard Toggle word wrap

자세한 내용은 19.6절. “로깅 메시지 콘텐츠”의 내용을 참조하십시오.

19.1.4. 어디에서 시작해야합니까?

간단한 로깅 예제를 실행하려면 19.2절. “로깅 사용의 간단한 예” 에 설명된 지침을 따르십시오.

Apache CXF에서 로깅 작동 방식에 대한 자세한 내용은 전체 장을 참조하십시오.

19.1.5. java.util.logging에 대한 자세한 정보

java.util.logging 유틸리티는 가장 널리 사용되는 Java 로깅 프레임워크 중 하나입니다. 이 프레임워크를 사용하고 확장하는 방법을 설명하는 온라인에서 사용할 수 있는 많은 정보가 있습니다. 그러나 시작점으로 다음 문서는 java.util.logging 에 대한 좋은 개요를 제공합니다.

19.2. 로깅 사용의 간단한 예

19.2.1. 로그 수준 및 출력 대상 변경

wsdl_first 샘플 애플리케이션에서 로그 메시지의 로그 수준 및 출력 대상을 변경하려면 다음 단계를 완료합니다.

  1. InstallDir/samples/wsdl_first 디렉터리에 있는 README.txt 파일의 java 섹션을 사용하여 데모 실행에 설명된 샘플 서버를 실행합니다. server start 명령은 다음과 같이 기본 logging.properties 파일을 지정합니다.

    Expand
    플랫폼명령 +

    Windows

    java -Djava.util.logging.config.file=%CXF_HOME%\etc\logging.properties demo.hw.server.Server를 시작합니다.

    +

    UNIX

    Java -Djava.util.logging.config.file=$CXF_HOME/etc/logging.properties demo.hw.server.Server &

    +

    기본 logging.properties 파일은 InstallDir/etc 디렉터리에 있습니다. 경고 수준 로그 메시지를 콘솔에 출력하도록 Apache CXF 로거를 구성합니다. 결과적으로 콘솔에 인쇄가 거의 표시되지 않습니다.

  2. README.txt 파일에 설명된 대로 서버를 중지합니다.
  3. 기본 logging.properties 파일의 복사본을 만들고 이름을 mylogging.properties 파일로 지정하고 기본 logging.properties 파일과 동일한 디렉터리에 저장합니다.
  4. 다음 구성 행을 편집하여 mylogging.properties 파일의 글로벌 로깅 수준 및 콘솔 로깅 수준을 INFO 로 변경합니다.

    .level= INFO
    java.util.logging.ConsoleHandler.level = INFO
    Copy to Clipboard Toggle word wrap
  5. 다음 명령을 사용하여 서버를 다시 시작하십시오.

    Expand
    플랫폼명령 +

    Windows

    java -Djava.util.logging.config.file=%CXF_HOME%\etc\mylogging.properties demo.hw.server.Server를 시작합니다.

    +

    UNIX

    Java -Djava.util.logging.config.file=$CXF_HOME/etc/mylogging.properties demo.hw.server.Server &

    +

    수준 INFO 의 메시지를 기록하도록 글로벌 로깅 및 콘솔 로거를 구성했기 때문에 콘솔에 더 많은 로그 메시지가 출력됩니다.

19.3. 기본 로깅 구성 파일

19.3.1. 로깅 구성 개요

기본 로깅 구성 파일 logging.propertiesInstallDir/etc 디렉터리에 있습니다. 경고 수준 메시지를 콘솔에 출력하도록 Apache CXF 로거를 구성합니다. 이 수준의 로깅이 애플리케이션에 적합한 경우 사용하기 전에 파일을 변경할 필요가 없습니다. 그러나 로그 메시지에서 세부 수준을 변경할 수 있습니다. 예를 들어 로그 메시지가 콘솔로 전송되는지 파일 또는 둘 다로 변경할 수 있습니다. 또한 개별 패키지 수준에서 로깅을 지정할 수 있습니다.

참고

이 섹션에서는 기본 logging.properties 파일에 표시되는 구성 속성에 대해 설명합니다. 그러나 설정할 수 있는 다른 많은 java.util.logging 구성 속성이 있습니다. java.util.logging API에 대한 자세한 내용은 java.util.logging javadoc ( http://download.oracle.com/javase/1.5/docs/api/java/util/logging/package-summary.html 참조하십시오.

19.3.2. 로깅 출력 구성

19.3.2.1. 개요

Java 로깅 유틸리티인 java.util.logging 은 처리기 클래스를 사용하여 로그 메시지를 출력합니다. 표 19.1. “java.util.logging 핸들러 클래스” 기본 logging.properties 파일에 구성된 처리기를 표시합니다.

Expand
표 19.1. java.util.logging 핸들러 클래스
처리기 클래스출력 대상

ConsoleHandler

콘솔에 로그 메시지를 출력

FileHandler

로그 메시지를 파일에 출력

중요

시작 시 Java VM에서 설치하려면 처리기 클래스가 시스템 classpath에 있어야 합니다. 이 작업은 Apache CXF 환경을 설정할 때 수행됩니다.

19.3.2.2. 콘솔 처리기 구성

예 19.2. “콘솔 처리기 구성” 콘솔 로거를 구성하는 코드를 보여줍니다.

예 19.2. 콘솔 처리기 구성

handlers= java.util.logging.ConsoleHandler
Copy to Clipboard Toggle word wrap

콘솔 처리기는 예 19.3. “콘솔 처리기 속성” 에 표시된 구성 속성도 지원합니다.

예 19.3. 콘솔 처리기 속성

java.util.logging.ConsoleHandler.level = WARNING
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
Copy to Clipboard Toggle word wrap

예 19.3. “콘솔 처리기 속성” 에 표시된 구성 속성은 다음과 같이 설명할 수 있습니다.

콘솔 처리기는 별도의 로그 수준 구성 속성을 지원합니다. 이를 통해 글로벌 로깅 설정이 다를 수 있는 동안 콘솔에 인쇄된 로그 메시지를 제한할 수 있습니다( 19.3.3절. “로깅 수준 구성”참조). 기본 설정은 WARNING 입니다.

콘솔 처리기 클래스에서 로그 메시지를 포맷하는 데 사용하는 java.util.logging 포맷터 클래스를 지정합니다. 기본 설정은 java.util.logging.SimpleFormatter 입니다.

19.3.2.3. 파일 처리기 구성

예 19.4. “파일 처리기 구성” 파일 처리기를 구성하는 코드를 표시합니다.

예 19.4. 파일 처리기 구성

handlers= java.util.logging.FileHandler
Copy to Clipboard Toggle word wrap

파일 처리기는 예 19.5. “파일 핸들러 구성 속성” 에 표시된 구성 속성도 지원합니다.

예 19.5. 파일 핸들러 구성 속성

java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
Copy to Clipboard Toggle word wrap

예 19.5. “파일 핸들러 구성 속성” 에 표시된 구성 속성은 다음과 같이 설명할 수 있습니다.

출력 파일의 위치와 패턴을 지정합니다. 기본 설정은 홈 디렉터리입니다.

로거가 하나의 파일에 쓰는 최대 양을 바이트 단위로 지정합니다. 기본 설정은 50000 입니다. 0으로 설정하면 로거가 하나의 파일에 쓰는 양에 제한이 없습니다.

순환할 출력 파일 수를 지정합니다. 기본 설정은 1 입니다.

파일 처리기 클래스에서 로그 메시지를 포맷하는 데 사용하는 java.util.logging 포맷터 클래스를 지정합니다. 기본 설정은 java.util.logging.19Formatter 입니다.

19.3.2.4. 콘솔 처리기와 파일 처리기를 둘 다 구성

콘솔 로깅 및 파일 구성 에 표시된 대로 콘솔 처리기와 파일 처리기를 쉼표로 지정하여 로그 메시지를 콘솔 및 파일에 출력하도록 로깅 유틸리티를 설정할 수 있습니다.

콘솔 로깅 및 파일 구성

Logging
Copy to Clipboard Toggle word wrap

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
Copy to Clipboard Toggle word wrap

19.3.3. 로깅 수준 구성

19.3.3.1. 로깅 수준

java.util.logging 프레임워크는 가장 자세한 정보 표시까지 다음과 같은 수준의 로깅을 지원합니다.

  • 심각
  • 경고
  • INFO
  • CONFIG
  • OK
  • FINER
  • BESTST
19.3.3.2. 글로벌 로깅 수준 구성

모든 로거에 로깅되는 이벤트 유형을 구성하려면 예 19.6. “글로벌 로깅 수준 구성” 에 표시된 대로 글로벌 로깅 수준을 구성합니다.

예 19.6. 글로벌 로깅 수준 구성

.level= WARNING
Copy to Clipboard Toggle word wrap
19.3.3.3. 개별 패키지에서 로깅 구성
level
Copy to Clipboard Toggle word wrap

java.util.logging 프레임워크는 개별 패키지 수준에서 로깅 구성을 지원합니다. 예를 들어 예 19.7. “패키지 수준에서 로깅 구성” 에 표시된 코드 줄은 com.xyz.foo 패키지의 클래스에서 SEVERE 수준에서 로깅을 구성합니다.

예 19.7. 패키지 수준에서 로깅 구성

com.xyz.foo.level = SEVERE
Copy to Clipboard Toggle word wrap

19.4. 명령줄에서 로깅 활성화

19.4.1. 개요

애플리케이션을 시작할 때 java.util.logging.config.file 속성을 정의하여 애플리케이션에서 로깅 유틸리티를 실행할 수 있습니다. 기본 logging.properties 파일 또는 해당 애플리케이션에 고유한 logging.properties 파일을 지정할 수 있습니다.

19.4.2. 애플리케이션에 로그 구성 파일 지정

start-up
Copy to Clipboard Toggle word wrap

애플리케이션 시작 시 로깅을 지정하려면 예 19.8. “명령줄에서 로깅을 시작하는 플래그” 에 애플리케이션을 시작할 때 표시된 플래그를 추가합니다.

예 19.8. 명령줄에서 로깅을 시작하는 플래그

-Djava.util.logging.config.file=myfile
Copy to Clipboard Toggle word wrap

19.5. Cryostat 및 서비스에 대한 로깅

19.5.1. 개요

“개별 패키지에서 로깅 구성” 에 설명된 com.xyz.foo.level 구성 속성을 사용하여 지정된 Apache CXF 로깅 하위 시스템에 대해 세분화된 로깅을 설정할 수 있습니다.

19.5.2. Apache CXF 로깅 하위 시스템

표 19.2. “Apache CXF Logging Cryostats” 사용 가능한 Apache CXF 로깅 하위 시스템 목록을 표시합니다.

Expand
표 19.2. Apache CXF Logging Cryostats
하위 시스템설명

org.apache.cxf.aegis

Aegis 바인딩

org.apache.cxf.binding.coloc

배치된 바인딩

org.apache.cxf.binding.http

HTTP 바인딩

org.apache.cxf.binding.jbi

JBI 바인딩

org.apache.cxf.binding.object

Java 오브젝트 바인딩

org.apache.cxf.binding.soap

Cryostat 바인딩

org.apache.cxf.binding.xml

XML 바인딩

org.apache.cxf.bus

Apache CXF 버스

org.apache.cxf.configuration

구성 프레임워크

org.apache.cxf.endpoint

서버 및 클라이언트 끝점

org.apache.cxf.interceptor

인터셉터

org.apache.cxf.jaxws

Cryostat-WS 스타일 메시지 교환, Cryostat-WS 처리기 처리, Cryostat-WS 및 구성과 관련된 인터셉터의 프런트 엔드

org.apache.cxf.jbi

JBI 컨테이너 통합 클래스

org.apache.cxf.jca

JCA 컨테이너 통합 클래스

org.apache.cxf.js

JavaScript 프론트 엔드

org.apache.cxf.transport.http

HTTP 전송

org.apache.cxf.transport.https

HTTPS를 사용하여 HTTP 전송의 보안 버전

org.apache.cxf.transport.jbi

JBI 전송

org.apache.cxf.transport.jms

JMS 전송

org.apache.cxf.transport.local

로컬 파일 시스템을 사용한 전송 구현

org.apache.cxf.transport.servlet

STS-WS 끝점을 서블릿 컨테이너로 로드하기 위한 HTTP 전송 및 서블릿 구현

org.apache.cxf.ws.addressing

WS-Addressing 구현

org.apache.cxf.ws.policy

WS-Policy 구현

org.apache.cxf.ws.rm

WS-ReliableMessaging(WS-RM) 구현

org.apache.cxf.ws.security.wss4j

WSS4J 보안 구현

19.5.3. 예제

WS-Addressing 샘플은 InstallDir/samples/ws_addressing 디렉터리에 포함되어 있습니다. 로깅은 해당 디렉터리에 있는 logging.properties 파일에 구성됩니다. 관련 구성 행은 예 19.9. “WS-Addressing에 대한 로깅 구성” 에 표시됩니다.

예 19.9. WS-Addressing에 대한 로깅 구성

java.util.logging.ConsoleHandler.formatter = demos.ws_addressing.common.ConciseFormatter
...
org.apache.cxf.ws.addressing.soap.MAPCodec.level = INFO
Copy to Clipboard Toggle word wrap

예 19.9. “WS-Addressing에 대한 로깅 구성” 의 구성을 사용하면 WS-Addressing 헤더와 관련된 로그 메시지를 스누핑하고 간결한 형식으로 콘솔에 표시합니다.

이 샘플을 실행하는 방법에 대한 자세한 내용은 InstallDir/samples/ws_addressing 디렉터리에 있는 README.txt 파일을 참조하십시오.

19.6. 로깅 메시지 콘텐츠

19.6.1. 개요

서비스와 소비자 간에 전송되는 메시지의 콘텐츠를 기록할 수 있습니다. 예를 들어 서비스와 소비자 간에 전송되는 Cryostat 메시지의 내용을 로깅할 수 있습니다.

19.6.2. 메시지 콘텐츠 로깅 구성

서비스와 소비자 간에 전송되는 메시지를 기록하려면 그 반대의 경우 다음 단계를 완료하십시오.

19.6.3. 끝점에 로깅 기능 추가

예 19.10. “끝점 구성에 로깅 추가” 에 표시된 대로 끝점 구성에 로깅 기능을 추가합니다.

예 19.10. 끝점 구성에 로깅 추가

<jaxws:endpoint ...>
  <jaxws:features>
    <bean class="org.apache.cxf.feature.LoggingFeature"/>
  </jaxws:features>
</jaxws:endpoint>
Copy to Clipboard Toggle word wrap

예 19.10. “끝점 구성에 로깅 추가” 에 표시된 XML 예제에서는 Cryostat 메시지를 로깅할 수 있습니다.

19.6.4. 소비자에 로깅 기능 추가

예 19.11. “클라이언트 구성에 로깅 추가” 에 표시된 대로 클라이언트 구성에 로깅 기능을 추가합니다.

예 19.11. 클라이언트 구성에 로깅 추가

<jaxws:client ...>
   <jaxws:features>
      <bean class="org.apache.cxf.feature.LoggingFeature"/>
    </jaxws:features>
</jaxws:client>
Copy to Clipboard Toggle word wrap

예 19.11. “클라이언트 구성에 로깅 추가” 에 표시된 XML 예제에서는 Cryostat 메시지를 로깅할 수 있습니다.

19.6.5. logging을 log INFO 수준 메시지로 설정

예 19.12. “로깅 수준 정보를 INFO로 설정” 에 표시된 대로 서비스와 연결된 logging.properties 파일이 INFO 수준 메시지를 기록하도록 구성되어 있는지 확인합니다.

예 19.12. 로깅 수준 정보를 INFO로 설정

.level= INFO
java.util.logging.ConsoleHandler.level = INFO
Copy to Clipboard Toggle word wrap

19.6.6. Envoy 메시지 로깅

Cryostat 메시지의 로깅을 보려면 다음과 같이 InstallDir/samples/wsdl_first 디렉터리에 있는 wsdl_first 샘플 애플리케이션이 수정됩니다.

  1. 예 19.13. “로깅 Cryostat 메시지에 대한 끝점 구성” 에 표시된 jaxws:features 요소를 wsdl_first 샘플의 디렉터리에 있는 cxf.xml 구성 파일에 추가합니다.

    예 19.13. 로깅 Cryostat 메시지에 대한 끝점 구성

    <jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
                    createdFromAPI="true">
      <jaxws:properties>
        <entry key="schema-validation-enabled" value="true" />
      </jaxws:properties>
      <jaxws:features>
        <bean class="org.apache.cxf.feature.LoggingFeature"/>
      </jaxws:features>
    </jaxws:endpoint>
    Copy to Clipboard Toggle word wrap
  2. 샘플은 InstallDir/etc 디렉터리에 있는 기본 logging.properties 파일을 사용합니다. 이 파일의 복사본을 만들고 이름을 mylogging.properties 로 지정합니다.
  3. mylogging.properties 파일에서 다음과 같이 .leveljava.util.logging.ConsoleHandler.level 구성 속성을 편집하여 로깅 수준을 INFO 로 변경합니다.

    .level= INFO
    java.util.logging.ConsoleHandler.level = INFO
    Copy to Clipboard Toggle word wrap
  4. 다음과 같이 cxf.xml 파일과 mylogging.properties 파일에서 새 구성 설정을 사용하여 서버를 시작합니다.

    Expand
    플랫폼명령 +

    Windows

    java -Djava.util.logging.config.file=%CXF_HOME%\etc\mylogging.properties demo.hw.server.Server를 시작합니다.

    +

    UNIX

    Java -Djava.util.logging.config.file=$CXF_HOME/etc/mylogging.properties demo.hw.server.Server &

    +

  5. 다음 명령을 사용하여 hello world 클라이언트를 시작합니다.

    Expand
    플랫폼명령 +

    Windows

    Java -Djava.util.logging.config.file=%CXF_HOME%\etc\mylogging.properties demo.hw.client.Client .\wdl\hello_world.wsdl

    +

    UNIX

    Java -Djava.util.logging.config.file=$CXF_HOME/etc/mylogging.properties demo.hw.client.Client ./wsdl/hello_world.wsdl

    +

Cryostat 메시지는 콘솔에 기록됩니다.

20장. WS-Addressing 배포

초록

Apache CXF는 Cryostat-WS 애플리케이션을 위한 WS-Addressing을 지원합니다. 이 장에서는 Apache CXF 런타임 환경에서 WS-Addressing을 배포하는 방법을 설명합니다.

20.1. WS-Addressing 소개

20.1.1. 개요

WS-Addressing은 서비스가 전송 중 중립 방식으로 주소 지정 정보를 통신할 수 있도록 하는 사양입니다. 다음 두 부분으로 구성됩니다.

  • 웹 서비스 끝점에 대한 참조를 전달하기 위한 구조
  • 주소 지정 정보를 특정 메시지와 연결하는 MAP(메시지 주소 지정 속성) 세트

20.1.2. 지원되는 사양

Apache CXF는 WS-Addressing 2004/08 사양과 WS-Addressing 2005/03 사양을 모두 지원합니다.

20.1.3. 추가 정보

WS-Addressing에 대한 자세한 내용은 http://www.w3.org/Submission/ws-addressing/ 에서 2004/08 제출을 참조하십시오.

20.2. WS-Addressing Interceptors

20.2.1. 개요

Apache CXF에서 WS-Addressing 기능은 인터셉터로 구현됩니다. Apache CXF 런타임은 인터셉터를 사용하여 전송 및 수신 중인 원시 메시지를 가로채고 사용합니다. 전송이 메시지를 수신하면 메시지 개체를 생성하고 인터셉터 체인을 통해 해당 메시지를 보냅니다. WS-Addressing interceptors가 애플리케이션의 인터셉터 체인에 추가되면 메시지에 포함된 모든 WS-Addressing 정보가 처리됩니다.

20.2.2. WS-Addressing Interceptors

WS-Addressing 구현은 표 20.1. “WS-Addressing Interceptors” 에 설명된 대로 두 개의 인터셉터로 구성됩니다.

Expand
표 20.1. WS-Addressing Interceptors
인터셉터설명

org.apache.cxf.ws.addressing.MAPAggregator

발신 메시지에 대한 메시지 주소 속성(MAP)을 집계하는 논리 인터셉터입니다.

org.apache.cxf.ws.addressing.soap.MAPCodec

SMTP(Message Addressing Properties)의 인코딩 및 디코딩을 담당하는 프로토콜별 인터셉터입니다.

20.3. WS-Addressing 활성화

20.3.1. 개요

WS-Addressing 인터셉터를 사용하려면 인바운드 및 아웃바운드 인터셉터 체인에 추가해야 합니다. 이 작업은 다음 방법 중 하나로 수행됩니다.

  • Apache CXF 기능
  • RMAssertion 및 WS-Policy Framework
  • WS-Addressing Feature에서 Policy Assertion 사용

20.3.2. WS-Addressing을 기능으로 추가

WS-Addressing은 각각 예 20.1. “client.xml 및 클라이언트 구성에 WS-Addressing 기능 추가”예 20.2. “server.xml 및 서버 구성에 WS-Addressing 기능 추가” 에 표시된 대로 WS-Addressing 기능을 클라이언트 및 서버 구성에 추가하여 활성화할 수 있습니다.

예 20.1. client.xml 및 클라이언트 구성에 WS-Addressing 기능 추가

<?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"
       xmlns:wsa="http://cxf.apache.org/ws/addressing"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://cxf.apache.org/ws/addressing
          http://cxf.apache.org/schemas/ws-addr-conf.xsd">

    <jaxws:client ...>
        <jaxws:features>
            <wsa:addressing/>
        </jaxws:features>
    </jaxws:client>
</beans>
Copy to Clipboard Toggle word wrap

예 20.2. server.xml 및 서버 구성에 WS-Addressing 기능 추가

<?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"
       xmlns:wsa="http://cxf.apache.org/ws/addressing"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <jaxws:endpoint ...>
        <jaxws:features>
            <wsa:addressing/>
        </jaxws:features>
    </jaxws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap

20.4. WS-Addressing 속성 구성

20.4.1. 개요

Apache CXF WS-Addressing 기능 요소는 네임스페이스 http://cxf.apache.org/ws/addressing 에 정의되어 있습니다. 표 20.2. “WS-Addressing 특성” 에 설명된 두 가지 속성을 지원합니다.

Expand
표 20.2. WS-Addressing 특성
특성 이름현재의

allowDuplicates

중복된 MessageID가 허용되는지 여부를 결정하는 부울입니다. 기본 설정은 true 입니다.

usingAddressingAdvisory

WSDL에 UsingAddressing 요소의 존재가 권고인지 여부를 나타내는 부울입니다. 즉, WS-Addressing 헤더의 인코딩이 수행되지 않습니다.

20.4.2. WS-Addressing 특성 구성

특성과 값을 서버 또는 클라이언트 구성 파일의 WS-Addressing 기능으로 설정하여 WS-Addressing 특성을 구성합니다. 예를 들어 다음 구성 추출에서는 서버 끝점에서 allowDuplicates 속성을 false 로 설정합니다.

<beans ... xmlns:wsa="http://cxf.apache.org/ws/addressing" ...>
    <jaxws:endpoint ...>
        <jaxws:features>
            <wsa:addressing allowDuplicates="false"/>
        </jaxws:features>
    </jaxws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap

20.4.3. 기능에 포함된 WS-Policy 어설션 사용

예 20.3. “정책을 사용하여 WS-Addressing 구성” 에서 비익명 응답을 활성화하기 위한 주소 지정 정책 어설션이 정책 요소에 포함됩니다.

예 20.3. 정책을 사용하여 WS-Addressing 구성

<?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:wsa="http://cxf.apache.org/ws/addressing"
        xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
        xmlns:policy="http://cxf.apache.org/policy-config"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
http://www.w3.org/2006/07/ws-policy http://www.w3.org/2006/07/ws-policy.xsd
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schema/ws/addressing.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <jaxws:endpoint name="{http://cxf.apache.org/greeter_control}GreeterPort"
                    createdFromAPI="true">
        <jaxws:features>
            <policy:policies>
                <wsp:Policy xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                    <wsam:Addressing>
                        <wsp:Policy>
                            <wsam:NonAnonymousResponses/>
                        </wsp:Policy>
                    </wsam:Addressing>
                </wsp:Policy>
            <policy:policies>
        </jaxws:features>
    </jaxws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap

21장. 신뢰할 수 있는 메시징 활성화

초록

Apache CXF는 WS-RM(WS-Reliable Messaging)을 지원합니다. 이 장에서는 Apache CXF에서 WS-RM을 활성화하고 구성하는 방법을 설명합니다.

21.1. WS-RM 소개

21.1.1. 개요

WS-ReliableMessaging(WS-RM)은 분산 환경에서 메시지를 안정적으로 전달하는 프로토콜입니다. 이를 통해 소프트웨어, 시스템 또는 네트워크 장애에 있는 분산 애플리케이션 간에 메시지를 안정적으로 전달할 수 있습니다.

예를 들어 WS-RM을 사용하면 올바른 메시지가 네트워크 간에 정확히 한 번, 올바른 순서로 전달되도록 할 수 있습니다.

21.1.2. WS-RM 작동 방식

WS-RM은 소스와 대상 끝점 간의 메시지를 안정적으로 전달할 수 있도록 합니다. 소스는 메시지의 초기 발신자이며 대상은 그림 21.1. “웹 서비스 신뢰할 수 있는 메시징” 에 표시된 대로 최종 수신자입니다.

그림 21.1. 웹 서비스 신뢰할 수 있는 메시징

신뢰할 수 있는 메시지 교환

WS-RM 메시지의 흐름은 다음과 같이 설명될 수 있습니다.

  1. RM 소스는 CreateSequence 프로토콜 메시지를 RM 대상에 보냅니다. 여기에는 승인을 수신하는 끝점에 대한 참조가 포함됩니다( wsrm:AcksTo 끝점).
  2. RM 대상은 CreateSequenceResponse 프로토콜 메시지를 RM 소스로 다시 보냅니다. 이 메시지에는 RM 시퀀스 세션의 시퀀스 ID가 포함되어 있습니다.
  3. RM 소스는 애플리케이션 소스에서 보낸 각 메시지에 RM 시퀀스 헤더를 추가합니다. 이 헤더에는 시퀀스 ID와 고유한 메시지 ID가 포함됩니다.
  4. RM 소스는 각 메시지를 RM 대상으로 전송합니다.
  5. RM 대상은 RM SequenceAcknowledgement 헤더가 포함된 메시지를 전송하여 RM 소스에서 메시지를 수신함을 확인합니다.
  6. RM 대상은 정확히once-in-order 방식으로 애플리케이션 대상에 메시지를 전달합니다.
  7. RM 소스는 아직 승인을 받지 못했음을 메시지를 다시 전송합니다.

    첫 번째 재전송 시도는 기본 재전송 간격 후에 수행됩니다. 기본적으로 지수 백오프 간격 또는 고정 간격으로 연속 재전송 시도가 수행됩니다. 자세한 내용은 21.5절. “WS-RM 구성” 에서 참조하십시오.

이 전체 프로세스는 요청과 응답 메시지 모두에 대해 대칭적으로 발생합니다. 즉, 응답 메시지의 경우 서버는 RM 소스 역할을 하며 클라이언트는 RM 대상 역할을 합니다.

21.1.3. WS-RM 전달 보장

WS-RM은 사용된 전송 프로토콜에 관계없이 분산 환경에서 안정적인 메시지 전달을 보장합니다. 안정적인 전달이 보장되지 않는 경우 소스 또는 대상 끝점에서 오류를 기록합니다.

21.1.4. 지원되는 사양

Apache CXF는 다음 버전의 WS-RM 사양을 지원합니다.

WS-ReliableMessaging 1.0

(기본값) 2005년 2월 제출 버전에 대한 수정 사항은 현재 최신 버전이 아닙니다. 그러나 이전 버전과의 호환성을 위해 이 버전이 기본값으로 사용됩니다.

WS-RM의 버전 1.0은 다음 네임스페이스를 사용합니다.

http://schemas.xmlsoap.org/ws/2005/02/rm/
Copy to Clipboard Toggle word wrap

WS-RM의 이 버전은 다음 WS-Addressing 버전과 함께 사용할 수 있습니다.

http://schemas.xmlsoap.org/ws/2004/08/addressing (default)
http://www.w3.org/2005/08/addressing
Copy to Clipboard Toggle word wrap

WS-RM의 2005년 2월 제출 버전을 준수하기 위해 첫 번째 WS-Addressing 버전(Apache CXF의 기본값)을 사용해야 합니다. 그러나 대부분의 다른 웹 서비스 구현이 최신 WS-Addressing 사양으로 전환되었으므로 Apache CXF를 사용하면 WS-A 버전을 선택하여 상호 운용성을 용이하게 할 수 있습니다( 21.4절. “런타임 제어”참조).

WS-ReliableMessaging 1.1/1.2

공식 1.1/1.2 웹 서비스 신뢰할 수 있는 메시징 사양에 해당합니다.

WS-RM의 버전 1.1 및 1.2에서는 다음 네임스페이스를 사용합니다.

http://docs.oasis-open.org/ws-rx/wsrm/200702
Copy to Clipboard Toggle word wrap

WS-RM의 1.1 및 1.2 버전에서는 다음 WS-Addressing 버전을 사용합니다.

http://www.w3.org/2005/08/addressing
Copy to Clipboard Toggle word wrap

21.1.5. WS-RM 버전 선택

다음과 같이 사용할 WS-RM 사양 버전을 선택할 수 있습니다.

서버 측
공급자 측에서 Apache CXF는 WS-ReliableMessaging 버전을 클라이언트에서 사용하고 적절하게 응답합니다.
클라이언트 측
클라이언트 측에서 WS-RM 버전은 클라이언트 구성에서 사용하는 네임스페이스( 21.5절. “WS-RM 구성”참조)에 따라 결정되거나 런타임 제어 옵션을 사용하여 WS-RM 버전을 재정의해야 합니다( 21.4절. “런타임 제어”참조).

21.2. WS-RM 인터셉터

21.2.1. 개요

Apache CXF에서 WS-RM 기능은 인터셉터로 구현됩니다. Apache CXF 런타임은 인터셉터를 사용하여 전송 및 수신 중인 원시 메시지를 가로채고 사용합니다. 전송이 메시지를 수신하면 메시지 개체를 생성하고 인터셉터 체인을 통해 해당 메시지를 보냅니다. 애플리케이션의 인터셉터 체인에 WS-RM 인터셉터가 포함된 경우 애플리케이션은 안정적인 메시징 세션에 참여할 수 있습니다. WS-RM 인터셉터는 메시지 청크의 수집 및 집계를 처리합니다. 또한 모든 승인 및 재전송 논리를 처리합니다.

21.2.2. Apache CXF WS-RM Interceptors

Apache CXF WS-RM 구현은 표 21.1. “Apache CXF WS-ReliableMessaging Interceptors” 에 설명된 4개의 인터셉터로 구성됩니다.

Expand
표 21.1. Apache CXF WS-ReliableMessaging Interceptors
인터셉터설명

org.apache.cxf.ws.rm.RMOutInterceptor

발신 메시지에 대한 신뢰성 보장을 제공하는 논리적 측면을 처리합니다.

CreateSequence 요청을 전송하고 CreateSequenceResponse 응답을 기다리는 책임이 있습니다.

애플리케이션 메시지에 대해 시퀀스 속성 ID 및 메시지 번호 집계를 담당합니다.

org.apache.cxf.ws.rm.RMInInterceptor

애플리케이션 메시지에 대해 RM 프로토콜 메시지 및 SequenceAcknowledgement 메시지를 가로채고 처리할 책임이 있습니다.

org.apache.cxf.ws.rm.RMCaptureInInterceptor

영구 스토리지를 위해 들어오는 메시지를 캐싱합니다.

org.apache.cxf.ws.rm.RMDeliveryInterceptor

애플리케이션에 메시지를 즉시 전달할 수 있도록 합니다.

org.apache.cxf.ws.rm.soap.RMSoapInterceptor

안정성 속성을#159 헤더로 인코딩 및 디코딩합니다.

org.apache.cxf.ws.rm.RetransmissionInterceptor

향후 재전송을 위해 애플리케이션 메시지의 사본 생성을 담당합니다.

21.2.3. WS-RM 활성화

인터셉터 체인에 WS-RM 인터셉터가 있으면 필요한 경우 WS-RM 프로토콜 메시지를 교환합니다. 예를 들어 아웃바운드 인터셉터 체인에서 첫 번째 애플리케이션 메시지를 가로채는 경우 RMOutInterceptorCreateSequence 요청을 전송하고 CreateSequenceResponse 응답을 수신할 때까지 원래 애플리케이션 메시지를 처리하도록 대기합니다. 또한 WS-RM 인터셉터는 애플리케이션 메시지에 시퀀스 헤더를 추가하고 대상 측에서 메시지에서 압축을 풉니다. 메시지를 안정적으로 교환하기 위해 애플리케이션 코드를 변경할 필요가 없습니다.

WS-RM을 활성화하는 방법에 대한 자세한 내용은 21.3절. “WS-RM 활성화” 을 참조하십시오.

21.2.4. WS-RM 속성 구성

구성을 통해 시퀀스 요약 및 신뢰할 수 있는 교환의 다른 측면을 제어합니다. 예를 들어 기본적으로 Apache CXF는 시퀀스의 수명을 최대화하여 대역 외 WS-RM 프로토콜 메시지에 의해 발생하는 오버헤드를 줄입니다. 애플리케이션 메시지마다 별도의 시퀀스를 사용하려면 WS-RM 소스의 시퀀스 종료 정책을 구성합니다(최대 시퀀스 길이를 1로 설정).

WS-RM 동작 구성에 대한 자세한 내용은 21.5절. “WS-RM 구성” 을 참조하십시오.

21.3. WS-RM 활성화

21.3.1. 개요

안정적인 메시징을 사용하려면 인바운드 및 아웃바운드 메시지 및 결함 모두에 대해 WS-RM 인터셉터를 인터셉터 체인에 추가해야 합니다. WS-RM 인터셉터는 WS-Addressing을 사용하므로 WS-Addressing 인터셉터도 인터셉터 체인에 있어야 합니다.

다음 두 가지 방법 중 하나로 이러한 인터셉터가 있는지 확인할 수 있습니다.

  • 명시적으로, Spring 빈을 사용하여 디스패치 체인에 추가
  • Apache CXF 런타임이 사용자를 대신하여 인터셉터를 투명하게 추가하도록 하는 WS-Policy 어설션을 사용하여 암시적으로 되게 합니다.

21.3.2. Spring 빈: 명시적으로 인터셉터 추가

WS-RM을 활성화하려면 Apache CXF 버스에 WS-RM 및 WS-Addressing 인터셉터를 추가하거나 Spring Ignition 구성을 사용하여 소비자 또는 서비스 끝점에 추가합니다. 이 방법은 InstallDir/samples/ws_rm 디렉터리에 있는 WS-RM 샘플에서 가져온 방법입니다. 구성 파일 ws-rm.cxf 는 Spring 빈으로 하나씩 추가되는 WS-RM 및 WS-Addressing 인터셉터를 보여줍니다( 예 21.1. “Spring Cryostat를 사용하여 WS-RM 활성화”참조).

예 21.1. Spring Cryostat를 사용하여 WS-RM 활성화

<?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.xsd">
   <bean id="mapAggregator" class="org.apache.cxf.ws.addressing.MAPAggregator"/>
   <bean id="mapCodec" class="org.apache.cxf.ws.addressing.soap.MAPCodec"/>
   <bean id="rmLogicalOut" class="org.apache.cxf.ws.rm.RMOutInterceptor">
        <property name="bus" ref="cxf"/>
   </bean>
   <bean id="rmLogicalIn" class="org.apache.cxf.ws.rm.RMInInterceptor">
        <property name="bus" ref="cxf"/>
   </bean>
   <bean id="rmCodec" class="org.apache.cxf.ws.rm.soap.RMSoapInterceptor"/>
   <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl">
        <property name="inInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalIn"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
        <property name="inFaultInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalIn"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
        <property name="outInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalOut"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
        <property name="outFaultInterceptors">
            <list>
                <ref bean="mapAggregator">
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalOut"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
    </bean>
</beans>
Copy to Clipboard Toggle word wrap

예 21.1. “Spring Cryostat를 사용하여 WS-RM 활성화” 에 표시된 코드는 다음과 같이 설명할 수 있습니다.

Apache CXF 구성 파일은 Spring XML 파일입니다. 요소에 의해 캡슐화된 하위 요소의 네임스페이스 및 스키마 파일을 선언하는 열기 Spring 요소를 포함해야 합니다.

각 WS-Addressing interceptors-MAPAggregatorMAPCodec 를 구성합니다. WS-Addressing에 대한 자세한 내용은 20장. WS-Addressing 배포 을 참조하십시오.

각 WS-RM 인터셉터(RMOutInterceptor,RMInInterceptor, RMSoapInterceptor )를 구성합니다.

인바운드 메시지의 인터셉터 체인에 WS-Addressing 및 WS-RM 인터셉터를 추가합니다.

인바운드 오류의 인터셉터 체인에 WS-Addressing 및 WS-RM 인터셉터를 추가합니다.

아웃바운드 메시지의 인터셉터 체인에 WS-Addressing 및 WS-RM 인터셉터를 추가합니다.

WS-Addressing 및 WS-RM 인터셉터를 아웃바운드 결함의 인터셉터 체인에 추가합니다.

21.3.3. WS-Policy 프레임워크: 암시적으로 인터셉터 추가

WS-Policy 프레임워크는 WS-Policy를 사용할 수 있는 인프라 및 API를 제공합니다. 2006년 11월 Web Services Policy 1.5-FrameworkWeb Services Policy 1.5-Attachment 사양을 준수합니다.

Apache CXF WS-Policy 프레임워크를 사용하여 WS-RM을 활성화하려면 다음을 수행합니다.

  1. 클라이언트 및 서버 끝점에 정책 기능을 추가합니다. 예 21.2. “WS-Policy를 사용하여 WS-RM 구성” jaxws:feature 요소 내에 중첩된 참조 8080을 표시합니다. 참조 8080은 동일한 구성 파일 내에서 별도의 요소로 정의되는 AddressingPolicy 를 지정합니다.

    예 21.2. WS-Policy를 사용하여 WS-RM 구성

    <jaxws:client>
        <jaxws:features>
          <ref bean="AddressingPolicy"/>
        </jaxws:features>
    </jaxws:client>
    <wsp:Policy wsu:Id="AddressingPolicy" xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
        <wsam:Addressing>
          <wsp:Policy>
            <wsam:NonAnonymousResponses/>
          </wsp:Policy>
        </wsam:Addressing>
    </wsp:Policy>
    Copy to Clipboard Toggle word wrap
  2. 예 21.3. “WSDL 파일에 RM 정책 추가” 에 표시된 대로 신뢰할 수 있는 메시징 정책을 wsdl:service 요소 또는 정책 참조 요소의 연결 지점으로 사용할 수 있는 기타 WSDL 요소를 추가합니다.

    예 21.3. WSDL 파일에 RM 정책 추가

    <wsp:Policy wsu:Id="RM"
       xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
            <wsp:Policy/>
        </wsam:Addressing>
        <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
            <wsrmp:BaseRetransmissionInterval Milliseconds="10000"/>
        </wsrmp:RMAssertion>
    </wsp:Policy>
    ...
    <wsdl:service name="ReliableGreeterService">
        <wsdl:port binding="tns:GreeterSOAPBinding" name="GreeterPort">
            <soap:address location="http://localhost:9020/SoapContext/GreeterPort"/>
            <wsp:PolicyReference URI="#RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"/>
        </wsdl:port>
    </wsdl:service>
    Copy to Clipboard Toggle word wrap

21.4. 런타임 제어

21.4.1. 개요

클라이언트 코드에서 org.apache.cxf.ws.rm.RMManager 클래스의 공개 상수로 정의된 키 값을 런타임 시 제어하도록 여러 메시지 컨텍스트 속성 값을 설정할 수 있습니다.

21.4.2. 런타임 제어 옵션

다음 표에는 org.apache.cxf.ws.rm.RMManager 클래스에서 정의한 키가 나열되어 있습니다.

Expand
설명

WSRM_VERSION_PROPERTY

문자열 WS-RM 버전 네임스페이스(http://schemas.xmlsoap.org/ws/2005/02/rm/ 또는 http://docs.oasis-open.org/ws-rx/wsrm/200702).

WSRM_WSA_VERSION_PROPERTY

문자열 WS-Addressing 버전 네임스페이스(http://schemas.xmlsoap.org/ws/2004/08/addressing 또는 http://www.w3.org/2005/08/addressing) - http://schemas.xmlsoap.org/ws/2005/02/rm/ RM 네임스페이스를 사용하지 않는 한 이 속성은 무시됩니다.

WSRM_LAST_MESSAGE_PROPERTY

WS-RM 코드에 마지막 메시지가 전송되고 있음을 알리는 부울 값 true 로 코드가 WS-RM 시퀀스 및 릴리스 리소스(CXF의 3.0.0 버전부터)를 닫을 수 있습니다(클라이언트를 닫을 때 WS-RM은 기본적으로 RM 시퀀스를 종료합니다).

WSRM_INACTIVITY_TIMEOUT_PROPERTY

밀리초 단위의 긴 비활성 타임아웃입니다.

WSRM_RETRANSMISSION_INTERVAL_PROPERTY

밀리초 단위의 긴 기본 재전송 간격입니다.

WSRM_EXPONENTIAL_BACKOFF_PROPERTY

부울 지수 백오프 플래그입니다.

WSRM_ACKNOWLEDGEMENT_INTERVAL_PROPERTY

밀리초 단위의 긴 승인 간격입니다.

21.4.3. WS-RM에서 Cryostat 제어

Apache CXF의 Cryostat 관리 기능을 사용하여 WS-RM의 여러 측면을 모니터링하고 제어할 수도 있습니다. Cryostat 작업의 전체 목록은 org.apache.cxf.ws.rm.ManagedRMManagerorg.apache.cxf.ws.rm.ManagedRMEndpoint 에 의해 정의되지만 이러한 작업에는 현재 RM 상태를 개별 메시지 수준으로 보는 작업이 포함됩니다. JXM을 사용하여 WS-RM 시퀀스를 종료하거나 종료하고, 원격 RM 엔드포인트에서 이전에 메시지를 승인할 때 알림을 받을 수도 있습니다.

21.4.4. Cryostat 제어의 예

예를 들어 클라이언트 구성에 Cryostat 서버가 활성화된 경우 다음 코드를 사용하여 수신된 마지막 승인 번호를 추적할 수 있습니다.

// Java
private static class AcknowledgementListener implements NotificationListener {
    private volatile long lastAcknowledgement;

    @Override
    public void handleNotification(Notification notification, Object handback) {
        if (notification instanceof AcknowledgementNotification) {
            AcknowledgementNotification ack = (AcknowledgementNotification)notification;
            lastAcknowledgement = ack.getMessageNumber();
        }
    }

    // initialize client
...
    // attach to JMX bean for notifications
    //  NOTE: you must have sent at least one message to initialize RM before executing this code
    Endpoint ep = ClientProxy.getClient(client).getEndpoint();
    InstrumentationManager im = bus.getExtension(InstrumentationManager.class);
    MBeanServer mbs = im.getMBeanServer();
    RMManager clientManager = bus.getExtension(RMManager.class);
    ObjectName name = RMUtils.getManagedObjectName(clientManager, ep);
    System.out.println("Looking for endpoint name " + name);
    AcknowledgementListener listener = new AcknowledgementListener();
    mbs.addNotificationListener(name, listener, null, null);

    // send messages using RM with acknowledgement status reported to listener
...
Copy to Clipboard Toggle word wrap

21.5. WS-RM 구성

21.5.1. Apache CXF-Specific WS-RM 속성 구성

21.5.1.1. 개요

Apache CXF별 속성을 구성하려면 rmManager Spring 8080을 사용합니다. 구성 파일에 다음을 추가합니다.

예 21.4. “Apache CXF-Specific WS-RM 속성 구성” 간단한 예를 보여줍니다.

예 21.4. Apache CXF-Specific WS-RM 속성 구성

&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://cxf.apache.org/ws/rm/manager http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd"&gt;
...
&lt;wsrm-mgr:rmManager&gt;
&lt;!--
  ...Your configuration goes here
--&gt;
&lt;/wsrm-mgr:rmManager&gt;
Copy to Clipboard Toggle word wrap
21.5.1.2. rmManager Spring 8080의 하위 항목

표 21.2. “rmManager Spring Cryostat의 하위” http://cxf.apache.org/ws/rm/manager 네임스페이스에 정의된 rmManager Spring 8080의 하위 요소를 표시합니다.

Expand
표 21.2. rmManager Spring Cryostat의 하위
element설명

RMAsertion

RMAsertion 유형의요소

deliveryAssurance

적용되어야 하는 전달 보장을 설명하는 DeliveryAssuranceType 유형의 요소

sourcePolicy

RM 소스의 세부 정보를 구성할 수 있는 SourcePolicyType 유형의 요소

destinationPolicy

RM 대상에 대한 세부 정보를 구성할 수 있는 DestinationPolicyType 유형의 요소

21.5.1.3. 예제

예를 들면 “승인되지 않은 최대 메시지 임계값” 을 참조하십시오.

21.5.2. 표준 WS-RM 정책 속성 구성

21.5.2.1. 개요

다음 방법 중 하나로 표준 WS-RM 정책 속성을 구성할 수 있습니다.

21.5.2.2. WS-Policy RMAsertion children

표 21.3. “WS-Policy RMAsertion Element” http://schemas.xmlsoap.org/ws/2005/02/rm/policy 네임스페이스에 정의된 요소를 표시합니다.

Expand
표 21.3. WS-Policy RMAsertion Element
이름설명

InactivityTimeout

끝점이 비활성으로 인해 RM 시퀀스를 종료하기 전에 메시지를 수신하지 않고 전달해야 하는 시간을 지정합니다.

BaseRetransmissionInterval

지정된 메시지에 대해 RM 소스에서 승인을 받아야 하는 간격을 설정합니다. BaseRetransmissionInterval 에서 설정한 시간 내에 승인이 수신되지 않으면 RM Source가 메시지를 다시 전송합니다.

ExponentialBackoff

일반적으로 알려진 지수 백오프 알고리즘(Tanenbaum)을 사용하여 재전송 간격이 조정됨을 나타냅니다.

자세한 내용은 Computer Networks, Andrew S. Tanenbaum, Prentice Hall PTR, 2003을 참조하십시오.

AcknowledgementInterval

WS-RM에서 반환 메시지로 승인이 전송되거나 독립 실행형으로 전송됩니다. 승인을 보내는 데 반환 메시지를 사용할 수 없는 경우 RM Destination은 독립형 승인을 보내기 전에 승인 간격까지 기다릴 수 있습니다. 승인되지 않은 메시지가 없는 경우 RM Destination은 승인을 보내지 않도록 선택할 수 있습니다.

21.5.2.3. 자세한 참조 정보

각 요소의 하위 요소 및 속성에 대한 설명을 포함한 자세한 참조 정보는 http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd 에서 참조하십시오.

21.5.2.4. rmManager Spring 8080의 RMAssertion

Apache CXF rmManager Spring Ignition 내에 RMAssertion 을 추가하여 표준 WS-RM 정책 속성을 구성할 수 있습니다. 모든 WS-RM 구성을 동일한 구성 파일에 유지하려면, 즉, Apache CXF별 속성 및 표준 WS-RM 정책 속성을 동일한 파일에 구성하려면 이 방법이 가장 좋습니다.

예를 들어 예 21.5. “rmManager Spring Cryostat에서 RMAssertion을 사용하여 WS-RM 속성 구성” 의 구성은 다음과 같습니다.

  • rmManager Springans 내의 RMAssertion 을 사용하여 구성된 표준 WS-RM 정책 속성 BaseRetransmissionInterval.
  • 동일한 구성 파일에 구성된 Apache CXF별 RM 속성 intraMessageThreshold.

예 21.5. rmManager Spring Cryostat에서 RMAssertion을 사용하여 WS-RM 속성 구성

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
       xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
    </wsrm-policy:RMAssertion>
    <wsrm-mgr:destinationPolicy>
        <wsrm-mgr:acksPolicy intraMessageThreshold="0" />
    </wsrm-mgr:destinationPolicy>
</wsrm-mgr:rmManager>
</beans>
Copy to Clipboard Toggle word wrap
21.5.2.5. 기능 내 정책

예 21.6. “기능 내에서 WS-RM 속성 구성” 에 표시된 대로 기능 내에서 표준 WS-RM 정책 속성을 구성할 수 있습니다.

예 21.6. 기능 내에서 WS-RM 속성 구성

<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:wsa="http://cxf.apache.org/ws/addressing"
        xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
http://www.w3.org/2006/07/ws-policy http://www.w3.org/2006/07/ws-policy.xsd
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schema/ws/addressing.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <jaxws:endpoint name="{http://cxf.apache.org/greeter_control}GreeterPort" createdFromAPI="true">
        <jaxws:features>
               <wsp:Policy>
                   <wsrm:RMAssertion xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
                     <wsrm:AcknowledgementInterval Milliseconds="200" />
                   </wsrm:RMAssertion>
                   <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                       <wsp:Policy>
                            <wsam:NonAnonymousResponses/>
                       </wsp:Policy>
                   </wsam:Addressing>
              </wsp:Policy>
        </jaxws:features>
    </jaxws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap
21.5.2.6. WSDL 파일

WS-Policy 프레임워크를 사용하여 WS-RM을 활성화하는 경우 WSDL 파일에서 표준 WS-RM 정책 속성을 구성할 수 있습니다. 다른 정책 인식 웹 서비스 스택에 배포된 소비자와 원활하게 WS-RM을 상호 운용하고 사용하려면 이 방법이 좋은 방법입니다.

예를 들어 기본 재전송 간격이 WSDL 파일에서 구성된 “WS-Policy 프레임워크: 암시적으로 인터셉터 추가” 를 참조하십시오.

21.5.2.7. 외부 첨부 파일

외부 첨부 파일에서 표준 WS-RM 정책 속성을 구성할 수 있습니다. 이 방법은 WSDL 파일을 변경할 수 없거나 변경할 수 없는 경우 좋은 방법입니다.

예 21.7. “외부 연결에서 WS-RM 구성” 특정 EPR에 대해 WS-A 및 WS-RM(base retransmission interval of 30초)을 모두 활성화하는 외부 첨부 파일을 표시합니다.

예 21.7. 외부 연결에서 WS-RM 구성

<attachments xmlns:wsp="http://www.w3.org/2006/07/ws-policy" xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsp:PolicyAttachment>
        <wsp:AppliesTo>
           <wsa:EndpointReference>
                <wsa:Address>http://localhost:9020/SoapContext/GreeterPort</wsa:Address>
            </wsa:EndpointReference>
        </wsp:AppliesTo>
        <wsp:Policy>
            <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                <wsp:Policy/>
            </wsam:Addressing>
            <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
                <wsrmp:BaseRetransmissionInterval Milliseconds="30000"/>
            </wsrmp:RMAssertion>
        </wsp:Policy>
    </wsp:PolicyAttachment>
</attachments>/
Copy to Clipboard Toggle word wrap

21.5.3. WS-RM 구성 사용 사례

21.5.3.1. 개요

이 하위 섹션에서는 사용 사례 관점에서 WS-RM 속성을 구성하는 데 중점을 둡니다. 속성이 http://schemas.xmlsoap.org/ws/2005/02/rm/policy/ 네임스페이스에 정의된 표준 WS-RM 정책 속성인 경우 rmManager Spring 8080 내의 RMAssertion 에 설정하는 예만 표시됩니다. 기능 내에서 정책과 같은 특성을 설정하는 방법에 대한 자세한 내용은 WSDL 파일에서 또는 외부 연결에서 21.5.2절. “표준 WS-RM 정책 속성 구성” 를 참조하십시오.

다음 사용 사례를 다룹니다.

21.5.3.2. 기본 재전송 간격

BaseRetransmissionInterval 요소는 RM 소스가 아직 승인되지 않은 메시지를 다시 전송하는 간격을 지정합니다. http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd 스키마 파일에 정의되어 있습니다. 기본값은 3000밀리초입니다.

예 21.8. “WS-RM 기본 재전송 간격 설정” WS-RM 기본 재전송 간격을 설정하는 방법을 보여줍니다.

예 21.8. WS-RM 기본 재전송 간격 설정

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>
Copy to Clipboard Toggle word wrap
21.5.3.3. 재전송을 위한 지수 백오프

ExponentialBackoff 요소는 승인되지 않은 메시지에 대한 연속 재전송 시도가 기하급수적으로 수행되는지 여부를 결정합니다.

ExponentialBackoff 요소가 있으면 이 기능을 활성화합니다. 기본적으로 2 의 지수 백오프 비율이 사용됩니다. ExponentialBackoff 는 플래그입니다. 요소가 있으면 지수 백오프가 활성화됩니다. 요소가 없으면 지수 백오프가 비활성화됩니다. 값이 필요하지 않습니다.

예 21.9. “WS-RM 노출 백오프 속성 설정” 재전송을 위해 WS-RM 지수 백오프를 설정하는 방법을 보여줍니다.

예 21.9. WS-RM 노출 백오프 속성 설정

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:ExponentialBackoff/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>
Copy to Clipboard Toggle word wrap
21.5.3.4. 승인 간격

AcknowledgementInterval 요소는 WS-RM 대상이 비동기 승인을 전송하는 간격을 지정합니다. 이러한 승인은 수신되는 메시지를 수신 시 전송하는 동기식 확인에 추가됩니다. 기본 비동기 승인 간격은 0 밀리초입니다. 즉, AcknowledgementInterval 이 특정 값으로 구성되지 않은 경우 승인이 즉시 전송됩니다(즉, 사용 가능한 첫 번째 기회에).

비동기 승인은 다음 두 조건이 충족되는 경우에만 RM 대상에 의해 전송됩니다.

  • RM 대상은 비익명 wsrm:acksTo 끝점을 사용하고 있습니다.
  • 응답 메시지에 대한 승인에 대한 감사의 기회를 비추는 것은 승인 기간이 만료되기 전에 발생하지 않습니다.

예 21.10. “WS-RM 승인 간격 설정” WS-RM 승인 간격을 설정하는 방법을 보여줍니다.

예 21.10. WS-RM 승인 간격 설정

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>
Copy to Clipboard Toggle word wrap
21.5.3.5. 승인되지 않은 최대 메시지 임계값

maxUnacknowledged 속성은 시퀀스가 종료되기 전에 시퀀스당 누적될 수 있는 풀링되지 않은 메시지의 최대 수를 설정합니다.

예 21.11. “WS-RM 최대 풀링되지 않은 메시지 임계값 설정” WS-RM 최대 알 수 없는 메시지 임계값을 설정하는 방법을 보여줍니다.

예 21.11. WS-RM 최대 풀링되지 않은 메시지 임계값 설정

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxUnacknowledged="20" />
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:reliableMessaging>
</beans>
Copy to Clipboard Toggle word wrap
21.5.3.6. RM 순서의 최대 길이

maxLength 속성은 WS-RM 시퀀스의 최대 길이를 설정합니다. 기본값은 0 입니다. 즉, WS-RM 시퀀스의 길이는 바인딩되지 않습니다.

이 속성이 설정되면 RM 끝점은 제한에 도달하고 이전에 보낸 메시지의 모든 승인을 받은 후 새 RM 시퀀스를 생성합니다. 새 메시지는 newsequence를 사용하여 전송됩니다.

예 21.12. “WS-RM 메시지 시퀀스의 최대 길이 설정” RM 시퀀스의 최대 길이를 설정하는 방법을 보여줍니다.

예 21.12. WS-RM 메시지 시퀀스의 최대 길이 설정

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxLength="100" />
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:reliableMessaging>
</beans>
Copy to Clipboard Toggle word wrap
21.5.3.7. 메시지 전달 보장 정책

다음 전달 보장 정책을 사용하도록 RM 대상을 구성할 수 있습니다.

  • RM 대상은 한 번만 애플리케이션 대상에 메시지를 전달합니다. 메시지가 두 번 이상 전달되는 경우 오류가 발생합니다. 시퀀스의 일부 메시지는 전달되지 않을 수 있습니다.
  • AtLeastOnce - RM 대상은 하나 이상의 애플리케이션 대상에 메시지를 전달합니다. 전송된 모든 메시지가 전달되거나 오류가 발생합니다. 일부 메시지는 두 번 이상 전달될 수 있습니다.
  • InOrder - RM 대상은 전송된 순서대로 애플리케이션 대상에 메시지를 전달합니다. 이 전달 보증은 At Cryostat Once 또는 AtLeastOnce 보증과 결합할 수 있습니다.

예 21.13. “WS-RM 메시지 전달 보장 정책 설정” WS-RM 메시지 전달 보장을 설정하는 방법을 보여줍니다.

예 21.13. WS-RM 메시지 전달 보장 정책 설정

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:deliveryAssurance>
        <wsrm-mgr:AtLeastOnce />
    </wsrm-mgr:deliveryAssurance>
</wsrm-mgr:reliableMessaging>
</beans>
Copy to Clipboard Toggle word wrap

21.6. WS-RM 지속성 구성

21.6.1. 개요

이 장에서 이미 설명한 Apache CXF WS-RM 기능은 네트워크 오류와 같은 경우 안정성을 제공합니다. WS-RM 지속성은 RM 소스 또는 RM 대상 충돌과 같은 다른 유형의 오류에서 안정성을 제공합니다.

WS-RM 지속성은 다양한 RM 엔드포인트의 상태를 영구 스토리지에 저장해야 합니다. 이렇게 하면 끝점이 재탄권될 때 메시지를 계속 보내고 수신할 수 있습니다.

Apache CXF는 구성 파일에서 WS-RM 지속성을 활성화합니다. 기본 WS-RM 지속성 저장소는 JDBC 기반입니다. 편의를 위해 Apache CXF에는 즉시 배포할 수 있는 Derby가 포함되어 있습니다. 또한 영구 저장소는 Java API를 사용하여 노출됩니다. 고유한 지속성 메커니즘을 구현하기 위해 기본 DB로 이 API를 사용하여 하나를 구현할 수 있습니다.

중요

WS-RM 지속성은 단방향 호출에서만 지원되며 기본적으로 비활성화되어 있습니다.

21.6.2. 작동 방식

Apache CXF WS-RM 지속성은 다음과 같이 작동합니다.

  • RM 소스 엔드포인트에서 발신 메시지는 전송 전에 유지됩니다. 승인이 수신되면 영구 저장소에서 제거됩니다.
  • 충돌로 복구한 후 모든 메시지가 승인될 때까지 지속된 메시지를 복구하고 다시 전송을 수행합니다. 이 시점에서 RM 시퀀스가 닫힙니다.
  • RM 대상 끝점에서는 수신 메시지가 유지되고 성공적인 저장소에 승인이 전송됩니다. 메시지가 성공적으로 디스패치되면 영구 저장소에서 제거됩니다.
  • 충돌에서 복구한 후 지속 가능한 메시지를 복구하고 이를 전송합니다. 또한 RM 시퀀스를 새 메시지가 수락, 승인 및 전달되는 상태로 가져옵니다.

21.6.3. WS-persistence 활성화

WS-RM 지속성을 활성화하려면 WS-RM의 영구 저장소를 구현하는 오브젝트를 지정해야 합니다. 직접 개발하거나 Apache CXF와 함께 제공되는 JDBC 기반 저장소를 사용할 수 있습니다.

예 21.14. “기본 WS-RM 지속성 저장소에 대한 구성” 에 표시된 구성은 Apache CXF와 함께 제공되는 JDBC 기반 저장소를 활성화합니다.

예 21.14. 기본 WS-RM 지속성 저장소에 대한 구성

<bean id="RMTxStore" class="org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore"/>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <property name="store" ref="RMTxStore"/>
</wsrm-mgr:rmManager>
Copy to Clipboard Toggle word wrap

21.6.4. WS-persistence 구성

Apache CXF와 함께 제공되는 JDBC 기반 저장소는 표 21.4. “JDBC 저장소 속성” 에 표시된 속성을 지원합니다.

Expand
표 21.4. JDBC 저장소 속성
특성 이름유형기본 설정

driverClassName

문자열

org.apache.derby.jdbc.EmbeddedDriver

userName

문자열

null

passWord

문자열

null

url

문자열

jdbc:derby:rmdb;create=true

예 21.15. “WS-RM 지속성을 위한 JDBC 저장소 구성” 에 표시된 구성은 Apache CXF와 함께 제공되는 JDBC 기반 저장소를 활성화하며 driverClassNameurl 을 기본값이 아닌 값으로 설정합니다.

예 21.15. WS-RM 지속성을 위한 JDBC 저장소 구성

<bean id="RMTxStore" class="org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore">
    <property name="driverClassName" value="com.acme.jdbc.Driver"/>
    <property name="url" value="jdbc:acme:rmdb;create=true"/>
</bean>
Copy to Clipboard Toggle word wrap

22장. 고가용성 활성화

초록

이 장에서는 Apache CXF 런타임에서 고가용성을 활성화하고 구성하는 방법을 설명합니다.

22.1. 고가용성 소개

22.1.1. 개요

확장 가능하고 안정적인 애플리케이션에는 분산 시스템의 단일 장애 지점을 방지하기 위해 고가용성이 필요합니다. 다음을 사용하여 단일 장애 지점으로부터 시스템을 보호할 수 있습니다. 복제된 서비스.

복제된 서비스는 동일한 서비스의 여러 인스턴스 또는 복제본 으로 구성됩니다. 이러한 작업은 단일 논리 서비스 역할을 합니다. 클라이언트는 복제된 서비스에 대한 요청을 호출하고 Apache CXF는 해당 요청을 멤버 복제본 중 하나에 제공합니다. 복제본으로의 라우팅은 클라이언트에 투명합니다.

22.1.2. 정적 페일오버가 있는 HA

Apache CXF는 WSDL 파일에서 복제본 세부 정보가 인코딩되는 정적 장애 조치를 통해 HA(고가용성)를 지원합니다. WSDL 파일에는 여러 포트가 포함되어 있으며 동일한 서비스에 대한 여러 호스트를 포함할 수 있습니다. WSDL 파일이 변경되지 않는 한 클러스터의 복제본 수는 정적으로 유지됩니다. 클러스터 크기를 변경하려면 WSDL 파일을 편집해야 합니다.

22.2. 정적 Cryostat를 사용하여 HA 활성화

22.2.1. 개요

정적 장애 조치로 HA를 활성화하려면 다음을 수행해야 합니다.

22.2.2. 서비스 WSDL 파일의 복제본 세부 정보 인코딩

서비스 WSDL 파일에서 클러스터의 복제본 세부 정보를 인코딩해야 합니다. 예 22.1. “정적 Cryostat를 사용하여 HA 활성화: WSDL 파일” 3개의 복제본의 서비스 클러스터를 정의하는 WSDL 파일 추출을 표시합니다.

예 22.1. 정적 Cryostat를 사용하여 HA 활성화: WSDL 파일

<wsdl:service name="ClusteredService">
    <wsdl:port binding="tns:Greeter_SOAPBinding" name="Replica1">
        <soap:address location="http://localhost:9001/SoapContext/Replica1"/>
    </wsdl:port>

    <wsdl:port binding="tns:Greeter_SOAPBinding" name="Replica2">
        <soap:address location="http://localhost:9002/SoapContext/Replica2"/>
    </wsdl:port>

    <wsdl:port binding="tns:Greeter_SOAPBinding" name="Replica3">
        <soap:address location="http://localhost:9003/SoapContext/Replica3"/>
    </wsdl:port>

</wsdl:service>
Copy to Clipboard Toggle word wrap

예 22.1. “정적 Cryostat를 사용하여 HA 활성화: WSDL 파일” 에 표시된 WSDL 추출은 다음과 같이 설명할 수 있습니다.

세 포트에 노출된 ClusterService 서비스를 정의합니다.

  1. Replica1
  2. Replica2
  3. Replica3

Replica1 을 정의하여 포트 9001 에서 HTTP 끝점을 통해 ClusterService 를 Syslog로 노출합니다.

포트 9002 에서 HTTP 끝점을 통해 ClusterService 를 Syslog로 노출하는 Replica2 를 정의합니다.

포트 9003 에서 HTTP 끝점을 통해 ClusterService 를 Syslog로 노출하도록 Replica3 을 정의합니다.

22.2.3. 클라이언트 구성에 클러스터링 기능 추가

클라이언트 구성 파일에서 예 22.2. “정적 Cryostat를 사용하여 HA 활성화: 클라이언트 구성” 에 표시된 대로 클러스터링 기능을 추가합니다.

예 22.2. 정적 Cryostat를 사용하여 HA 활성화: 클라이언트 구성

<?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"
       xmlns:clustering="http://cxf.apache.org/clustering"
         xsi:schemaLocation="http://cxf.apache.org/jaxws
         http://cxf.apache.org/schemas/jaxws.xsd
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">

    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica1"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover/>
        </jaxws:features>
    </jaxws:client>

    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica2"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover/>
        </jaxws:features>
    </jaxws:client>

    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica3"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover/>
        </jaxws:features>
    </jaxws:client>

</beans>
Copy to Clipboard Toggle word wrap

22.3. 정적 Cryostat를 사용하여 HA 구성

22.3.1. 개요

기본적으로 정적 페일오버가 있는 HA는 클라이언트가 통신하는 원본 서비스를 사용할 수 없게 되거나 실패하는 경우 복제본 서비스를 선택할 때 순차적 전략을 사용합니다. 순차적 전략은 사용될 때마다 동일한 순차적 순서로 복제본 서비스를 선택합니다. 선택은 Apache CXF의 내부 서비스 모델에 의해 결정되며 결정적 장애 조치(failover) 패턴이 생성됩니다.

22.3.2. 임의의 전략 구성

복제본을 선택할 때 순차적 전략 대신 임의의 전략을 사용하도록 정적 장애 조치로 HA를 구성할 수 있습니다. random 전략은 서비스를 사용할 수 없게 될 때마다 임의의 복제본 서비스를 선택합니다. 클러스터의 남아 있는 멤버에서 장애 조치 대상을 선택하는 것은 완전히 임의적입니다.

임의의 전략을 구성하려면 예 22.3. “정적 Cryostat에 대한 Random 전략 구성” 에 표시된 구성을 클라이언트 구성 파일에 추가합니다.

예 22.3. 정적 Cryostat에 대한 Random 전략 구성

<beans ...>
    <bean id="Random" class="org.apache.cxf.clustering.RandomStrategy"/>

    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica3"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover>
                <clustering:strategy>
                    <ref bean="Random"/>
                </clustering:strategy>
            </clustering:failover>
        </jaxws:features>
    </jaxws:client>
</beans>
Copy to Clipboard Toggle word wrap

예 22.3. “정적 Cryostat에 대한 Random 전략 구성” 에 표시된 구성은 다음과 같이 설명할 수 있습니다.

임의의 전략을 구현하는 Random scaling 및 implementation 클래스를 정의합니다.

복제본을 선택할 때 임의의 전략이 사용되도록 지정합니다.

23장. Apache CXF 바인딩 ID

23.1. 바인딩 ID 테이블

부록 A. Maven OSGi 툴 사용

초록

대규모 프로젝트의 번들 또는 번들 컬렉션을 수동으로 생성하는 것은 번거로울 수 있습니다. Maven 번들 플러그인은 프로세스를 자동화하고 번들 매니페스트의 콘텐츠를 지정하는 데 필요한 여러 바로 가기를 제공하여 작업을 더 쉽게 수행할 수 있습니다.

A.1. Maven 번들 플러그인

Red Hat Fuse OSGi 툴링은 Apache Felix의 Maven 번들 플러그인을 사용합니다. 번들 플러그인은 Peter Kriens의 bnd 도구를 기반으로 합니다. 번들에 패키징되는 클래스의 콘텐츠를 인트로스펙션하여 OSGi 번들 매니페스트의 구성을 자동화합니다. 번들에 포함된 클래스에 대한 지식을 사용하여 플러그인에서 번들 매니페스트에서 Import-PackagesExport-Package 속성을 채울 적절한 값을 계산할 수 있습니다. 플러그인에는 번들 매니페스트의 다른 필수 속성에 사용되는 기본값도 있습니다.

번들 플러그인을 사용하려면 다음을 수행합니다.

  1. A.2절. “Red Hat Fuse OSGi 프로젝트 설정” 프로젝트의 POM 파일에 대한 번들 플러그인입니다.
  2. A.3절. “번들 플러그인 구성” 번들의 매니페스트를 올바르게 채우는 플러그인입니다.

A.2. Red Hat Fuse OSGi 프로젝트 설정

A.2.1. 개요

OSGi 번들을 빌드하기 위한 Maven 프로젝트는 간단한 단일 수준 프로젝트일 수 있습니다. 하위 프로젝트는 필요하지 않습니다. 그러나 다음을 수행해야 합니다.

  1. 번들 플러그인을 POM에 추가합니다.
  2. Maven에 결과를 OSGi 번들로 패키징하도록 지시합니다.
참고

적절한 설정으로 프로젝트를 설정하는 데 사용할 수 있는 여러 Maven archetypes가 있습니다.

A.2.2. 디렉토리 구조

OSGi 번들을 구성하는 프로젝트는 단일 수준 프로젝트일 수 있습니다. 최상위 POM 파일과 src 폴더만 있으면 됩니다. 모든 Maven 프로젝트에서와 마찬가지로 src/java 폴더에 모든 Java 소스 코드를 배치하고 src/resources 폴더에 비 Java 리소스를 배치합니다.

Java가 아닌 리소스에는 Spring 구성 파일, JBI 엔드포인트 구성 파일 및 WSDL 계약이 포함됩니다.

참고

Apache CXF, Apache Camel 또는 다른 Spring configured Quarkus를 사용하는 Red Hat Fuse OSGi 프로젝트에는 src/resources/META-INF/spring 폴더에 있는 beans.xml 파일도 포함됩니다.

A.2.3. 번들 플러그인 추가

번들 플러그인을 사용하려면 먼저 Apache Felix에 대한 종속성을 추가해야 합니다. 종속성을 추가한 후 번들 플러그인을 POM의 플러그인 부분에 추가할 수 있습니다.

예 A.1. “POM에 OSGi 번들 플러그인 추가” 번들 플러그인을 프로젝트에 추가하는 데 필요한 POM 항목이 표시됩니다.

예 A.1. POM에 OSGi 번들 플러그인 추가

...
<dependencies>
  <dependency>
    <groupId>org.apache.felix</groupId>
    <artifactId>org.osgi.core</artifactId>
    <version>1.0.0</version>
  </dependency>
...
</dependencies>
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <configuration>
        <instructions>
          <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
          <Import-Package>*,org.apache.camel.osgi</Import-Package>
          <Private-Package>org.apache.servicemix.examples.camel</Private-Package>
        </instructions>
      </configuration>
    </plugin>
  </plugins>
</build>
...
Copy to Clipboard Toggle word wrap

예 A.1. “POM에 OSGi 번들 플러그인 추가” 의 항목은 다음을 수행합니다.

Apache Felix에 대한 종속성 추가

번들 플러그인을 프로젝트에 추가

프로젝트의 아티팩트 ID를 번들의 심볼릭 이름으로 사용하도록 플러그인을 구성합니다.

번들 클래스에서 가져온 모든 Java 패키지를 포함하도록 플러그인을 구성합니다. 또한 org.apache.camel.osgi 패키지를 가져옵니다.

나열된 클래스를 번들하도록 플러그인을 구성하지만 내보낸 패키지 목록에 포함하지 마십시오.

참고

프로젝트의 요구 사항을 충족하도록 구성을 편집합니다.

번들 플러그인 구성에 대한 자세한 내용은 A.3절. “번들 플러그인 구성” 을 참조하십시오.

A.2.4. 번들 플러그인 활성화

Maven에서 번들 플러그인을 사용하도록 하려면 프로젝트 결과를 번들로 패키징하도록 지시합니다. POM 파일의 패키징 요소를 번들로 설정하여 이 작업을 수행합니다.

A.2.5. 유용한 Maven archetypes

번들 플러그인을 사용하도록 사전 구성된 프로젝트를 생성하는 데 사용할 수 있는 여러 Maven archetypes가 있습니다.

A.2.6. Spring OSGi archetype

Spring OSGi archetype은 다음과 같이 Spring DM을 사용하여 OSGi 프로젝트를 빌드하기 위한 일반 프로젝트를 생성합니다.

org.springframework.osgi/spring-bundle-osgi-archetype/1.1.2
Copy to Clipboard Toggle word wrap

다음 명령을 사용하여 archetype을 호출합니다.

mvn archetype:generate -DarchetypeGroupId=org.springframework.osgi -DarchetypeArtifactId=spring-osgi-bundle-archetype -DarchetypeVersion=1.1.2 -DgroupId=groupId -DartifactId=artifactId -Dversion=version
Copy to Clipboard Toggle word wrap

A.2.7. Apache CXF 코드 우선 archetype

Apache CXF 코드 우선 archetype은 다음과 같이 Java에서 서비스를 빌드하기 위한 프로젝트를 생성합니다.

org.apache.servicemix.tooling/servicemix-osgi-cxf-code-first-archetype/2010.02.0-fuse-02-00
Copy to Clipboard Toggle word wrap

다음 명령을 사용하여 archetype을 호출합니다.

mvn archetype:generate -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-osgi-cxf-code-first-archetype -DarchetypeVersion=2010.02.0-fuse-02-00 -DgroupId=groupId -DartifactId=artifactId -Dversion=version
Copy to Clipboard Toggle word wrap

A.2.8. Apache CXF wsdl-first archetype

Apache CXF wsdl 우선 archetype은 다음과 같이 WSDL에서 서비스를 생성하기 위한 프로젝트를 생성합니다.

org.apache.servicemix.tooling/servicemix-osgi-cxf-wsdl-first-archetype/2010.02.0-fuse-02-00
Copy to Clipboard Toggle word wrap

다음 명령을 사용하여 archetype을 호출합니다.

mvn archetype:generate -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-osgi-cxf-wsdl-first-archetype -DarchetypeVersion=2010.02.0-fuse-02-00 -DgroupId=groupId -DartifactId=artifactId -Dversion=version
Copy to Clipboard Toggle word wrap

A.2.9. Apache Camel archetype

Apache Camel archetype은 다음과 같이 Red Hat Fuse에 배포된 경로를 빌드하기 위한 프로젝트를 생성합니다.

org.apache.servicemix.tooling/servicemix-osgi-camel-archetype/2010.02.0-fuse-02-00
Copy to Clipboard Toggle word wrap

다음 명령을 사용하여 archetype을 호출합니다.

mvn archetype:generate -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-osgi-camel-archetype -DarchetypeVersion=2010.02.0-fuse-02-00 -DgroupId=groupId -DartifactId=artifactId -Dversion=version
Copy to Clipboard Toggle word wrap

A.3. 번들 플러그인 구성

A.3.1. 개요

번들 플러그인에는 작동하는 데 정보가 거의 필요하지 않습니다. 모든 필수 속성은 기본 설정을 사용하여 유효한 OSGi 번들을 생성합니다.

기본값만 사용하여 유효한 번들을 생성할 수 있지만 일부 값을 수정해야 합니다. 플러그인의 instructions 요소 내에 대부분의 속성을 지정할 수 있습니다.

A.3.2. 구성 속성

일반적으로 사용되는 일부 구성 속성은 다음과 같습니다.

A.3.3. 번들의 심볼릭 이름 설정

기본적으로 번들 플러그인은 Bundle-SymbolicName 속성 값을 groupId + "." + artifactId 로 설정합니다.

  • groupId 에 섹션이 하나만 있는 경우 클래스가 포함된 첫 번째 패키지 이름이 반환됩니다.

    예를 들어, Id 그룹이 commons-logging:commons-logging 인 경우 번들의 심볼릭 이름은 org.apache.commons.logging 입니다.

  • artifactIdgroupId 의 마지막 섹션과 동일한 경우 groupId 가 사용됩니다.

    예를 들어 POM에서 그룹 ID와 아티팩트 ID를 org.apache.maven:maven 로 지정하는 경우 번들의 심볼릭 이름은 org.apache.maven 입니다.

  • artifactIdgroupId 의 마지막 섹션으로 시작되면 해당 부분이 제거됩니다.

    예를 들어 POM에서 그룹 ID 및 아티팩트 ID를 org.apache.maven:maven-core 로 지정하는 경우 번들의 심볼릭 이름은 org.apache.maven.core 입니다.

번들의 심볼릭 이름에 고유한 값을 지정하려면 예 A.2. “번들의 심볼릭 이름 설정” 과 같이 플러그인의 instructions 요소에 Bundle-SymbolicName 자식을 추가합니다.

예 A.2. 번들의 심볼릭 이름 설정

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
     ...
    </instructions>
  </configuration>
</plugin>
Copy to Clipboard Toggle word wrap

A.3.4. 번들 이름 설정

기본적으로 번들의 이름은 ${project.name} 로 설정됩니다.

번들 이름에 대한 자체 값을 지정하려면 예 A.3. “번들 이름 설정” 과 같이 플러그인의 instructions 요소에 Bundle-Name 자식을 추가합니다.

예 A.3. 번들 이름 설정

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-Name>JoeFred</Bundle-Name>
     ...
    </instructions>
  </configuration>
</plugin>
Copy to Clipboard Toggle word wrap

A.3.5. 번들 버전 설정

기본적으로 번들의 버전은 ${project.version} 로 설정됩니다. 모든 대시(-)는 점(.)으로 교체되고 숫자는 최대 4자리로 채워집니다. 예를 들어 4.2-SNAPSHOT4.2.0.SNAPSHOT 이 됩니다.

번들 버전에 대한 자체 값을 지정하려면 예 A.4. “번들 버전 설정” 과 같이 플러그인의 instructions 요소에 Bundle-Version 자식을 추가합니다.

예 A.4. 번들 버전 설정

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-Version>1.0.3.1</Bundle-Version>
     ...
    </instructions>
  </configuration>
</plugin>
Copy to Clipboard Toggle word wrap

A.3.6. 내보낸 패키지 지정

기본적으로 OSGi 매니페스트의 Export-Package 목록은 기본 패키지 . impl 또는 .internal 을 포함하는 패키지를 제외하고 로컬 Java 소스 코드의 모든 패키지( src/main/java아래)로 채워집니다.

중요

플러그인 구성에서 Private-Package 요소를 사용하고 내보낼 패키지 목록을 지정하지 않는 경우 기본 동작에는 번들의 Private-Package 요소에 나열된 패키지만 포함됩니다. 패키지를 내보내지 않습니다.

기본 동작으로 인해 패키지가 매우 크고 비공개로 유지해야 하는 패키지를 내보낼 수 있습니다. 내보낸 패키지 목록을 변경하려면 플러그인의 instructions 요소에 Export-Package 자식을 추가할 수 있습니다.

Export-Package 요소는 번들에 포함할 패키지 목록을 지정하고 내보낼 패키지 목록을 지정합니다. 패키지 이름은 * 와일드카드 기호를 사용하여 지정할 수 있습니다. 예를 들어 com.fuse.demo.* 항목에는 com.fuse.demo 로 시작하는 프로젝트의 클래스 경로에 있는 모든 패키지가 포함되어 있습니다.

제외할 패키지를 지정할 수 있습니다 ! ! 항목을 접두사로 지정합니다. 예를 들어 !com.fuse.demo.private 항목은 com.fuse.demo.private 패키지를 제외합니다.

패키지를 제외할 때 목록의 항목 순서가 중요합니다. 목록은 처음부터 순서대로 처리되며 후속 일치하지 않는 항목은 무시됩니다.

예를 들어 com.fuse.demo 패키지를 제외하고 com.fuse.demo .demo 로 시작하는 모든 패키지를 포함하려면 다음을 사용하여 패키지를 나열합니다.

!com.fuse.demo.private,com.fuse.demo.*
Copy to Clipboard Toggle word wrap

그러나 com.fuse.demo.*,!com.fuse.demo.private 을 사용하여 패키지를 나열하면 com.fuse.demo.private 이 첫 번째 패턴과 일치하므로 번들에 포함됩니다.

A.3.7. 개인 패키지 지정

패키지를 내보내지 않고 번들에 포함할 패키지 목록을 지정하려면 번들 플러그인 구성에 Private-Package 명령을 추가할 수 있습니다. 기본적으로 Private-Package 명령을 지정하지 않으면 로컬 Java 소스의 모든 패키지가 번들에 포함됩니다.

중요

패키지가 Private-Package 요소 및 Export-Package 요소의 항목과 일치하는 경우 Export-Package 요소가 우선합니다. 패키지가 번들에 추가되어 내보내집니다.

Private-Package 요소는 번들에 포함할 패키지 목록을 지정하는 Export-Package 요소와 유사하게 작동합니다. 번들 플러그인은 목록을 사용하여 번들에 포함할 프로젝트의 클래스 경로의 모든 클래스를 찾습니다. 이러한 패키지는 번들에 패키지되지만 내보내지 않습니다( Export-Package 명령으로도 선택하지 않는 한).

예 A.5. “번들에 개인 패키지 포함” 번들에 개인 패키지를 포함하는 구성 표시

예 A.5. 번들에 개인 패키지 포함

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Private-Package>org.apache.cxf.wsdlFirst.impl</Private-Package>
     ...
    </instructions>
  </configuration>
</plugin>
Copy to Clipboard Toggle word wrap

A.3.8. 가져온 패키지 지정

기본적으로 번들 플러그인은 OSGi 매니페스트의 Import-Package 속성을 번들 콘텐츠에서 참조하는 모든 패키지 목록으로 채웁니다.

기본 동작은 일반적으로 대부분의 프로젝트에 충분하지만 목록에 자동으로 추가되지 않는 패키지를 가져오려는 인스턴스를 찾을 수 있습니다. 기본 동작으로 인해 원하지 않는 패키지를 가져올 수도 있습니다.

번들에서 가져올 패키지 목록을 지정하려면 플러그인의 instructions 요소에 Import-Package 자식을 추가합니다. 패키지 목록의 구문은 Export-Package 요소 및 Private-Package 요소와 동일합니다.

중요

Import-Package 요소를 사용하면 플러그인에서 번들의 콘텐츠를 자동으로 검사하여 필요한 가져오기가 있는지 확인하지 않습니다. 번들 내용이 스캔되었는지 확인하려면 패키지 목록의 마지막 항목으로 * 를 배치해야 합니다.

예 A.6. “번들로 가져온 패키지 지정” 번들로 가져온 패키지를 지정하기 위한 구성 표시

예 A.6. 번들로 가져온 패키지 지정

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Import-Package>javax.jws, javax.wsdl, org.apache.cxf.bus, org.apache.cxf.bus.spring, org.apache.cxf.bus.resource, org.apache.cxf.configuration.spring, org.apache.cxf.resource, org.springframework.beans.factory.config, * </Import-Package>
     ...
   </instructions>
  </configuration>
</plugin>
Copy to Clipboard Toggle word wrap

A.3.9. 더 많은 정보

번들 플러그인 구성에 대한 자세한 내용은 다음을 참조하십시오.

V 부. Cryostat-WS를 사용하여 애플리케이션 개발

이 가이드에서는 표준 Cryostat-WS API를 사용하여 웹 서비스를 개발하는 방법을 설명합니다.

24장. 상향식 서비스 개발

초록

서비스 지향 애플리케이션의 일부로 노출하려는 기능 세트를 이미 구현하는 Java 코드가 있는 많은 인스턴스가 있습니다. 또한 단순히 WSDL을 사용하여 인터페이스를 정의하는 것을 피하려고 할 수도 있습니다. Cryostat-WS 주석을 사용하면 Java 클래스를 활성화하는 데 필요한 정보를 추가할 수 있습니다. WSDL 계약 대신 사용할 수 있는 SEI( Service Endpoint Interface )를 생성할 수도 있습니다. WSDL 계약을 원하는 경우 Apache CXF는 주석이 달린 Java 코드에서 계약을 생성하는 툴을 제공합니다.

24.1. Cryostat-WS 서비스 개발 소개

Java에서 시작하는 서비스를 생성하려면 다음을 수행해야 합니다.

  1. 24.2절. “SEI 생성” 서비스로 노출하려는 메서드를 정의하는 SEI(Service Endpoint Interface)입니다.

    참고

    Java 클래스에서 직접 작업할 수 있지만 인터페이스에서 작업하는 것이 좋습니다. 인터페이스는 서비스를 사용하는 애플리케이션을 개발하는 개발자와 공유하는 데 더 적합합니다. 인터페이스는 더 작고 서비스의 구현 세부 정보를 제공하지 않습니다.

  2. 24.3절. “코드에 주석 달기” 코드에 필요한 주석입니다.
  3. 24.4절. “WSDL 생성” 서비스에 대한 WSDL 계약입니다.

    참고

    SEI를 서비스 계약으로 사용하려는 경우 WSDL 계약을 생성할 필요가 없습니다.

  4. 31장. 서비스 게시 서비스 공급자로서의 서비스.

24.2. SEI 생성

24.2.1. 개요

서비스 엔드포인트 인터페이스 (SEI)는 서비스 구현과 해당 서비스에 대한 요청을 하는 소비자 간에 공유되는 Java 코드의 일부입니다. SEI는 서비스에서 구현한 메서드를 정의하고 서비스 노출 방법에 대한 세부 정보를 엔드포인트로 제공합니다. WSDL 계약을 시작할 때 코드 생성기에 의해 SEI가 생성됩니다. 그러나 Java에서 시작할 때는 개발자가 SEI를 생성할 책임이 있습니다. SEI를 만드는 데는 두 가지 기본 패턴이 있습니다.

  • 녹색 필드 개발 - 이 패턴에서 기존 Java 코드 또는 WSDL 없이 새 서비스를 개발하고 있습니다. 먼저 SEI를 만드는 것이 가장 좋습니다. 그런 다음 SEI를 사용하는 서비스 공급자 및 소비자를 구현하는 모든 개발자에게 SEI를 배포할 수 있습니다.

    참고

    녹색 필드 서비스 개발을 수행하는 권장 방법은 서비스 및 해당 인터페이스를 정의하는 WSDL 계약을 생성하여 시작하는 것입니다. 26장. 시작 지점 WSDL 계약을 참조하십시오.

  • 서비스 활성화 - 이 패턴에서 일반적으로 Java 클래스로 구현되는 기존 기능 세트가 있으며 서비스 활성화를 원합니다. 즉, 다음 두 가지 작업을 수행해야 합니다.

    1. 서비스의 일부로 노출될 작업 포함하는 SEI를 생성합니다.
    2. SEI를 구현하도록 기존 Java 클래스를 수정합니다.

      참고

      Java 클래스에 Cryostat-WS 주석을 추가할 수는 있지만 권장되지는 않습니다.

24.2.2. 인터페이스 작성

SEI는 표준 Java 인터페이스입니다. 클래스가 구현하는 메서드 집합을 정의합니다. 또한 구현 클래스에 액세스할 수 있는 여러 멤버 필드와 상수를 정의할 수도 있습니다.

SEI의 경우 정의된 메서드는 서비스에 의해 노출되는 작업에 매핑되도록 설계되었습니다. SEI는 wsdl:portType 요소에 해당합니다. SEI에 의해 정의된 방법은 wsdl:portType 요소의 wsdl:operation 요소에 해당합니다.

참고

Cryostat-WS는 서비스의 일부로 노출되지 않는 메서드를 지정할 수 있는 주석을 정의합니다. 그러나 이러한 방법을 SEI에서 벗어나는 것이 가장 좋습니다.

예 24.1. “Simple SEI” 주식 업데이트 서비스에 대한 간단한 SEI를 보여줍니다.

예 24.1. Simple SEI

package com.fusesource.demo;

public interface quoteReporter
{
  public Quote getQuote(String ticker);
}
Copy to Clipboard Toggle word wrap

24.2.3. 인터페이스 구현

SEI는 표준 Java 인터페이스이므로 이를 구현하는 클래스는 표준 Java 클래스입니다. Java 클래스로 시작하는 경우 인터페이스를 구현하도록 수정해야 합니다. SEI로 시작하는 경우 구현 클래스는 SEI를 구현합니다.

예 24.2. “간단한 구현 클래스” 예 24.1. “Simple SEI” 에서 인터페이스를 구현하기 위한 클래스를 표시합니다.

예 24.2. 간단한 구현 클래스

package com.fusesource.demo;

import java.util.*;

public class stockQuoteReporter implements quoteReporter
{
  ...
public Quote getQuote(String ticker)
  {
    Quote retVal = new Quote();
    retVal.setID(ticker);
    retVal.setVal(Board.check(ticker));[1]
    Date retDate = new Date();
    retVal.setTime(retDate.toString());
    return(retVal);
  }
}
Copy to Clipboard Toggle word wrap


[1] Board is an assumed class whose implementation is left to the reader.

24.3. 코드에 주석 달기

24.3.1. Cryostat-WS 주석 개요

Cryostat-WS 주석은 SEI를 완전히 지정된 서비스 정의에 매핑하는 데 사용되는 메타데이터를 지정합니다. 주석에 제공된 정보는 다음과 같습니다.

  • 서비스의 대상 네임스페이스입니다.
  • 요청 메시지를 보유하는 데 사용되는 클래스의 이름입니다.
  • 응답 메시지를 보관하는 데 사용되는 클래스의 이름입니다.
  • 작업이 한 가지 방법인 경우
  • 서비스에서 사용하는 바인딩 스타일
  • 사용자 정의 예외에 사용되는 클래스의 이름입니다.
  • 서비스에서 사용하는 유형이 정의된 네임스페이스
참고

대부분의 주석에는 합리적인 기본값이 있으며 값을 제공할 필요가 없습니다. 그러나 주석에 더 많은 정보를 제공하면 서비스 정의가 더 잘 지정됩니다. 잘 지정된 서비스 정의는 분산 애플리케이션의 모든 부분이 함께 작동할 가능성을 높입니다.

24.3.2. 필수 주석

24.3.2.1. 개요

Java 코드에서 서비스를 생성하려면 코드에 하나의 주석만 추가해야 합니다. SEI 및 구현 클래스 모두에 @WebService 주석을 추가해야 합니다.

24.3.2.2. @WebService 주석

@WebService 주석은 javax.jws.WebService 인터페이스에 의해 정의되며 인터페이스로 배치되며 서비스로 사용하기 위한 클래스 또는 인터페이스에 배치됩니다. @WebService 에는 에 설명된 속성이 있습니다. 표 24.1. “@WebService 속성”

Expand
표 24.1. @WebService 속성
속성설명

name

서비스 인터페이스의 이름을 지정합니다. 이 속성은 WSDL 계약에서 서비스의 인터페이스를 정의하는 wsdl:portType 요소의 name 속성에 매핑됩니다. 기본값은 구현 클래스의 이름에 PortType 을 추가하는 것입니다. [a]

targetNamespace

서비스가 정의된 대상 네임스페이스를 지정합니다. 이 속성을 지정하지 않으면 대상 네임스페이스가 패키지 이름에서 파생됩니다.

serviceName

게시된 서비스의 이름을 지정합니다. 이 속성은 게시된 서비스를 정의하는 wsdl:service 요소의 name 속성에 매핑됩니다. 기본값은 서비스 구현 클래스의 이름을 사용하는 것입니다.

wsdlLocation

서비스의 WSDL 계약이 저장되는 URL을 지정합니다. 상대 URL을 사용하여 지정해야 합니다. 기본값은 서비스가 배포된 URL입니다.

endpointInterface

구현 클래스에서 구현하는 SEI의 전체 이름을 지정합니다. 이 속성은 서비스 구현 클래스에서 속성을 사용할 때만 지정됩니다.

portName

서비스가 게시되는 끝점의 이름을 지정합니다. 이 속성은 게시된 서비스에 대한 엔드포인트 세부 정보를 지정하는 wsdl:port 요소의 name 속성에 매핑됩니다. 기본값은 서비스 구현 클래스의 이름에 포트 추가입니다.

[a] SEI에서 WSDL을 생성하면 구현 클래스 이름 대신 인터페이스 이름이 사용됩니다.
참고

@WebService 주석의 속성에 대해 값을 제공할 필요는 없습니다. 그러나 가능한 한 많은 정보를 제공하는 것이 좋습니다.

24.3.2.3. SEI 주석 처리

SEI에서 @WebService 주석을 추가해야 합니다. SEI는 서비스를 정의하는 계약이므로 @WebService 주석의 속성에 대해 가능한 한 자세히 지정해야 합니다.

예 24.3. “@WebService 주석과 인터페이스” @WebService 주석을 사용하여 예 24.1. “Simple SEI” 에 정의된 인터페이스를 표시합니다.

예 24.3. @WebService 주석과 인터페이스

package com.fusesource.demo;

import javax.jws.*;

@WebService(name="quoteUpdater",
            targetNamespace="http://demos.redhat.com",
	        serviceName="updateQuoteService",
            wsdlLocation="http://demos.redhat.com/quoteExampleService?wsdl",
            portName="updateQuotePort")
public interface quoteReporter
{
  public Quote getQuote(String ticker);
}
Copy to Clipboard Toggle word wrap

예 24.3. “@WebService 주석과 인터페이스”@WebService 주석은 다음을 수행합니다.

서비스 인터페이스를 정의하는 wsdl:portType 요소의 name 속성 값이 quoteUpdater 임을 지정합니다.

서비스의 대상 네임스페이스가 http://demos.redhat.com 임을 지정합니다.

게시된 서비스를 정의하는 wsdl:service 요소의 name 값이 updateQuoteService 임을 지정합니다.

서비스가 http://demos.redhat.com/quoteExampleService?wsdl 에서 WSDL 계약을 게시하도록 지정합니다.

서비스를 노출하는 엔드포인트를 정의하는 wsdl:port 요소의 name 속성 값이 updateQuotePort 임을 지정합니다.

24.3.2.4. 서비스 구현 주석 처리

@WebService 주석으로 SEI에 주석을 달 수 있는 것 외에도 @WebService 주석을 사용하여 서비스 구현 클래스에 주석을 달아야 합니다. 서비스 구현 클래스에 주석을 추가할 때 endpointInterface 속성만 지정해야 합니다. 예 24.4. “주석이 달린 서비스 구현 클래스” 에 표시된 대로 속성은 SEI의 전체 이름으로 설정해야 합니다.

예 24.4. 주석이 달린 서비스 구현 클래스

package org.eric.demo;

import javax.jws.*;

@WebService(endpointInterface="com.fusesource.demo.quoteReporter")
public class stockQuoteReporter implements quoteReporter
{
public Quote getQuote(String ticker)
  {
  ...
  }
}
Copy to Clipboard Toggle word wrap

24.3.3. 선택적 주석

초록

@WebService 주석은 Java 인터페이스 또는 Java 클래스를 활성화하는 서비스에 충분하지만 서비스가 서비스 공급자로 노출되는 방법을 완전히 설명하지는 않습니다. Cryostat-WS 프로그래밍 모델에서는 사용하는 바인딩과 같은 서비스에 대한 세부 정보를 Java 코드에 추가하기 위해 여러 선택적 주석을 사용합니다. 이러한 주석을 서비스의 SEI에 추가합니다.

SEI에서 제공하는 세부 정보가 많을수록 개발자가 정의한 기능을 사용할 수 있는 애플리케이션을 더 쉽게 구현할 수 있습니다. 또한 툴에 의해 생성된 WSDL 문서를 보다 구체적으로 만듭니다.

24.3.3.1. 개요

주석을 사용하여 바인딩 속성 정의

서비스에 Cryostat 바인딩을 사용하는 경우 Cryostat-WS 주석을 사용하여 여러 바인딩 속성을 지정할 수 있습니다. 이러한 속성은 서비스의 WSDL 계약에 지정할 수 있는 속성에 직접 해당합니다. 매개 변수 스타일과 같은 일부 설정은 메서드를 구현하는 방법을 제한할 수 있습니다. 이러한 설정은 메서드 매개변수에 주석을 달 때 사용할 수 있는 주석에도 영향을 미칠 수 있습니다.

24.3.3.2. @SOAPBinding 주석

@SOAPBinding 주석은 javax.jws.soap.SOAPBinding 인터페이스에서 정의합니다. 배포 시 서비스에서 사용하는 Cryostat 바인딩에 대한 세부 정보를 제공합니다. @SOAPBinding 주석을 지정하지 않으면 래핑된 doc/literal#159 바인딩을 사용하여 서비스가 게시됩니다.

@SOAPBinding 주석을 SEI 및 SEI의 메서드에 배치할 수 있습니다. 메서드에서 사용하는 경우 메서드의 @SOAPBinding 주석 설정이 우선합니다.

표 24.2. “@SOAPBinding 속성” @SOAPBinding 주석의 속성을 표시합니다.

Expand
표 24.2. @SOAPBinding 속성
속성설명

style

style.DOCUMENT(기본값)

Style.RPC

Cryostat 메시지의 스타일을 지정합니다. RPC 스타일이 지정되면 Cryostat 본문 내의 각 메시지 부분은 매개변수 또는 반환 값이며 soap:body 요소 내의 래퍼 요소 내에 표시됩니다. 래퍼 요소 내의 메시지 부분은 작업 매개변수에 해당하며 작업의 매개변수와 동일한 순서로 표시되어야 합니다. DOCUMENT 스타일이 지정되면 Cryostat 본문의 내용은 유효한 XML 문서여야 하지만 해당 양식은 엄격하게 제한되지 않습니다.

사용

use.LITERAL (기본값)

사용.ENCODED[a]

Cryostat 메시지의 데이터를 스트리밍하는 방법을 지정합니다.

parameterStyle [b]

ParameterStyle.BARE

ParameterStyle.WRAPPED (기본값)

WSDL 계약의 메시지 부분에 해당하는 메서드 매개 변수를 Cryostat 메시지 본문에 배치하는 방법을 지정합니다. BARE가 지정되면 각 매개변수가 메시지 루트의 자식 요소로 메시지 본문에 배치됩니다. WRAPPED가 지정되면 모든 입력 매개변수가 요청 메시지의 단일 요소로 래핑되고 모든 출력 매개변수는 응답 메시지의 단일 요소로 래핑됩니다.

[a] Use.ENCODED는 현재 지원되지 않습니다.
[b] 스타일을 RPC로 설정하면 WRAPPED 매개변수 스타일을 사용해야 합니다.
24.3.3.3. 베어 스타일 매개변수 문서

문서 베어 스타일은 Java 코드와 서비스의 결과 XML 표현 간의 가장 직접적인 매핑입니다. 이 스타일을 사용할 때 작업의 매개 변수 목록에 정의된 입력 및 출력 매개변수에서 직접 스키마 유형이 생성됩니다.

@SOAPBinding 주석과 함께 style.DOCUMENT로 설정된 해당 style 속성 및 ParameterStyle.BARE로 설정된 parameterStyle 속성을 사용하여 베어 문서\literal 스타일을 사용하도록 지정합니다.

베어 매개 변수를 사용할 때 작업이 문서 스타일 사용에 대한 제한을 위반하지 않도록 하려면 다음 조건을 준수해야 합니다.

  • 작업에는 입력 또는 input/output 매개변수가 둘 이상 없어야 합니다.
  • 작업에 void 이외의 반환 유형이 있는 경우 출력 또는 입력/출력 매개변수가 없어야 합니다.
  • 작업에 반환 유형이 있는 경우 출력 또는 input/output 매개변수가 두 개 이상 있어야 합니다.
참고

@WebParam 주석 또는 @WebResult 주석을 사용하여 Cryostat 헤더에 배치된 매개변수는 허용된 매개변수 수에 대해 계산되지 않습니다.

24.3.3.4. 문서 래핑된 매개변수

문서 래핑 스타일을 사용하면 Java 코드와 서비스의 결과 XML 표현 간의 매핑과 같은 더 많은 RPC를 사용할 수 있습니다. 이 스타일을 사용할 때 메서드 매개변수 목록의 매개 변수는 바인딩에 따라 단일 요소로 래핑됩니다. 이 문제의 단점은 Java 구현과 메시지가 유선에 배치되는 방법 간의 추가 단방향 계층을 도입한다는 것입니다.

래핑된 문서\literal 스타일을 사용하려면 @SOAPBinding 주석을 style.DOCUMENT로 설정하고 해당 parameterStyle 속성을 ParameterStyle.WRAPPED로 설정합니다.

“@RequestWrapper 주석” 주석 및 “@ResponseWrapper 주석” 주석을 사용하여 래퍼를 생성하는 방법을 일부 제어할 수 있습니다.

24.3.3.5. 예제

예 24.5. “Cryostat 바인딩 주석을 사용하여 문서 Bare#159 바인딩 지정” 문서 베어 Cryostat 메시지를 사용하는 SEI를 표시합니다.

예 24.5. Cryostat 바인딩 주석을 사용하여 문서 Bare#159 바인딩 지정

package org.eric.demo;

import javax.jws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;

@WebService(name="quoteReporter")
@SOAPBinding(parameterStyle=ParameterStyle.BARE)
public interface quoteReporter
{
  ...
}
Copy to Clipboard Toggle word wrap
24.3.3.6. 개요

주석을 사용하여 작업 속성 정의

런타임에서 Java 메서드 정의를 XML 작업 정의에 매핑하면 다음과 같은 세부 정보를 제공합니다.

  • 교환된 메시지는 XML에서와 같습니다.
  • 메시지를 하나의 메시지로 최적화할 수 있는 경우
  • 메시지가 정의된 네임스페이스
24.3.3.7. @WebMethod 주석

@WebMethod 주석은 javax.jws.WebMethod 인터페이스에서 정의합니다. 이는 SEI의 방법에 배치됩니다. @WebMethod 주석은 메서드가 연결된 작업을 설명하는 wsdl:operation 요소에 일반적으로 표시되는 정보를 제공합니다.

표 24.3. “@WebMethod 속성” @WebMethod 주석의 속성을 설명합니다.

Expand
표 24.3. @WebMethod 속성
속성설명

operationName

연결된 wsdl:operation 요소의 이름 값을 지정합니다. 기본값은 메서드의 이름입니다.

작업

메서드에 대해 생성된 soap:operation 요소의 soapAction 속성 값을 지정합니다. 기본값은 빈 문자열입니다.

exclude

메서드를 서비스 인터페이스에서 제외해야 하는지 여부를 지정합니다. 기본값은 false입니다.

24.3.3.8. @RequestWrapper 주석

@RequestWrapper 주석은 javax.xml.ws.RequestWrapper 인터페이스에서 정의합니다. 이는 SEI의 방법에 배치됩니다. @RequestWrapper 주석은 메시지 교환을 시작하는 요청 메시지의 메서드 매개 변수에 대해 래퍼 빈을 구현하는 Java 클래스를 지정합니다. 또한 요청 메시지를 마샬링하고 unmarshalling할 때 런타임에서 사용하는 요소 이름과 네임스페이스를 지정합니다.

표 24.4. “@RequestWrapper 속성” @RequestWrapper 주석의 속성을 설명합니다.

Expand
표 24.4. @RequestWrapper 속성
속성설명

localName

요청 메시지의 XML 표현에서 래퍼 요소의 로컬 이름을 지정합니다. 기본값은 메서드 이름 또는 “@WebMethod 주석” 주석의 operationName 속성 값입니다.

targetNamespace

XML 래퍼 요소가 정의된 네임스페이스를 지정합니다. 기본값은 SEI의 대상 네임스페이스입니다.

className

래퍼 요소를 구현하는 Java 클래스의 전체 이름을 지정합니다.

참고

className 속성만 필요합니다.

중요

메서드에도 @SOAPBinding 주석이 추가되고 해당 parameterStyle 속성이 ParameterStyle.BARE 로 설정된 경우 이 주석은 무시됩니다.

24.3.3.9. @ResponseWrapper 주석

@ResponseWrapper 주석은 javax.xml.ws.ResponseWrapper 인터페이스로 정의됩니다. 이는 SEI의 방법에 배치됩니다. @ResponseWrapper 는 메시지 교환의 응답 메시지에 메서드 매개 변수에 대한 래퍼 빈을 구현하는 Java 클래스를 지정합니다. 또한 응답 메시지를 마샬링하고 unmarshalling할 때 런타임에서 사용하는 요소 이름과 네임스페이스를 지정합니다.

표 24.5. “@ResponseWrapper 속성” @ResponseWrapper 주석의 속성을 설명합니다.

Expand
표 24.5. @ResponseWrapper 속성
속성설명

localName

응답 메시지의 XML 표현에서 래퍼 요소의 로컬 이름을 지정합니다. 기본값은 Response가 추가된 메서드 이름 또는 응답이 추가된 “@WebMethod 주석” 주석의 operationName 속성 값입니다.

targetNamespace

XML 래퍼 요소가 정의된 네임스페이스를 지정합니다. 기본값은 SEI의 대상 네임스페이스입니다.

className

래퍼 요소를 구현하는 Java 클래스의 전체 이름을 지정합니다.

참고

className 속성만 필요합니다.

중요

메서드에도 @SOAPBinding 주석이 추가되고 해당 parameterStyle 속성이 ParameterStyle.BARE 로 설정된 경우 이 주석은 무시됩니다.

24.3.3.10. @WebFault 주석

@WebFault 주석은 javax.xml.ws.WebFault 인터페이스에서 정의합니다. SEI에서 throw하는 예외에 적용됩니다. @WebFault 주석은 Java 예외를 wsdl:fault 요소에 매핑하는 데 사용됩니다. 이 정보는 서비스와 소비자 둘 다에서 처리할 수 있는 표현으로 예외를 마샬링하는 데 사용됩니다.

표 24.6. “@WebFault 속성” @WebFault 주석의 속성을 설명합니다.

Expand
표 24.6. @WebFault 속성
속성설명

name

fault 요소의 로컬 이름을 지정합니다.

targetNamespace

fault 요소가 정의된 네임스페이스를 지정합니다. 기본값은 SEI의 대상 네임스페이스입니다.

faultName

예외를 구현하는 Java 클래스의 전체 이름을 지정합니다.

중요

name 속성이 필요합니다.

24.3.3.11. @Oneway 주석

@Oneway 주석은 javax.jws.Oneway 인터페이스에서 정의합니다. 서비스의 응답이 필요하지 않은 SEI의 메서드에 배치됩니다. @Oneway 주석은 응답을 기다리지 않고 응답을 처리할 리소스를 예약하지 않고 메서드 실행을 최적화할 수 있음을 런타임에 알립니다.

이 주석은 다음 기준을 충족하는 메서드에서만 사용할 수 있습니다.

  • 공백을 반환합니다.
  • Holder 인터페이스를 구현하는 매개변수가 없습니다.
  • 소비자로 다시 전달할 수 있는 예외는 발생하지 않습니다.
24.3.3.12. 예제

예 24.6. “Annotated Methods가 있는 SEI” 는 주석이 달린 SEI를 표시합니다.

예 24.6. Annotated Methods가 있는 SEI

package com.fusesource.demo;

import javax.jws.*;
import javax.xml.ws.*;

@WebService(name="quoteReporter")
public interface quoteReporter
{
  @WebMethod(operationName="getStockQuote")
  @RequestWrapper(targetNamespace="http://demo.redhat.com/types",
                  className="java.lang.String")
  @ResponseWrapper(targetNamespace="http://demo.redhat.com/types",
                   className="org.eric.demo.Quote")
  public Quote getQuote(String ticker);
}
Copy to Clipboard Toggle word wrap
24.3.3.13. 개요

주석을 사용하여 매개변수 속성 정의

SEI의 메서드 매개 변수는 wsdl:message 요소 및 해당 wsdl:part 요소에 해당합니다. Cryostat-WS는 메서드 매개변수에 대해 생성되는 wsdl:part 요소를 설명할 수 있는 주석을 제공합니다.

24.3.3.14. @WebParam 주석

@WebParam 주석은 javax.jws.WebParam 인터페이스에서 정의합니다. SEI에 정의된 메서드의 매개 변수에 배치됩니다. @WebParam 주석을 사용하면 매개변수가 Cryostat 헤더에 배치되고 생성된 wsdl:part 의 기타 속성을 매개 변수의 방향을 지정할 수 있습니다.

표 24.7. “@WebParam 속성” @WebParam 주석의 속성을 설명합니다.

Expand
표 24.7. @WebParam 속성
속성설명

name

 

생성된 WSDL 문서에 표시되는 매개 변수의 이름을 지정합니다. RPC 바인딩의 경우 매개 변수를 나타내는 wsdl:part 의 이름입니다. 문서 바인딩의 경우 매개 변수를 나타내는 XML 요소의 로컬 이름입니다. Cryostat-WS 사양에 따라 기본값은 argN 입니다. 여기서 N 은 0 기반 인수 인덱스(즉, arg0, arg1, 등)로 교체됩니다.

targetNamespace

 

매개변수의 네임스페이스를 지정합니다. 매개 변수가 XML 요소에 매핑되는 문서 바인딩에서만 사용됩니다. 기본값은 서비스의 네임스페이스를 사용하는 것입니다.

mode

mode.IN(기본값)[a]

Mode.OUT

mode.INOUT

매개변수의 방향을 지정합니다.

헤더

false(기본값)

true

매개 변수가 Cryostat 헤더의 일부로 전달되는지 여부를 지정합니다.

partName

 

매개 변수의 wsdl:part 요소의 name 특성 값을 지정합니다. 이 속성은 문서 스타일 Cryostat 바인딩에 사용됩니다.

[a] Holder 인터페이스를 구현하는 모든 매개변수는 기본적으로 Mode.INOUT에 매핑됩니다.
24.3.3.15. @WebResult 주석

@WebResult 주석은 javax.jws.WebResult 인터페이스에서 정의합니다. SEI에 정의된 메서드에 배치됩니다. @WebResult 주석을 사용하면 메서드의 반환 값에 대해 생성된 wsdl:part 의 속성을 지정할 수 있습니다.

표 24.8. “@WebResult 속성” @WebResult 주석의 속성을 설명합니다.

Expand
표 24.8. @WebResult 속성
속성설명

name

생성된 WSDL 문서에 표시되는 반환 값의 이름을 지정합니다. RPC 바인딩의 경우 반환 값을 나타내는 wsdl:part 의 이름입니다. 문서 바인딩의 경우 반환 값을 나타내는 XML 요소의 로컬 이름입니다. 기본값은 return입니다.

targetNamespace

반환 값의 네임스페이스를 지정합니다. 반환 값이 XML 요소에 매핑되는 문서 바인딩에서만 사용됩니다. 기본값은 서비스의 네임스페이스를 사용하는 것입니다.

헤더

반환 값이 Cryostat 헤더의 일부로 전달되는지 여부를 지정합니다.

partName

반환 값에 대한 wsdl:part 요소의 name 특성 값을 지정합니다. 이 속성은 문서 스타일 Cryostat 바인딩에 사용됩니다.

24.3.3.16. 예제

예 24.7. “완전히 주석 처리됨 SEI” 는 완전히 주석이 달린 SEI를 표시합니다.

예 24.7. 완전히 주석 처리됨 SEI

package com.fusesource.demo;

import javax.jws.*;
import javax.xml.ws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;
import javax.jws.WebParam.*;

@WebService(targetNamespace="http://demo.redhat.com",
            name="quoteReporter")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)
public interface quoteReporter
{
  @WebMethod(operationName="getStockQuote")
  @RequestWrapper(targetNamespace="http://demo.redhat.com/types",
                  className="java.lang.String")
  @ResponseWrapper(targetNamespace="http://demo.redhat.com/types",
                   className="org.eric.demo.Quote")
  @WebResult(targetNamespace="http://demo.redhat.com/types",
             name="updatedQuote")
  public Quote getQuote(
                        @WebParam(targetNamespace="http://demo.redhat.com/types",
                                  name="stockTicker",
                                  mode=Mode.IN)
                        String ticker
  );
}
Copy to Clipboard Toggle word wrap

24.3.4. Apache CXF 주석

24.3.4.1. WSDL 문서

24.3.4.1.1. @WSDL설명서 주석

@WSDL설명서 주석은 org.apache.cxf.annotations.WSDL설명서 인터페이스로 정의됩니다. SEI 또는 SEI 방법에 배치할 수 있습니다.

이 주석을 사용하면 SEI가 WSDL로 변환된 후 wsdl:documentation 요소에 표시되는 문서를 추가할 수 있습니다. 기본적으로 문서 요소는 포트 유형 내에 표시되지만 배치 속성을 지정하여 문서가 WSDL 파일의 다른 위치에 표시되도록 할 수 있습니다. 24.3.4.2절. “@WSDL설명서 속성” @WSDL설명서 주석에서 지원하는 속성을 표시합니다.

24.3.4.2. @WSDL설명서 속성
Expand
속성설명

value

(필수) 문서 텍스트가 포함된 문자열입니다.

배치

(선택 사항) WSDL 파일에서 이 문서가 표시되는 위치를 지정합니다. 사용 가능한 배치 값 목록은 “WSDL 계약에 배치” 을 참조하십시오.

faultClass

(선택 사항) 배치가 FAULT_MESSAGE,PORT_TYPE_OPERATION_FAULT 또는 BINDING_OPERATION_FAULT 로 설정된 경우 이 속성을 오류를 나타내는 Java 클래스로 설정해야 합니다.

24.3.4.2.1. @WSDLDocumentationCollection 주석

@WSDLDocumentationCollection 주석은 org.apache.cxf.annotations.WSDLDocumentationCollection 인터페이스에 의해 정의됩니다. SEI 또는 SEI 방법에 배치할 수 있습니다.

이 주석은 단일 배치 위치 또는 다양한 배치 위치에 여러 문서 요소를 삽입하는 데 사용됩니다.

24.3.4.2.2. WSDL 계약에 배치

WSDL 계약에 문서가 표시되는 위치를 지정하려면 WSDL설명서.Placement 유형의 배치 속성을 지정할 수 있습니다. 배치에는 다음 값 중 하나가 있을 수 있습니다.

  • WSDLDocumentation.Placement.BINDING
  • WSDLDocumentation.Placement.BINDING_OPERATION
  • WSDLDocumentation.Placement.BINDING_OPERATION_FAULT
  • WSDLDocumentation.Placement.BINDING_OPERATION_INPUT
  • WSDLDocumentation.Placement.BINDING_OPERATION_OUTPUT
  • WSDLDocumentation.Placement.DEFAULT
  • WSDLDocumentation.Placement.FAULT_MESSAGE
  • WSDLDocumentation.Placement.INPUT_MESSAGE
  • WSDLDocumentation.Placement.OUTPUT_MESSAGE
  • WSDLDocumentation.Placement.PORT_TYPE
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION_FAULT
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION_INPUT
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION_OUTPUT
  • WSDLDocumentation.Placement.SERVICE
  • WSDLDocumentation.Placement.SERVICE_PORT
  • WSDLDocumentation.Placement.TOP
24.3.4.2.3. @WSDL설명서 예

24.3.4.3절. “@WSDL설명서 사용” SEI 및 해당 메서드 중 하나에 @WSDL설명서 주석을 추가하는 방법을 보여줍니다.

24.3.4.3. @WSDL설명서 사용
@WebService
@WSDLDocumentation("A very simple example of an SEI")
public interface HelloWorld {
    @WSDLDocumentation("A traditional form of greeting")
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap

24.3.4.4절. “문서를 사용하여 생성된 WSDL” 에 표시된 WSDL이 24.3.4.3절. “@WSDL설명서 사용” 의 SEI에서 생성되는 경우 문서 요소의 기본 배치는 각각 PORT_TYPEPORT_TYPE_OPERATION 입니다.

24.3.4.4. 문서를 사용하여 생성된 WSDL
<wsdl:definitions ... >
  ...
  <wsdl:portType name="HelloWorld">
    <wsdl:documentation>A very simple example of an SEI</wsdl:documentation>
    <wsdl:operation name="sayHi">
      <wsdl:documentation>A traditional form of greeting</wsdl:documentation>
      <wsdl:input name="sayHi" message="tns:sayHi">
    </wsdl:input>
      <wsdl:output name="sayHiResponse" message="tns:sayHiResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>
Copy to Clipboard Toggle word wrap
24.3.4.4.1. @WSDLDocumentationCollection의 예

24.3.4.5절. “@WSDLDocumentationCollection 사용” SEI에 @WSDLDocumentationCollection 주석을 추가하는 방법을 보여줍니다.

24.3.4.5. @WSDLDocumentationCollection 사용
@WebService
@WSDLDocumentationCollection(
    {
        @WSDLDocumentation("A very simple example of an SEI"),
        @WSDLDocumentation(value = "My top level documentation",
                           placement = WSDLDocumentation.Placement.TOP),
        @WSDLDocumentation(value = "Binding documentation",
                           placement = WSDLDocumentation.Placement.BINDING)
    }
)
public interface HelloWorld {
    @WSDLDocumentation("A traditional form of Geeky greeting")
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.6. 메시지의 스키마 유효성 검사

24.3.4.6.1. @SchemaValidation 주석

@SchemaValidation 주석은 org.apache.cxf.annotations.SchemaValidation 인터페이스에서 정의됩니다. SEI 및 개별 SEI 방법에 배치 할 수 있습니다.

이 주석은 이 엔드포인트로 전송된 XML 메시지의 스키마 유효성 검사를 켜집니다. 이 기능은 들어오는 XML 메시지의 형식에 문제가 있다고 의심되는 경우 테스트 목적에 유용할 수 있습니다. 기본적으로 검증은 성능에 상당한 영향을 미치기 때문에 비활성화되어 있습니다.

24.3.4.6.2. 스키마 검증 유형

스키마 유효성 검사 동작은 type 매개 변수에 의해 제어되며, 해당 값은 org.apache.cxf.annotations.SchemaValidation.SchemaValidationType 유형의 열거입니다. 24.3.4.7절. “스키마 유효성 검사 유형 값” 사용 가능한 검증 유형 목록을 표시합니다.

24.3.4.7. 스키마 유효성 검사 유형 값
Expand
유형설명

IN

클라이언트 및 서버의 수신 메시지에 스키마 유효성 검사를 적용합니다.

OUT

클라이언트 및 서버의 발신 메시지에 스키마 유효성 검사를 적용합니다.

둘 다

클라이언트와 서버의 수신 및 발신 메시지에 스키마 유효성 검사를 적용합니다.

NONE

모든 스키마 유효성 검사는 비활성화되어 있습니다.

REQUEST

메시지 요청에 스키마 검증을 적용합니다. 즉, 검증이 발신 클라이언트 메시지 및 수신 서버 메시지에 적용됩니다.

RESPONSE

응답 메시지에 스키마 유효성 검사를 적용하면 들어오는 클라이언트 메시지 및 발신 서버 메시지에 검증이 적용됩니다.

24.3.4.7.1. 예제

다음 예제에서는 MyService SEI를 기반으로 끝점에 대한 메시지의 스키마 유효성 검사를 활성화하는 방법을 보여줍니다. 주석을 SEI 전체 및 SEI의 개별 메서드에 어떻게 적용할 수 있는지 확인합니다.

@WebService
@SchemaValidation(type = SchemaValidationType.BOTH)
public interface MyService {
    Foo validateBoth(Bar data);

    @SchemaValidation(type = SchemaValidationType.NONE)
    Foo validateNone(Bar data);

    @SchemaValidation(type = SchemaValidationType.IN)
    Foo validateIn(Bar data);

    @SchemaValidation(type = SchemaValidationType.OUT)
    Foo validateOut(Bar data);

    @SchemaValidation(type = SchemaValidationType.REQUEST)
    Foo validateRequest(Bar data);

    @SchemaValidation(type = SchemaValidationType.RESPONSE)
    Foo validateResponse(Bar data);
}
Copy to Clipboard Toggle word wrap
24.3.4.8. 데이터 바인딩 지정

24.3.4.8.1. @DataBinding 주석

@DataBinding 주석은 org.apache.cxf.annotations.DataBinding 인터페이스에서 정의합니다. 이는 SEI에 배치됩니다.

이 주석은 데이터 바인딩을 SEI와 연결하는 데 사용되며 기본 CryostatB 데이터 바인딩을 대체합니다. @DataBinding 주석의 값은 데이터 바인딩 ClassName.class를 제공하는 클래스 여야 합니다.

24.3.4.8.2. 지원되는 데이터 바인딩

현재 Apache CXF에서 지원하는 데이터 바인딩은 다음과 같습니다.

  • org.apache.cxf.jaxb.JAXBDataBinding

    (기본값) 표준 Cryostat B 데이터 바인딩입니다.

  • org.apache.cxf.sdo.SDODataBinding

    SDO(Service Data Objects) 데이터 바인딩은 Apache Tuscany SDO 구현을 기반으로 합니다. Maven 빌드 컨텍스트에서 이 데이터 바인딩을 사용하려면 cxf-rt-databinding-sdo 아티팩트에 종속성을 추가해야 합니다.

  • org.apache.cxf.aegis.databinding.AegisDatabinding

    Maven 빌드 컨텍스트에서 이 데이터 바인딩을 사용하려면 cxf-rt-databinding-aegis 아티팩트에 종속성을 추가해야 합니다.

  • org.apache.cxf.xmlbeans.XmlBeansDataBinding

    Maven 빌드 컨텍스트에서 이 데이터 바인딩을 사용하려면 cxf-rt-databinding-xmlbeans 아티팩트에 종속성을 추가해야 합니다.

  • org.apache.cxf.databinding.source.SourceDataBinding

    이 데이터 바인딩은 Apache CXF 코어에 속합니다.

  • org.apache.cxf.databinding.stax.StaxDataBinding

    이 데이터 바인딩은 Apache CXF 코어에 속합니다.

24.3.4.8.3. 예제

24.3.4.9절. “데이터 바인딩 설정” SDO 바인딩을 HelloWorld SEI와 연결하는 방법 표시

24.3.4.9. 데이터 바인딩 설정
@WebService
@DataBinding(org.apache.cxf.sdo.SDODataBinding.class)
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.10. 메시지 압축
24.3.4.10.1. @GZIP 주석

@GZIP 주석은 org.apache.cxf.annotations.GZIP 인터페이스에서 정의합니다. 이는 SEI에 배치됩니다.

메시지의 GZIP 압축을 활성화합니다. GZIP는 협상된 개선 사항입니다. 즉, 클라이언트의 초기 요청이 압축되지 않지만 Accept 헤더가 추가되고 서버가 GZIP 압축을 지원하는 경우 응답이 압축되고 후속 요청도 발생합니다.

24.3.4.11절. “@GZIP 속성” @GZIP 주석에서 지원하는 선택적 속성을 표시합니다.

24.3.4.11. @GZIP 속성
Expand
속성설명

임계값

이 속성에서 지정한 크기보다 작은 메시지는 gzip이 아닙니다. 기본값은 -1(제한 없음)입니다.

24.3.4.11.1. @FastInfoset

@FastInfoset 주석은 org.apache.cxf.annotations.FastInfoset 인터페이스에서 정의합니다. 이는 SEI에 배치됩니다.

메시지에 FastInfoset 형식을 사용할 수 있습니다. FastInfoset은 XML의 바이너리 인코딩 형식이며 메시지 크기와 XML 메시지의 처리 성능을 모두 최적화하는 것을 목표로 합니다. 자세한 내용은 Fast Infoset 의 다음 Sun 문서를 참조하십시오.

FastInfoset은 협상된 개선 사항입니다. 즉, 클라이언트의 초기 요청은 FastInfoset 형식이 아니지만 Accept 헤더가 추가되고 서버가 FastInfoset을 지원하는 경우 응답이 FastInfoset에 있고 후속 요청도 발생합니다.

24.3.4.12절. “@FastInfoset 속성” @FastInfoset 주석에서 지원하는 선택적 속성을 표시합니다.

24.3.4.12. @FastInfoset 속성
Expand
속성설명

force

협상 대신 FastInfoset 형식을 강제로 사용하는 부울 속성입니다. true 인 경우 FastInfoset 형식을 강제로 사용합니다. 그렇지 않으면 협상합니다. 기본값은 false 입니다.

24.3.4.12.1. @GZIP 예

24.3.4.13절. “GZIP 활성화” HelloWorld SEI에 대해 GZIP 압축을 활성화하는 방법을 보여줍니다.

24.3.4.13. GZIP 활성화
@WebService
@GZIP
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.13.1. @FastInfoset 시험

24.3.4.14절. “FastInfoset 활성화” HelloWorld SEI에 대해 FastInfoset 형식을 활성화하는 방법을 보여줍니다.

24.3.4.14. FastInfoset 활성화
@WebService
@FastInfoset
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.15. 끝점에서 로깅 활성화

24.3.4.15.1. @logging 주석

@Logging 주석은 org.apache.cxf.annotations.Logging 인터페이스에서 정의합니다. 이는 SEI에 배치됩니다.

이 주석은 SEI와 연결된 모든 끝점에 로깅할 수 있습니다. 24.3.4.16절. “@logging 속성” 이 주석에서 설정할 수 있는 선택적 속성을 표시합니다.

24.3.4.16. @logging 속성
Expand
속성설명

제한

로그에서 메시지를 잘린 것 이상으로 크기 제한을 지정합니다. 기본값은 64K입니다.

inLocation

들어오는 메시지를 기록할 위치를 지정합니다. < stderr > , < stdout > , < logger > 또는 파일 이름일 수 있습니다. 기본값은 < logger> 입니다.

outLocation

발신 메시지를 기록할 위치를 지정합니다. < stderr > , < stdout > , < logger > 또는 파일 이름일 수 있습니다. 기본값은 < logger> 입니다.

24.3.4.16.1. 예제

24.3.4.17절. “주석을 사용하여 로깅 구성” HelloWorld SEI에 대한 로깅을 활성화하는 방법을 보여줍니다. 여기서 들어오는 메시지가 < stdout >으로 전송되고 발신 메시지가 < logger >로 전송됩니다.

24.3.4.17. 주석을 사용하여 로깅 구성
@WebService
@Logging(limit=16000, inLocation="<stdout>")
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.18. 끝점에 속성 및 정책 추가

초록

속성 및 정책을 사용하여 구성 데이터를 엔드포인트와 연결할 수 있습니다. 여기서 중요한 차이점은 속성은 Apache CXF 특정 구성 메커니즘이지만 정책은 표준 WSDL 구성 메커니즘이라는 것입니다. 정책은 일반적으로 WS 사양 및 표준에서 시작되며 일반적으로 WSDL 계약에 표시되는 wsdl:policy 요소를 정의하여 설정합니다. 반면 속성은 Apache CXF 특정이며 일반적으로 Apache CXF Spring 구성 파일에서 jaxws:properties 요소를 정의하여 설정합니다.

그러나 여기에 설명된 대로 주석을 사용하여 Java에서 속성 설정 및 WSDL 정책 설정을 정의할 수도 있습니다.

24.3.4.19. 속성 추가
24.3.4.19.1. @EndpointProperty 주석

@EndpointProperty 주석은 org.apache.cxf.annotations.EndpointProperty 인터페이스에서 정의합니다. 이는 SEI에 배치됩니다.

이 주석은 Apache CXF별 구성 설정을 엔드포인트에 추가합니다. 끝점 속성은 Spring 구성 파일에 지정할 수도 있습니다. 예를 들어 엔드포인트에서 WS-Security를 구성하려면 다음과 같이 Spring 구성 파일에서 jaxws:properties 요소를 사용하여 엔드포인트 속성을 추가할 수 있습니다.

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jaxws="http://cxf.apache.org/jaxws"
   ... >

   <jaxws:endpoint
      id="MyService"
      address="https://localhost:9001/MyService"
      serviceName="interop:MyService"
      endpointName="interop:MyServiceEndpoint"
      implementor="com.foo.MyService">

      <jaxws:properties>
         <entry key="ws-security.callback-handler" value="interop.client.UTPasswordCallback"/>
         <entry key="ws-security.signature.properties" value="etc/keystore.properties"/>
         <entry key="ws-security.encryption.properties" value="etc/truststore.properties"/>
         <entry key="ws-security.encryption.username" value="useReqSigCert"/>
      </jaxws:properties>

   </jaxws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap

또는 24.3.4.20절. “@EndpointProperty 주석을 사용하여 WS-Security 구성” 에 표시된 대로 @EndpointProperty 주석을 SEI에 추가하여 Java에서 이전 구성 설정을 지정할 수 있습니다.

24.3.4.20. @EndpointProperty 주석을 사용하여 WS-Security 구성
@WebService
@EndpointProperty(name="ws-security.callback-handler" value="interop.client.UTPasswordCallback")
@EndpointProperty(name="ws-security.signature.properties" value="etc/keystore.properties")
@EndpointProperty(name="ws-security.encryption.properties" value="etc/truststore.properties")
@EndpointProperty(name="ws-security.encryption.username" value="useReqSigCert")
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.20.1. @EndpointProperties 주석

@EndpointProperties 주석은 org.apache.cxf.annotations.EndpointProperties 인터페이스에서 정의합니다. 이는 SEI에 배치됩니다.

이 주석은 여러 개의 @EndpointProperty 주석을 목록으로 그룹화하는 방법을 제공합니다. @EndpointProperties 를 사용하면 24.3.4.20절. “@EndpointProperty 주석을 사용하여 WS-Security 구성” 에 표시된 대로 24.3.4.21절. “@EndpointProperties 주석을 사용하여 WS-Security 구성” 를 다시 작성할 수 있습니다.

24.3.4.21. @EndpointProperties 주석을 사용하여 WS-Security 구성
@WebService
@EndpointProperties(
  {
  @EndpointProperty(name="ws-security.callback-handler" value="interop.client.UTPasswordCallback"),
  @EndpointProperty(name="ws-security.signature.properties" value="etc/keystore.properties"),
  @EndpointProperty(name="ws-security.encryption.properties" value="etc/truststore.properties"),
  @EndpointProperty(name="ws-security.encryption.username" value="useReqSigCert")
})
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.22. 정책 추가
24.3.4.22.1. @policy 주석

@Policy 주석은 org.apache.cxf.annotations.Policy 인터페이스에서 정의합니다. SEI 또는 SEI 방법에 배치할 수 있습니다.

이 주석은 WSDL 정책을 SEI 또는 SEI 메서드와 연결하는 데 사용됩니다. 정책은 표준 wsdl:policy 요소가 포함된 XML 파일을 참조하는 URI를 제공하여 지정합니다. WSDL 계약이 SEI(예: java2ws 명령줄 도구 사용)에서 생성되는 경우 이 정책을 WSDL에 포함할지 여부를 지정할 수 있습니다.

24.3.4.23절. “@policy 속성” @Policy 주석에서 지원하는 속성을 표시합니다.

24.3.4.23. @policy 속성
Expand
속성설명

uri

(필수) 정책 정의가 포함된 파일의 위치입니다.

includeInWSDL

(선택 사항) WSDL을 생성할 때 생성된 계약에 정책을 포함할지 여부입니다. 기본값은 true 입니다.

배치

(선택 사항) WSDL 파일에서 이 문서가 표시되는 위치를 지정합니다. 사용 가능한 배치 값 목록은 “WSDL 계약에 배치” 을 참조하십시오.

faultClass

(선택 사항) 배치가 BINDING_OPERATION_FAULT 또는 PORT_TYPE_OPERATION_FAULT 로 설정된 경우 이 정책이 적용되는 오류를 지정하도록 이 속성을 설정해야 합니다. 값은 오류를 나타내는 Java 클래스입니다.

24.3.4.23.1. @policies 주석

@Policies 주석은 org.apache.cxf.annotations.Policies 인터페이스에서 정의합니다. SEI 또는 SEI 방법에 배치 할 수 있습니다.

이 주석은 여러 개의 @Policy 주석을 목록으로 그룹화하는 방법을 제공합니다.

24.3.4.23.2. WSDL 계약에 배치

WSDL 계약에 정책이 표시되는 위치를 지정하려면 Policy.Placement 유형인 placement 속성을 지정할 수 있습니다. 배치에는 다음 값 중 하나가 있을 수 있습니다.

Policy.Placement.BINDING
Policy.Placement.BINDING_OPERATION
Policy.Placement.BINDING_OPERATION_FAULT
Policy.Placement.BINDING_OPERATION_INPUT
Policy.Placement.BINDING_OPERATION_OUTPUT
Policy.Placement.DEFAULT
Policy.Placement.PORT_TYPE
Policy.Placement.PORT_TYPE_OPERATION
Policy.Placement.PORT_TYPE_OPERATION_FAULT
Policy.Placement.PORT_TYPE_OPERATION_INPUT
Policy.Placement.PORT_TYPE_OPERATION_OUTPUT
Policy.Placement.SERVICE
Policy.Placement.SERVICE_PORT
Copy to Clipboard Toggle word wrap
24.3.4.23.3. @Policy 예

다음 예제에서는 WSDL 정책을 HelloWorld SEI와 연결하는 방법과 정책을 sayHi 방법과 연결하는 방법을 보여줍니다. 정책 자체는 주석policies 디렉터리의 파일 시스템의 XML 파일에 저장됩니다.

@WebService
@Policy(uri = "annotationpolicies/TestImplPolicy.xml",
        placement = Policy.Placement.SERVICE_PORT),
@Policy(uri = "annotationpolicies/TestPortTypePolicy.xml",
        placement = Policy.Placement.PORT_TYPE)
public interface HelloWorld {
    @Policy(uri = "annotationpolicies/TestOperationPTPolicy.xml",
            placement = Policy.Placement.PORT_TYPE_OPERATION),
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap
24.3.4.23.4. @Policies의 예

다음 예와 같이 @Policies 주석을 사용하여 여러 @Policy 주석을 목록으로 그룹화할 수 있습니다.

@WebService
@Policies({
    @Policy(uri = "annotationpolicies/TestImplPolicy.xml",
            placement = Policy.Placement.SERVICE_PORT),
    @Policy(uri = "annotationpolicies/TestPortTypePolicy.xml",
            placement = Policy.Placement.PORT_TYPE)
})
public interface HelloWorld {
    @Policy(uri = "annotationpolicies/TestOperationPTPolicy.xml",
            placement = Policy.Placement.PORT_TYPE_OPERATION),
    String sayHi(@WebParam(name = "text") String text);
}
Copy to Clipboard Toggle word wrap

24.4. WSDL 생성

24.4.1. Maven 사용

코드에 주석을 달면 java2ws Maven 플러그인의 -wsdl 옵션을 사용하여 서비스에 대한 WSDL 계약을 생성할 수 있습니다. java2ws Maven 플러그인에 대한 자세한 옵션 목록은 44.3절. “java2ws” 에서 참조하십시오.

예 24.8. “Java에서 WSDL 생성” WSDL을 생성하기 위해 java2ws Maven 플러그인을 설정하는 방법을 보여줍니다.

예 24.8. Java에서 WSDL 생성

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-java2ws-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>process-classes</id>
      <phase>process-classes</phase>
      <configuration>
        <className>className</className>
        <genWsdl>true</genWsdl>
      </configuration>
      <goals>
        <goal>java2ws</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Copy to Clipboard Toggle word wrap
참고

className 값을 정규화된 className으로 바꿉니다.

24.4.2. 예제

예 24.9. “SEI에서 생성된 WSDL” 다음은 예 24.7. “완전히 주석 처리됨 SEI” 에 표시된 SEI에 대해 생성되는 WSDL 계약을 표시합니다.

예 24.9. SEI에서 생성된 WSDL

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://demo.eric.org/"
          xmlns:tns="http://demo.eric.org/"
		  xmlns:ns1=""
		  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
		  xmlns:ns2="http://demo.eric.org/types"
		  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
		  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <xsd:schema>
      <xs:complexType name="quote">
        <xs:sequence>
          <xs:element name="ID" type="xs:string" minOccurs="0"/>
          <xs:element name="time" type="xs:string" minOccurs="0"/>
          <xs:element name="val" type="xs:float"/>
        </xs:sequence>
      </xs:complexType>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="getStockQuote">
    <wsdl:part name="stockTicker" type="xsd:string">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getStockQuoteResponse">
    <wsdl:part name="updatedQuote" type="tns:quote">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="quoteReporter">
    <wsdl:operation name="getStockQuote">
      <wsdl:input name="getQuote" message="tns:getStockQuote">
    </wsdl:input>
      <wsdl:output name="getQuoteResponse" message="tns:getStockQuoteResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="quoteReporterBinding" type="tns:quoteReporter">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getStockQuote">
      <soap:operation style="rpc" />
      <wsdl:input name="getQuote">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getQuoteResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="quoteReporterService">
    <wsdl:port name="quoteReporterPort" binding="tns:quoteReporterBinding">
      <soap:address location="http://localhost:9000/quoteReporterService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
Copy to Clipboard Toggle word wrap

25장. WSDL 계약 없이 소비자 개발

초록

서비스 소비자를 개발하는 데 WSDL 계약이 필요하지 않습니다. 주석이 달린 SEI에서 서비스 소비자를 생성할 수 있습니다. SEI와 함께 서비스를 노출하는 끝점이 게시되는 주소, 서비스를 노출하는 엔드포인트를 정의하는 서비스 요소의 QName, 소비자가 요청하는 끝점을 정의하는 port 요소의 QName을 알아야 합니다. 이 정보는 SEI의 주석에 지정되거나 별도로 제공될 수 있습니다.

25.1. Java-First 소비자 개발

WSDL 계약 없이 소비자를 생성하려면 다음을 수행해야 합니다.

25.2. 서비스 오브젝트 생성

25.2.1. 개요

javax.xml.ws.Service 클래스는 서비스를 노출하는 모든 끝점의 정의가 포함된 wsdl:service 요소를 나타냅니다. 따라서 서비스에서 원격 호출을 수행하기 위한 프록시인 wsdl:port 요소에 의해 정의된 엔드포인트를 가져올 수 있는 메서드를 제공합니다.

참고

Service 클래스는 XML 문서를 사용하는 대신 클라이언트 코드가 Java 형식으로 작업할 수 있도록 하는 추상화를 제공합니다.

25.2.2. create() 메서드

Service 클래스에는 새 Service 개체를 만드는 데 사용할 수 있는 두 개의 정적 create() 메서드가 있습니다. 예 25.1. “Service create() Methods” 에 표시된 대로 두 create() 메서드는 Service 오브젝트가 나타내는 wsdl:service 요소의 QName을 사용하고, 하나는 WSDL 계약의 위치를 지정하는 URI를 사용합니다.

참고

모든 서비스는 WSDL 계약을 게시합니다. Cryostat/HTTP 서비스의 경우 URI는 일반적으로 ?wsdl.wsdl이 추가된 서비스에 대한 URI입니다.

예 25.1. Service create() Methods

공용 정적서비스생성URLwsdlLocationQNameserviceNameWebServiceExceptionpublic staticServicecreateQNameserviceNameWebServiceException

serviceName 매개변수의 값은 QName입니다. 네임스페이스 부분 값은 서비스의 대상 네임스페이스입니다. 서비스의 대상 네임스페이스는 @WebService 주석의 targetNamespace 속성에 지정됩니다. QName의 로컬 부분의 값은 wsdl:service 요소의 name 속성 값입니다. 다음 방법 중 하나로 이 값을 확인할 수 있습니다. . @WebService 주석의 serviceName 속성에 지정됩니다.

  1. Service@WebService 주석의 name 속성 값에 추가합니다.
  2. SEI 이름에 서비스를 추가합니다.
중요

OSGi 환경에 배포된 프로그래밍 방식으로 생성된 CXF 소비자는 ClassNotFoundExceptions가 발생할 가능성을 방지하기 위해 특별한 처리가 필요합니다. 프로그래밍 방식으로 생성된 CXF 소비자가 포함된 각 번들에 싱글톤 CXF 기본 버스를 생성하고 모든 번들의 CXF 소비자가 이를 사용하는지 확인해야 합니다. 이 보호 장치가 없으면 하나의 번들에 다른 번들에서 생성된 CXF 기본 버스가 할당되어 상속 번들에 실패할 수 있습니다.

예를 들어 번들 A에서 CXF 기본 버스를 명시적으로 설정하지 않았으며 번들 B에서 생성된 CXF 기본 버스가 할당되었다고 가정합니다. 번들 A의 CXF 버스를 추가 기능(예: SSL 또는 WS-Security)으로 구성하거나 번들 A에서 애플리케이션의 특정 클래스 또는 리소스를 로드해야 하는 경우 실패합니다. 이는 CXF 버스 인스턴스가 스레드 컨텍스트 클래스 로더(TCCL)를 생성한 번들의 번들 클래스 로더(이 경우 번들 B)로 설정하기 때문입니다. 또한 CXF의 WS-Security 구현과 같은 특정 프레임워크는 TCCL을 사용하여 번들 내부에서 calback 처리기 클래스 또는 기타 속성 파일과 같은 리소스를 로드합니다. 번들 A에는 번들 B의 기본 CXF 버스가 할당되어 있고 TCCL이므로 ws4j 계층에서 번들 A에서 필요한 리소스를 로드할 수 없으므로 ClassNotFoundException 오류가 발생합니다.

Singleton CXF 기본 버스를 생성하려면 “예제” 와 같이 서비스 오브젝트를 생성하는 기본 방법의 시작 부분에 이 코드를 삽입합니다.

BusFactory.setThreadDefaultBus(BusFactory.newInstance().createBus());
Copy to Clipboard Toggle word wrap

25.2.3. 예제

예 25.2. “서비스 오브젝트 생성” 예 24.7. “완전히 주석 처리됨 SEI” 에 표시된 SEI의 서비스 오브젝트를 생성하는 코드를 보여줍니다.

예 25.2. 서비스 오브젝트 생성

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    BusFactory.setThreadDefaultBus(BusFactory.newInstance().createBus());
    QName serviceName = new QName("http://demo.redhat.com", "stockQuoteReporter");
    Service s = Service.create(serviceName);
   ...
  }
}
Copy to Clipboard Toggle word wrap

예 25.2. “서비스 오브젝트 생성” 의 코드는 다음을 수행합니다.

서비스의 모든 CXF 사용자가 사용할 수 있는 싱글톤 CXF 기본 버스를 생성합니다.

targetNamespace 속성 및 @WebService 주석의 name 속성을 사용하여 서비스의 QName을 빌드합니다.

단일 매개 변수 create() 메서드를 호출하여 새 Service 오브젝트를 생성합니다.

참고

단일 매개변수 create() 를 사용하면 WSDL 계약에 액세스하는 데 대한 종속성을 가질 수 없습니다.

25.3. 서비스에 포트 추가

25.3.1. 개요

서비스에 대한 엔드포인트 정보는 wsdl:port 요소에 정의되어 있으며 Service 오브젝트는 WSDL 계약에 정의된 각 끝점에 대한 프록시 인스턴스를 생성합니다. Service 개체를 만들 때 WSDL 계약을 지정하지 않으면 Service 오브젝트에 서비스를 구현하는 엔드포인트에 대한 정보가 없으므로 프록시 인스턴스를 생성할 수 없습니다. 이 경우 addPort() 메서드를 사용하여 wsdl:port 요소를 나타내는 데 필요한 정보를 Service 오브젝트에 제공해야 합니다.

25.3.2. addPort() 메서드

서비스 클래스는 예 25.3. “addPort() 메서드” 에 표시된 addPort() 메서드를 정의합니다. 이는 소비자 구현에 사용할 수 있는 WSDL 계약이 없는 경우 사용됩니다. addPort() 메서드를 사용하면 Service 오브젝트에 서비스 구현을 위한 프록시를 생성하는 데 필요한 일반적으로 wsdl:port 요소에 저장되는 정보를 제공할 수 있습니다.

예 25.3. addPort() 메서드

addPortQNameportNameStringbindingIdStringendpointAddressWebServiceException

portName 의 값은 QName입니다. 네임스페이스 부분 값은 서비스의 대상 네임스페이스입니다. 서비스의 대상 네임스페이스는 @WebService 주석의 targetNamespace 속성에 지정됩니다. QName의 로컬 부분의 값은 wsdl:port 요소의 name 속성 값입니다. 다음 방법 중 하나로 이 값을 확인할 수 있습니다.

  1. @WebService 주석의 portName 속성에 지정합니다.
  2. @WebService 주석의 name 속성 값에 Port 를 추가합니다.
  3. SEI 이름에 Port 를 추가합니다.

bindingId 매개변수의 값은 끝점에서 사용하는 바인딩 유형을 고유하게 식별하는 문자열입니다. Cryostat 바인딩의 경우 표준 Cryostat 네임스페이스를 사용합니다. http://schemas.xmlsoap.org/soap/. 끝점이 Cryostat 바인딩을 사용하지 않는 경우 bindingId 매개변수의 값은 바인딩 개발자에 의해 결정됩니다. endpointAddress 매개변수의 값은 끝점이 게시되는 주소입니다. Cryostat/HTTP 끝점의 경우 주소는 HTTP 주소입니다. HTTP 이외의 전송에서는 다른 주소 체계를 사용합니다.

25.3.3. 예제

예 25.4. “서비스 오브젝트에 포트 추가” 예 25.2. “서비스 오브젝트 생성” 에서 생성된 서비스 오브젝트에 포트를 추가하는 코드를 보여줍니다.

예 25.4. 서비스 오브젝트에 포트 추가

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    ...
    QName portName = new QName("http://demo.redhat.com", "stockQuoteReporterPort");
    s.addPort(portName,
              "http://schemas.xmlsoap.org/soap/",
              "http://localhost:9000/StockQuote");
    ...
  }
}
Copy to Clipboard Toggle word wrap

예 25.4. “서비스 오브젝트에 포트 추가” 의 코드는 다음을 수행합니다.

portName 매개변수에 대한 QName을 생성합니다.

addPort() 메서드를 호출합니다.

끝점에서 Cryostat 바인딩을 사용하도록 지정합니다.

끝점이 게시되는 주소를 지정합니다.

25.4. 끝점에 대한 프록시 가져오기

25.4.1. 개요

서비스 프록시는 원격 서비스에서 노출하는 모든 메서드를 제공하고 원격 호출을 수행하는 데 필요한 모든 세부 정보를 처리하는 오브젝트입니다. Service 오브젝트는 getPort() 메서드를 통해 인식하는 모든 끝점에 대한 서비스 프록시를 제공합니다. 서비스 프록시가 있으면 해당 메서드를 호출할 수 있습니다. 프록시는 서비스 계약에 지정된 연결 세부 정보를 사용하여 호출을 원격 서비스 엔드포인트로 전달합니다.

25.4.2. getPort() 메서드

예 25.5. “getPort() 메서드” 에 표시된 getPort() 메서드는 지정된 끝점에 대한 서비스 프록시를 반환합니다. 반환된 프록시는 SEI와 동일한 클래스입니다.

예 25.5. getPort() 메서드

public &lt;T> TgetPortQNameportNameClass<T>serviceEndpointInterfaceWebServiceException

portName 매개변수 값은 프록시가 생성되는 끝점을 정의하는 wsdl:port 요소를 식별하는 QName입니다. serviceEndpointInterface 매개변수의 값은 SEI의 정규화된 이름입니다.

참고

WSDL 계약 없이 작업하는 경우 portName 매개변수의 값은 일반적으로 addPort() 를 호출할 때 portName 매개변수에 사용되는 값과 동일합니다.

25.4.3. 예제

예 25.6. “서비스 프록시 가져오기” 예 25.4. “서비스 오브젝트에 포트 추가” 에 추가된 끝점의 서비스 프록시를 가져오는 코드를 보여줍니다.

예 25.6. 서비스 프록시 가져오기

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    ...
    quoteReporter proxy = s.getPort(portName, quoteReporter.class);
    ...
  }
}
Copy to Clipboard Toggle word wrap

25.5. 소비자의 비즈니스 논리 구현

25.5.1. 개요

원격 엔드포인트에 대한 서비스 프록시를 인스턴스화하면 로컬 오브젝트인 것처럼 메서드를 호출할 수 있습니다. 호출은 원격 메서드가 완료될 때까지 차단됩니다.

참고

@OneWay 주석으로 메서드에 주석을 달면 호출이 즉시 반환됩니다.

25.5.2. 예제

예 25.7. “WSDL 계약 없이 구현됨” 예 24.7. “완전히 주석 처리됨 SEI” 에 정의된 서비스의 소비자를 표시합니다.

예 25.7. WSDL 계약 없이 구현됨

package com.fusesource.demo;

import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    QName serviceName = new QName("http://demo.eric.org", "stockQuoteReporter");
  Service s = Service.create(serviceName);

    QName portName = new QName("http://demo.eric.org", "stockQuoteReporterPort");
  s.addPort(portName, "http://schemas.xmlsoap.org/soap/", "http://localhost:9000/EricStockQuote");

  quoteReporter proxy = s.getPort(portName, quoteReporter.class);

  Quote quote = proxy.getQuote("ALPHA");
    System.out.println("Stock "+quote.getID()+" is worth "+quote.getVal()+" as of "+quote.getTime());
  }
}
Copy to Clipboard Toggle word wrap

예 25.7. “WSDL 계약 없이 구현됨” 의 코드는 다음을 수행합니다.

Service 오브젝트를 생성합니다.

Service 오브젝트에 끝점 정의를 추가합니다.

Service 오브젝트에서 서비스 프록시를 가져옵니다.

서비스 프록시에서 작업을 호출합니다.

26장. 시작 지점 WSDL 계약

26.1. WSDL 계약 샘플

예 26.1. “helloworld WSDL 계약” HelloWorld WSDL 계약을 표시합니다. 이 계약은 wsdl:portType 요소에서 단일 인터페이스 Greeter를 정의합니다. 계약에는 wsdl:port 요소에서 서비스를 구현할 끝점도 정의합니다.

예 26.1. helloworld WSDL 계약

<?xml version="1.0" encoding=";UTF-8"?>
<wsdl:definitions name="HelloWorld"
                  targetNamespace="http://apache.org/hello_world_soap_http"
                  xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:tns="http://apache.org/hello_world_soap_http"
                  xmlns:x1="http://apache.org/hello_world_soap_http/types"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <schema targetNamespace="http://apache.org/hello_world_soap_http/types"
            xmlns="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">
      <element name="sayHiResponse">
        <complexType>
          <sequence>
            <element name="responseType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMe">
        <complexType>
          <sequence>
            <element name="requestType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMeResponse">
        <complexType>
          <sequence>
            <element name="responseType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMeOneWay">
        <complexType>
          <sequence>
            <element name="requestType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="pingMe">
        <complexType/>
      </element>
      <element name="pingMeResponse">
        <complexType/>
      </element>
      <element name="faultDetail">
        <complexType>
          <sequence>
            <element name="minor" type="short"/>
            <element name="major" type="short"/>
          </sequence>
        </complexType>
      </element>
    </schema>
  </wsdl:types>

  <wsdl:message name="sayHiRequest">
    <wsdl:part element="x1:sayHi" name="in"/>
  </wsdl:message>
  <wsdl:message name="sayHiResponse">
    <wsdl:part element="x1:sayHiResponse" name="out"/>
  </wsdl:message>
  <wsdl:message name="greetMeRequest">
    <wsdl:part element="x1:greetMe" name="in"/>
  </wsdl:message>
  <wsdl:message name="greetMeResponse">
    <wsdl:part element="x1:greetMeResponse" name="out"/>
  </wsdl:message>
  <wsdl:message name="greetMeOneWayRequest">
    <wsdl:part element="x1:greetMeOneWay" name="in"/>
  </wsdl:message>
  <wsdl:message name="pingMeRequest">
    <wsdl:part name="in" element="x1:pingMe"/>
  </wsdl:message>
  <wsdl:message name="pingMeResponse">
    <wsdl:part name="out" element="x1:pingMeResponse"/>
  </wsdl:message>
  <wsdl:message name="pingMeFault">
    <wsdl:part name="faultDetail" element="x1:faultDetail"/>
  </wsdl:message>

  <wsdl:portType name="Greeter">
    <wsdl:operation name="sayHi">
      <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
      <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
    </wsdl:operation>

    <wsdl:operation name="greetMe">
      <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
      <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
    </wsdl:operation>

    <wsdl:operation name="greetMeOneWay">
      <wsdl:input message="tns:greetMeOneWayRequest" name="greetMeOneWayRequest"/>
    </wsdl:operation>

    <wsdl:operation name="pingMe">
      <wsdl:input name="pingMeRequest" message="tns:pingMeRequest"/>
      <wsdl:output name="pingMeResponse" message="tns:pingMeResponse"/>
      <wsdl:fault name="pingMeFault" message="tns:pingMeFault"/>
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
    ...
  </wsdl:binding>

  <wsdl:service name="SOAPService">
    <wsdl:port binding="tns:Greeter_SOAPBinding" name="SoapPort">
      <soap:address location="http://localhost:9000/SoapContext/SoapPort"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
Copy to Clipboard Toggle word wrap

예 26.1. “helloworld WSDL 계약” 에 정의된 Greeter 인터페이스는 다음 작업을 정의합니다.

sayHi - xsd:string 의 단일 출력 매개 변수입니다.

CryostatMe - 입력 매개 변수, xsd:string, 출력 매개 변수인 xsd:string 이 있습니다.

CryostatMeOneWay - 단일 입력 매개변수인 xsd:string 이 있습니다. 이 작업에는 출력 매개 변수가 없으므로 단방향 호출(즉, 소비자는 서버의 응답을 기다리지 않음)으로 최적화됩니다.

PingMe - 입력 매개 변수와 출력 매개 변수는 없지만 오류 예외를 발생시킬 수 있습니다.

27장. 주요 서비스 개발

초록

서비스 공급자를 개발하는 하향식 메서드에서 WSDL 문서부터 시작하여 서비스 공급자가 구현할 작업 및 방법을 정의합니다. WSDL 문서를 사용하여 서비스 공급자에 대한 시작점 코드를 생성합니다. 생성된 코드에 비즈니스 논리를 추가하는 작업은 일반 Java 프로그래밍 API를 사용하여 수행됩니다.

27.1. Cryostat-WS 서비스 공급자 개발 개요

WSDL 문서가 있으면 Cryostat-WS 서비스 공급자를 개발하는 프로세스는 다음과 같습니다.

  1. 27.2절. “시작 지점 코드 생성” 시작 지점 코드입니다.
  2. 서비스 공급자의 작업을 구현 합니다.
  3. 31장. 서비스 게시 구현된 서비스입니다.

27.2. 시작 지점 코드 생성

27.2.1. 개요

Cryostat-WS는 WSDL에 정의된 서비스에서 해당 서비스를 서비스 공급자로 구현할 Java 클래스로의 자세한 매핑을 지정합니다. wsdl:portType 요소에서 정의하는 논리 인터페이스는 서비스 엔드포인트 인터페이스(SEI)에 매핑됩니다. WSDL에 정의된 모든 복잡한 유형은 JAXB(Java Architecture for XML Binding) 사양에 의해 정의된 매핑 뒤에 있는 Java 클래스에 매핑됩니다. wsdl:service 요소에서 정의한 엔드포인트도 사용자가 서비스를 구현하는 서비스 공급자에 액세스하는 데 사용하는 Java 클래스로 생성됩니다.

cxf-codegen-plugin Maven 플러그인은 이 코드를 생성합니다. 또한 구현을 위한 시작점 코드를 생성하기 위한 옵션을 제공합니다. 코드 생성기는 생성된 코드를 제어하기 위한 다양한 옵션을 제공합니다.

27.2.2. 코드 생성기 실행

예 27.1. “서비스 코드 생성” 코드 생성기를 사용하여 서비스에 대한 시작점 코드를 생성하는 방법을 보여줍니다.

예 27.1. 서비스 코드 생성

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                <sourceRoot>outputDir</sourceRoot>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>wsdl</wsdl>
                        <extraargs>
                            <extraarg>-server</extraarg>
                            <extraarg>-impl</extraarg>
                        </extraargs>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
       </execution>
    </executions>
</plugin>
Copy to Clipboard Toggle word wrap

이는 다음을 수행합니다.

  • impl 옵션은 WSDL 계약의 각 wsdl:portType 요소에 대한 쉘 구현 클래스를 생성합니다.
  • -server 옵션은 서비스 공급자를 독립 실행형 애플리케이션으로 실행하는 간단한 main() 을 생성합니다.
  • sourceRoot 는 생성된 코드가 outputDir 이라는 디렉터리에 작성되도록 지정합니다.
  • WSDL 요소는 코드가 생성되는 WSDL 계약을 지정합니다.

코드 생성기에 대한 전체 옵션 목록은 44.2절. “cxf-codegen-plugin” 을 참조하십시오.

27.2.3. 생성된 코드

표 27.1. “서비스 공급자를 위한 생성된 클래스” 서비스 공급자를 생성하기 위해 생성된 파일에 대해 설명합니다.

Expand
표 27.1. 서비스 공급자를 위한 생성된 클래스
파일설명

portTypeName.java

SEI입니다. 이 파일에는 서비스 공급자가 구현하는 인터페이스가 포함되어 있습니다. 이 파일을 편집해서는 안 됩니다.

serviceName.java

엔드포인트입니다. 이 파일에는 사용자가 서비스에서 요청하는 데 사용하는 Java 클래스가 포함되어 있습니다.

portTypeNameImpl.java

Skeleton 구현 클래스입니다. 이 파일을 수정하여 서비스 공급자를 빌드합니다.

portTypeNameServer.java

서비스 공급자를 독립형 프로세스로 배포할 수 있는 기본 서버 메인라인입니다. 자세한 내용은 31장. 서비스 게시 에서 참조하십시오.

또한 코드 생성기는 WSDL 계약에 정의된 모든 유형에 대한 Java 클래스를 생성합니다.

27.2.4. 생성된 패키지

생성된 코드는 WSDL 계약에 사용되는 네임스페이스를 기반으로 패키지에 배치됩니다. 서비스를 지원하기 위해 생성된 클래스( wsdl:portType 요소, wsdl:service 요소, wsdl:port 요소)는 WSDL 계약의 대상 네임스페이스를 기반으로 패키지에 배치됩니다. 계약의 유형 요소에 정의된 형식을 구현하기 위해 생성된 클래스는 types 요소의 targetNamespace 특성을 기반으로 패키지에 배치됩니다.

매핑 알고리즘은 다음과 같습니다.

  1. 선행 http:// 또는 urn:// 는 네임스페이스에서 제거됩니다.
  2. 네임스페이스의 첫 번째 문자열이 유효한 인터넷 도메인인 경우(예: .com 또는 .gov ) . gov로 종료되는 경우 앞에 있는 문자열이 제거되고 나머지 두 구성 요소는 플립됩니다.
  3. 네임스페이스의 최종 문자열이 .xxx 또는 .xx 패턴의 파일 확장자로 종료되면 확장자가 제거됩니다.
  4. 네임스페이스의 나머지 문자열은 결과 문자열에 추가되고 점으로 구분됩니다.
  5. 모든 문자는 소문자로 설정됩니다.

27.3. 서비스 공급자 구현

27.3.1. 구현 코드 생성

코드 생성기의 -impl 플래그를 사용하여 서비스 공급자를 빌드하는 데 사용되는 구현 클래스를 생성합니다.

참고

서비스 계약에 XML 스키마로 정의된 사용자 지정 형식이 포함된 경우 해당 유형의 클래스가 생성되고 사용 가능한지 확인해야 합니다.

코드 생성기 사용에 대한 자세한 내용은 44.2절. “cxf-codegen-plugin” 을 참조하십시오.

27.3.2. 생성된 코드

구현 코드는 다음 두 파일로 구성됩니다.

  • portTypeName.java - 서비스의 서비스 인터페이스(SEI)입니다.
  • portTypeNameImpl.java - 서비스에서 정의한 작업을 구현하는 데 사용할 클래스입니다.

27.3.3. 작업의 논리 구현

서비스 작업에 대한 비즈니스 논리를 제공하려면 portTypeNameImpl.java 의 스텁 메서드를 완료합니다. 일반적으로 표준 Java를 사용하여 비즈니스 논리를 구현합니다. 서비스에서 사용자 지정 XML 스키마 유형을 사용하는 경우 각 유형에 대해 생성된 클래스를 사용하여 조작해야 합니다. 일부 고급 기능에 액세스하는 데 사용할 수 있는 일부 Apache CXF 특정 API도 있습니다.

27.3.4. 예제

예를 들어 예 26.1. “helloworld WSDL 계약” 에 정의된 서비스의 구현 클래스는 예 27.2. “Greeter 서비스 구현” 와 같을 수 있습니다. 굵은 글꼴로 강조 표시된 코드 부분만 해당 speaker에서 삽입해야 합니다.

예 27.2. Greeter 서비스 구현

package demo.hw.server;

import org.apache.hello_world_soap_http.Greeter;

@javax.jws.WebService(portName = "SoapPort", serviceName = "SOAPService",
                      targetNamespace = "http://apache.org/hello_world_soap_http",
                      endpointInterface = "org.apache.hello_world_soap_http.Greeter")

public class GreeterImpl implements Greeter {

    public String greetMe(String me) {
       System.out.println("Executing operation greetMe"); System.out.println("Message received: " + me + "\n"); return "Hello " + me;
    }

    public void greetMeOneWay(String me) {
       System.out.println("Executing operation greetMeOneWay\n"); System.out.println("Hello there " + me);
    }

    public String sayHi() {
       System.out.println("Executing operation sayHi\n"); return "Bonjour";
    }

    public void pingMe() throws PingMeFault {
       FaultDetail faultDetail = new FaultDetail(); faultDetail.setMajor((short)2); faultDetail.setMinor((short)1); System.out.println("Executing operation pingMe, throwing PingMeFault exception\n"); throw new PingMeFault("PingMeFault raised by server", faultDetail);
    }
}
Copy to Clipboard Toggle word wrap

28장. WSDL 계약에서 소비자 개발

초록

소비자를 생성하는 한 가지 방법은 WSDL 계약에서 시작하는 것입니다. 계약은 소비자가 요청하는 서비스의 작업, 메시지 및 전송 세부 정보를 정의합니다. 소비자의 시작점 코드는 WSDL 계약에서 생성됩니다. 소비자가 요구하는 기능은 생성된 코드에 추가됩니다.

28.1. Stub 코드 생성

28.1.1. 개요

cxf-codegen-plugin Maven 플러그인은 WSDL 계약에서 스텁 코드를 생성합니다. 스텁 코드는 원격 서비스에서 작업을 호출하는 데 필요한 지원 코드를 제공합니다.

소비자의 경우 cxf-codegen-plugin Maven 플러그인은 다음과 같은 유형의 코드를 생성합니다.

  • 스텁 코드 - 소비자 구현을 위한 파일 지원.
  • 시작 지점 코드 - 원격 서비스에 연결하고 원격 서비스에서 모든 작업을 호출하는 샘플 코드입니다.

28.1.2. 소비자 코드 생성

소비자 코드를 생성하려면 cxf-codegen-plugin Maven 플러그인을 사용합니다. 예 28.1. “소비자 코드 생성” 코드 생성기를 사용하여 소비자 코드를 생성하는 방법을 보여줍니다.

예 28.1. 소비자 코드 생성

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
        <sourceRoot>outputDir</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>wsdl</wsdl>
            <extraargs>
              <extraarg>-client</extraarg>
            </extraargs>
          </wsdlOption>
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Copy to Clipboard Toggle word wrap

여기서 outputDir 은 생성된 파일이 배치되고 wsdl 이 WSDL 계약의 위치를 지정하는 디렉터리의 위치입니다. -client 옵션은 소비자의 main() 메서드에 대한 시작점 코드를 생성합니다.

cxf-codegen-plugin Maven 플러그인에 사용할 수 있는 인수의 전체 목록은 44.2절. “cxf-codegen-plugin” 에서 참조하십시오.

28.1.3. 생성된 코드

코드 생성 플러그인은 예 26.1. “helloworld WSDL 계약” 에 표시된 계약에 대해 다음 Java 패키지를 생성합니다.

  • org.apache.hello_world_soap_http - 이 패키지는 http://apache.org/hello_world_soap_http 대상 네임스페이스에서 생성됩니다. 이 네임스페이스에 정의된 모든 WSDL 엔터티(예: Greeter 포트 유형 및 CryostatService 서비스)는 Java 패키지에 매핑됩니다.
  • org.apache.hello_world_soap_http.types - 이 패키지는 http://apache.org/hello_world_soap_http/types 대상 네임스페이스에서 생성됩니다. 이 네임스페이스에 정의된 모든 XML 유형(즉, HelloWorld 계약의 wsdl:types 요소에 정의된 모든)은 이 Java 패키지의 Java 클래스에 매핑됩니다.

cxf-codegen-plugin Maven 플러그인에서 생성한 스텁 파일은 다음 카테고리로 분류됩니다.

  • org.apache.hello_world_soap_http 패키지의 WSDL 엔터티를 나타내는 클래스입니다. 다음 클래스는 WSDL 엔터티를 나타내기 위해 생성됩니다.

    • Cryostater - Greeter wsdl:portType 요소를 나타내는 Java 인터페이스입니다. Cryostat-WS 용어에서 이 Java 인터페이스는 서비스 엔드포인트 인터페이스(SEI)입니다.
    • CryostatService - CryostatService wsdl:service 요소를 나타내는 Java 서비스 클래스( javax.xml.ws.Service라고도 함)입니다.
    • PingMeFault - pingMeFault wsdl:fault 요소를 나타내는 Java 예외 클래스( java.lang.Exceptionextending)입니다.
  • org.objectweb.hello_world_soap_http.types 패키지에서 XML 유형을 나타내는 클래스입니다. HelloWorld 예제에서 유일하게 생성된 유형은 요청 및 응답 메시지에 대한 다양한 래퍼입니다. 이러한 데이터 유형 중 일부는 비동기 호출 모델에 유용합니다.

28.2. 소비자 구현

28.2.1. 개요

WSDL 계약에서 시작할 때 소비자를 구현하려면 다음 스텁을 사용해야 합니다.

  • 서비스 클래스
  • SEI

소비자 코드는 이러한 스텁을 사용하여 원격 서비스에 대한 요청을 만들기 위해 서비스 프록시를 인스턴스화합니다. 또한 소비자의 비즈니스 논리를 구현합니다.

28.2.2. 생성된 서비스 클래스

예 28.2. “생성된 서비스 클래스의 개요” 생성된 서비스 클래스의 일반적인 개요인 ServiceName_Service를 보여줍니다.[2]javax.xml.ws.Service 기본 클래스를 확장합니다.

예 28.2. 생성된 서비스 클래스의 개요

@WebServiceClient(name="..." targetNamespace="..."
                  wsdlLocation="...")
public class ServiceName extends javax.xml.ws.Service
{
  ...
  public ServiceName(URL wsdlLocation, QName serviceName) { }

  public ServiceName() { }

  // Available only if you specify '-fe cxf' option in wsdl2java
  public ServiceName(Bus bus) { }

  @WebEndpoint(name="...")
  public SEI getPortName() { }
  .
  .
  .
}
Copy to Clipboard Toggle word wrap

예 28.2. “생성된 서비스 클래스의 개요”ServiceName 클래스는 다음 메서드를 정의합니다.

  • ServiceName(URL wsdlLocation, QName serviceName) - wsdl:service 요소의 데이터를 기반으로 wsdl:service 요소의 데이터를 기반으로 wsdlLocation 에서 가져올 수 있는 WSDL 서비스의 QName ServiceName 서비스를 기반으로 서비스 오브젝트를 구성합니다.
  • ServiceName() - 기본 생성자입니다. 스텁 코드가 생성된 시점(예: wsdl2java 툴을 실행할 때) 제공되는 서비스 이름과 WSDL 계약을 기반으로 서비스 오브젝트를 구성합니다. 이 생성자를 사용하면 WSDL 계약이 지정된 위치에서 계속 사용할 수 있다고 가정합니다.
  • ServiceName(Bus bus) - (CXF 특정) 서비스를 구성하는 데 사용되는 버스 인스턴스를 지정할 수 있는 추가 생성자입니다. 이 기능은 여러 버스 인스턴스를 다른 스레드와 연결할 수 있는 다중 스레드 애플리케이션의 컨텍스트에서 유용할 수 있습니다. 이 생성자는 사용자가 지정한 버스가 이 서비스와 함께 사용되는지 확인하는 간단한 방법을 제공합니다. wsdl2java 툴을 호출할 때 -fe cxf 옵션을 지정하는 경우에만 사용할 수 있습니다.
  • GetPortName() - PortName 과 같은 name 특성을 사용하여 wsdl:port 요소에서 정의한 엔드포인트에 대한 프록시를 반환합니다. ServiceName 서비스에서 정의한 모든 wsdl:port 요소에 대해 getter 방법이 생성됩니다. 여러 끝점 정의가 포함된 wsdl:service 요소는 여러 getPortName() 메서드를 사용하여 생성된 서비스 클래스를 생성합니다.

28.2.3. 서비스 끝점 인터페이스

원래 WSDL 계약에 정의된 모든 인터페이스에 대해 해당 SEI를 생성할 수 있습니다. 서비스 끝점 인터페이스는 wsdl:portType 요소의 Java 매핑입니다. 원래 wsdl:portType 요소에 정의된 각 작업은 SEI의 해당 메서드에 매핑됩니다. 작업의 매개변수는 다음과 같이 매핑됩니다. . 입력 매개 변수는 메서드 인수에 매핑됩니다.

  1. 첫 번째 출력 매개변수는 반환 값에 매핑됩니다.
  2. 출력 매개 변수가 두 개 이상 있는 경우 두 번째 및 후속 출력 매개변수는 메서드 인수에 매핑됩니다(자세한 내용은 이러한 인수의 값을 Holder 유형을 사용하여 전달해야 함).

예를 들어 예 28.3. “Greeter 서비스 엔드 포인트 인터페이스”예 26.1. “helloworld WSDL 계약” 에 정의된 wsdl:portType 요소에서 생성되는 Greeter SEI를 표시합니다. 단순화를 위해 예 28.3. “Greeter 서비스 엔드 포인트 인터페이스” 는 표준 CryostatB 및 Cryostat-WS 주석을 생략합니다.

예 28.3. Greeter 서비스 엔드 포인트 인터페이스

package org.apache.hello_world_soap_http;
  ...
public interface Greeter
{
  public String sayHi();
  public String greetMe(String requestType);
  public void greetMeOneWay(String requestType);
  public void pingMe() throws PingMeFault;
}
Copy to Clipboard Toggle word wrap

28.2.4. 소비자 기본 기능

예 28.4. “소비자 구현 코드” HelloWorld 소비자를 구현하는 코드를 표시합니다. 소비자는 LokiService 서비스의 SoapPort 포트에 연결한 다음 Greeter 포트 유형에서 지원하는 각 작업을 호출합니다.

예 28.4. 소비자 구현 코드

package demo.hw.client;

import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import org.apache.hello_world_soap_http.Greeter;
import org.apache.hello_world_soap_http.PingMeFault;
import org.apache.hello_world_soap_http.SOAPService;

public final class Client {

  private static final QName SERVICE_NAME =
  new QName("http://apache.org/hello_world_soap_http",
            "SOAPService");

  private Client()
  {
  }

  public static void main(String args[]) throws Exception
  {
 if (args.length == 0)
    {
      System.out.println("please specify wsdl");
      System.exit(1);
    }

 URL wsdlURL;
    File wsdlFile = new File(args[0]);
    if (wsdlFile.exists())
    {
      wsdlURL = wsdlFile.toURL();
    }
    else
    {
      wsdlURL = new URL(args[0]);
    }

    System.out.println(wsdlURL);
 SOAPService ss = new SOAPService(wsdlURL,SERVICE_NAME);
 Greeter port = ss.getSoapPort();
    String resp;

 System.out.println("Invoking sayHi...");
    resp = port.sayHi();
    System.out.println("Server responded with: " + resp);
    System.out.println();

    System.out.println("Invoking greetMe...");
    resp = port.greetMe(System.getProperty("user.name"));
    System.out.println("Server responded with: " + resp);
    System.out.println();

    System.out.println("Invoking greetMeOneWay...");
    port.greetMeOneWay(System.getProperty("user.name"));
    System.out.println("No response from server as method is OneWay");
    System.out.println();

 try {
      System.out.println("Invoking pingMe, expecting exception...");
      port.pingMe();
    } catch (PingMeFault ex) {
      System.out.println("Expected exception: PingMeFault has occurred.");
      System.out.println(ex.toString());
    }
    System.exit(0);
  }
}
Copy to Clipboard Toggle word wrap

예 28.4. “소비자 구현 코드” 의 client.main() 방법은 다음과 같습니다.

Apache CXF 런타임 클래스가 클래스 경로에 있는 경우 런타임이 암시적으로 초기화됩니다. Apache CXF를 초기화하기 위해 특수 함수를 호출할 필요가 없습니다.

소비자는 HelloWorld에 대한 WSDL 계약의 위치를 제공하는 단일 문자열 인수를 예상합니다. WSDL 계약의 위치는 wsdlURL 에 저장됩니다.

WSDL 계약의 위치 및 서비스 이름이 필요한 생성자를 사용하여 서비스 오브젝트를 생성합니다. 적절한 getPortName() 메서드를 호출하여 필요한 포트의 인스턴스를 가져옵니다. 이 경우 CryostatService 서비스는 Greeter 서비스 엔드포인트 인터페이스를 구현하는 SoapPort 포트만 지원합니다.

소비자는 Greeter 서비스 엔드포인트 인터페이스에서 지원하는 각 방법을 호출합니다.

pingMe() 메서드의 경우 예제 코드는 PingMeFault 오류 예외를 catch하는 방법을 보여줍니다.

28.2.5. -fe cxf 옵션으로 생성된 클라이언트 프록시

wsdl2java에 -fe cxf 옵션을 지정하여 클라이언트 프록시를 생성하는 경우( cxf frontend를 선택하여) 생성된 클라이언트 프록시 코드가 Java 7과 더 잘 통합됩니다. 이 경우 getServiceNamePort() 메서드를 호출하면 SEI의 하위 인터페이스인 유형을 반환하고 다음과 같은 추가 인터페이스를 구현합니다.

  • java.lang.AutoCloseable
  • javax.xml.ws.BindingProvider (JAX-WS 2.0)
  • org.apache.cxf.endpoint.Client

클라이언트 프록시 작업을 간소화하는 방법을 보려면 표준 Cryostat-WS 프록시 오브젝트를 사용하여 작성된 다음 Java 코드 샘플을 고려하십시오.

// Programming with standard JAX-WS proxy object
//
(ServiceNamePortType port = service.getServiceNamePort();
((BindingProvider)port).getRequestContext()
        .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
port.serviceMethod(...);
((Closeable)port).close();
Copy to Clipboard Toggle word wrap

이전 코드를 cxf frontend에서 생성한 코드를 사용하여 작성된 다음 동일한 코드 샘플과 비교합니다.

// Programming with proxy generated using '-fe cxf' option
//
try (ServiceNamePortTypeProxy port = service.getServiceNamePort()) {
    port.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address);
    port.serviceMethod(...);
}
Copy to Clipboard Toggle word wrap


[2] wsdl:service 요소의 name 속성이 Service로 종료되면 _Service는 사용되지 않습니다.

29장. 런타임에 WSDL 찾기

초록

WSDL 문서의 위치를 애플리케이션에 하드 코딩하는 것은 확장할 수 없습니다. 실제 배포 환경에서는 WSDL 문서의 위치를 런타임 시 해석하도록 허용할 것입니다. Apache CXF는 이를 가능하게 하는 다양한 툴을 제공합니다.

29.1. WSDL 문서를 찾는 메커니즘

Cryostat-WS API를 사용하여 소비자를 개발할 때 서비스를 정의하는 WSDL 문서에 하드 코딩된 경로를 제공해야 합니다. 소규모 환경에서는 이 작업을 수행할 수 있지만 하드 코딩된 경로를 사용하는 것은 엔터프라이즈 배포에서 제대로 작동하지 않습니다.

이 문제를 해결하기 위해 Apache CXF는 하드 코딩된 경로 사용 요구 사항을 제거하기 위한 세 가지 메커니즘을 제공합니다.

참고

프록시를 구현 코드에 삽입하는 것이 가장 쉬운 방법이기 때문에 일반적으로 최상의 옵션입니다. 서비스 프록시를 삽입하고 인스턴스화하기 위한 클라이언트 엔드포인트와 구성 파일만 필요합니다.

29.2. 프록시를 인스턴스화합니다.

29.2.1. 개요

Apache CXF가 Spring Framework를 사용하면 Cryostat-WS API를 사용하여 서비스 프록시를 생성하는 번거로움을 방지할 수 있습니다. 구성 파일에서 클라이언트 끝점을 정의한 다음 구현 코드에 프록시를 직접 삽입할 수 있습니다. 런타임이 구현 오브젝트를 인스턴스화할 때 구성을 기반으로 외부 서비스에 대한 프록시도 인스턴스화합니다. 구현은 인스턴스화된 프록시를 참조하여 전달됩니다.

프록시는 구성 파일의 정보를 사용하여 인스턴스화되므로 WSDL 위치는 하드 코딩할 필요가 없습니다. 배포 시 변경할 수 있습니다. 런타임에서 애플리케이션의 classpath에서 WSDL을 검색하도록 지정할 수도 있습니다.

29.2.2. 절차

외부 서비스의 프록시를 서비스 공급자의 구현에 삽입하려면 다음을 수행합니다.

  1. 애플리케이션의 모든 부분에 액세스할 수 있는 잘 알려진 위치에 필요한 WSDL 문서를 배포합니다.

    참고

    애플리케이션을 WAR 파일로 배포하는 경우 WAR의 internet -INF/wsdl 폴더에 모든 WSDL 문서 및 XML 스키마 문서를 배치하는 것이 좋습니다.

    참고

    애플리케이션을 JAR 파일로 배포하는 경우 JAR의 META-INF/wsdl 폴더에 모든 WSDL 문서 및 XML 스키마 문서를 배치하는 것이 좋습니다.

  2. 삽입 중인 프록시에 대해 Cryostat-WS 클라이언트 끝점을 구성합니다.
  3. @Resource 주석을 사용하여 제공하는 서비스에 프록시를 삽입합니다. ???

29.2.3. 프록시 구성

애플리케이션의 구성 파일에서 jaxws:client 요소를 사용하여 Cryostat-WS 클라이언트 끝점을 구성합니다. 이는 런타임에서 지정된 속성을 사용하여 org.apache.cxf.jaxws.JaxWsClientProxy 오브젝트를 인스턴스화하도록 지시합니다. 이 오브젝트는 서비스 공급자에 삽입될 프록시입니다.

최소한 다음 속성에 대한 값을 제공해야 합니다.

  • ID- Specifies할 클라이언트를 식별하는 데 사용되는 ID입니다.
  • serviceClass- 프록시가 요청을 수행하는 서비스의 SEI를 지정합니다.

예 29.1. “서비스 구현에 삽입할 프록시 구성” Cryostat-WS 클라이언트 끝점에 대한 구성이 표시됩니다.

예 29.1. 서비스 구현에 삽입할 프록시 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:client id="bookClient"
                serviceClass="org.apache.cxf.demo.BookService"
                wsdlLocation="classpath:books.wsdl"/>
  ...
</beans>
Copy to Clipboard Toggle word wrap
참고

예 29.1. “서비스 구현에 삽입할 프록시 구성” 에서 wsdlLocation 속성은 classpath에서 WSDL을 로드하도록 런타임에 지시합니다. book.wsdl 이 classpath에 있으면 런타임에서 찾을 수 있습니다.

Cryostat-WS 클라이언트 구성에 대한 자세한 내용은 17.2절. “소비자 끝점 구성” 을 참조하십시오.

29.2.4. 공급자 구현 코딩

예 29.2. “서비스 구현에 프록시 삽입” 에 표시된 대로 @Resource 를 사용하여 구성된 프록시를 서비스 구현에 리소스로 삽입합니다.

예 29.2. 서비스 구현에 프록시 삽입

package demo.hw.server;

import org.apache.hello_world_soap_http.Greeter;

@javax.jws.WebService(portName = "SoapPort", serviceName = "SOAPService",
                      targetNamespace = "http://apache.org/hello_world_soap_http",
                      endpointInterface = "org.apache.hello_world_soap_http.Greeter")
public class StoreImpl implements Store {

@Resource(name="bookClient") private BookService proxy;

}
Copy to Clipboard Toggle word wrap

주석의 name 속성은 Cryostat-WS 클라이언트의 id 속성 값에 해당합니다. 구성된 프록시는 주석 직후 선언된 BookService 오브젝트에 삽입됩니다. 이 오브젝트를 사용하여 프록시의 외부 서비스에서 호출할 수 있습니다.

29.3. Cryostat-WS 카탈로그 사용

29.3.1. 개요

Cryostat-WS 사양은 모든 구현이 다음을 지원해야 합니다.

웹 서비스 설명, 특히 WSDL 및 XML 스키마 문서에 포함된 웹 서비스 문서를 확인할 때 사용할 표준 카탈로그 기능입니다.

이 카탈로그 기능은 OA Cryostat에서 지정한 XML 카탈로그 기능을 사용합니다. WSDL URI를 사용하는 모든 Cryostat-WS API 및 주석은 카탈로그를 사용하여 WSDL 문서의 위치를 확인합니다.

즉, WSDL 문서의 위치를 특정 배포 환경으로 다시 작성하는 XML 카탈로그 파일을 제공할 수 있습니다.

29.3.2. 카탈로그 작성

Cryostat-WS 카탈로그는 OA Cryostat XML Catalogs 1.1 사양에 정의된 표준 XML 카탈로그 입니다. 매핑을 지정할 수 있습니다.

  • URI에 대한 문서의 공용 식별자 및/또는 시스템 식별자입니다.
  • 다른 URI에 대한 리소스의 URI입니다.

표 29.1. “Common Cryostat-WS Catalog Cryostat” WSDL 위치 확인에 사용되는 몇 가지 공통 요소를 나열합니다.

Expand
표 29.1. Common Cryostat-WS Catalog Cryostat
element설명

uri

URI를 대체 URI에 매핑합니다.

rewriteURI

URI의 시작을 다시 작성합니다. 예를 들어 이 요소를 사용하면 http://cxf.apache.org 로 시작하는 모든 URI를 classpath: 로 시작하는 URI에 매핑할 수 있습니다.

uriSuffix

원래 URI의 접미사를 기반으로 대체 URI에 URI를 매핑합니다. 예를 들어 foo.xsd로 끝나는 모든 URI를 classpath: foo.xsd 에 매핑할 수 있습니다.

29.3.3. 카탈로그 패키지

Cryostat-WS 사양은 WSDL 및 XML 스키마 문서를 해결하는 데 사용되는 카탈로그가 META-INF/jax-ws-catalog.xml 이라는 사용 가능한 모든 리소스를 사용하여 어셈블되도록 합니다. 애플리케이션이 단일 JAR 또는 WAR에 패키지된 경우 카탈로그를 단일 파일에 배치할 수 있습니다.

애플리케이션이 여러 JAR로 패키지된 경우 카탈로그를 여러 파일로 분할할 수 있습니다. 각 카탈로그 파일은 특정 JAR의 코드에서 액세스하는 WSDL만 처리하도록 모듈화할 수 있습니다.

29.4. 계약 확인자 사용

29.4.1. 개요

런타임 시 WSDL 문서 위치를 해결하기 위한 가장 중요한 메커니즘은 사용자 정의 계약 확인자를 구현하는 것입니다. 이를 위해서는 Apache CXF 관련 ServiceContractResolver 인터페이스를 구현해야 합니다. 또한 버스에 사용자 정의 리졸버를 등록해야 합니다.

올바르게 등록되면 사용자 정의 계약 확인자가 필요한 WSDL 및 스키마 문서의 위치를 확인하는 데 사용됩니다.

29.4.2. 계약 확인 프로그램 구현

계약 확인자는 org.apache.cxf.endpoint.ServiceContractResolver 인터페이스의 구현입니다. 예 29.3. “ServiceContractResolver 인터페이스” 에 표시된 것처럼 이 인터페이스에는 구현해야 하는 단일 메서드인 getContractLocation() 이 있습니다. getContractLocation() 은 서비스의 QName을 가져와서 서비스의 WSDL 계약에 대한 URI를 반환합니다.

예 29.3. ServiceContractResolver 인터페이스

public interface ServiceContractResolver
{
   URI getContractLocation(QName qname);
}
Copy to Clipboard Toggle word wrap

WSDL 계약의 위치를 해결하는 데 사용되는 논리는 애플리케이션별로 다릅니다. UDDI 레지스트리, 데이터베이스, 파일 시스템의 사용자 지정 위치 또는 선택한 기타 메커니즘에서 계약 위치를 확인하는 논리를 추가할 수 있습니다.

29.4.3. 프로그래밍 방식으로 계약 확인 프로그램 등록

Apache CXF 런타임에서 계약 확인자를 사용하기 전에 계약 확인자 레지스트리에 등록해야 합니다. 계약 확인자 레지스트리는 org.apache.cxf.endpoint.ServiceContractResolverRegistry 인터페이스를 구현합니다. 그러나 자체 레지스트리를 구현할 필요는 없습니다. Apache CXF는 org.apache.cxf.endpoint.ServiceContractResolverRegistryImpl 클래스에서 기본 구현을 제공합니다.

기본 레지스트리에 계약 확인자를 등록하려면 다음을 수행합니다.

  1. 기본 버스 오브젝트에 대한 참조를 가져옵니다.
  2. 버스의 getExtension() 메서드를 사용하여 버스에서 서비스 계약 레지스트리를 가져옵니다.
  3. 계약 확인자 인스턴스를 생성합니다.
  4. 레지스트리의 register() 메서드를 사용하여 계약 확인자를 레지스트리에 등록합니다.

예 29.4. “계약 해결 프로그램 등록” 기본 레지스트리에 계약 확인자를 등록하기 위한 코드가 표시됩니다.

예 29.4. 계약 해결 프로그램 등록

BusFactory bf=BusFactory.newInstance();
Bus bus=bf.createBus();

ServiceContractResolverRegistry registry = bus.getExtension(ServiceContractResolverRegistry);

JarServiceContractResolver resolver = new JarServiceContractResolver();

registry.register(resolver);
Copy to Clipboard Toggle word wrap

예 29.4. “계약 해결 프로그램 등록” 의 코드는 다음을 수행합니다.

버스 인스턴스를 가져옵니다.

버스의 계약 확인자 레지스트리를 가져옵니다.

계약 확인자의 인스턴스를 만듭니다.

계약 확인 프로그램을 레지스트리에 등록합니다.

29.4.4. 구성을 사용하여 계약 확인 프로그램 등록

구성을 통해 클라이언트에 추가할 수 있도록 계약 해결자를 구현할 수도 있습니다. 계약 확인자는 런타임이 구성을 읽고 해결자를 인스턴스화할 때 확인자가 직접 등록하는 방식으로 구현됩니다. 런타임은 초기화를 처리하므로 클라이언트가 계약 확인자를 사용해야 하는지 런타임에 결정할 수 있습니다.Because the runtime handles the initialization, you can decide at runtime if a client needs to use the contract resolver.

구성을 통해 클라이언트에 추가할 수 있도록 계약 해결자를 구현하려면 다음을 수행합니다.

  1. 계약 확인자 구현에 init() 메서드를 추가합니다.
  2. 예 29.4. “계약 해결 프로그램 등록” 과 같이 계약 확인자를 계약 확인자 레지스트리에 등록하는 init() 메서드에 논리를 추가합니다.
  3. @PostConstruct 주석을 사용하여 init() 메서드를 분리합니다.

예 29.5. “구성을 사용하여 등록할 수 있는 서비스 계약 해결 방법” 구성을 사용하여 클라이언트에 추가할 수 있는 계약 확인자 구현을 표시합니다.

예 29.5. 구성을 사용하여 등록할 수 있는 서비스 계약 해결 방법

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.xml.namespace.QName;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;

public class UddiResolver implements ServiceContractResolver
{
  private Bus bus;
  ...

  @PostConstruct
  public void init()
  {
    BusFactory bf=BusFactory.newInstance();
    Bus bus=bf.createBus();
    if (null != bus)
    {
      ServiceContractResolverRegistry resolverRegistry = bus.getExtension(ServiceContractResolverRegistry.class);
      if (resolverRegistry != null)
      {
        resolverRegistry.register(this);
      }
    }
  }

  public URI getContractLocation(QName serviceName)
  {
    ...
  }
}
Copy to Clipboard Toggle word wrap

계약 확인자를 클라이언트에 등록하려면 클라이언트 구성에 ans 요소를 추가해야 합니다. Cryo stat 요소의 클래스 속성은 계약 확인자를 구현하는 클래스의 이름입니다.

예 29.6. “ans Configuring a Contract Resolver” org.apache.cxf.demos.myContractResolver 클래스에서 구현한 구성 해결자를 추가하기 위한 8080을 표시합니다.

예 29.6. ans Configuring a Contract Resolver

<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.xsd">
  ...
  <bean id="myResolver" class="org.apache.cxf.demos.myContractResolver" />
  ...
</beans>
Copy to Clipboard Toggle word wrap

29.4.5. 계약 해결 순서

새 프록시가 생성되면 런타임은 계약 레지스트리 확인자를 사용하여 원격 서비스의 WSDL 계약을 찾습니다. 계약 확인자 레지스트리는 확인자가 등록된 순서대로 각 계약 확인자의 getContractLocation() 메서드를 호출합니다. 등록된 계약 확인자 중 하나에서 반환된 첫 번째 URI를 반환합니다.

잘 알려진 공유 파일 시스템에서 WSDL 계약을 해결하려고 시도한 계약 확인자를 등록한 경우 사용된 유일한 계약 확인자가 됩니다. 그러나 UDDI 레지스트리를 사용하여 WSDL 위치를 해결한 계약 확인자를 나중에 등록한 경우 레지스트리는 두 해결 방법을 사용하여 서비스의 WSDL 계약을 찾을 수 있습니다. 먼저 레지스트리는 공유 파일 시스템 계약 확인자를 사용하여 계약을 찾습니다. 해당 계약 확인자가 실패하면 레지스트리에서 UDDI 계약 확인자를 사용하여 찾습니다.

30장. 일반 장애 처리

초록

Cryostat-WS 사양은 다음 두 가지 유형의 오류를 정의합니다. 하나는 일반적인 Cryostat-WS 런타임 예외입니다. 다른 하나는 메시지 처리 중에 발생하는 프로토콜 특정 예외 클래스입니다.

30.1. Runtime Faults

30.1.1. 개요

대부분의 Cryostat-WS API는 일반적인 javax.xml.ws.WebServiceException 예외를 생성합니다.

30.1.2. WebServiceException을 throw하는 API

표 30.1. “Throw WebServiceException API” 일반 WebServiceException 예외를 throw할 수 있는 일부 Cryostat-WS API를 나열합니다.

Expand
표 30.1. Throw WebServiceException API
API이유

Binding.setHandlerChain()

처리기 체인 구성에 오류가 있습니다.

BindingProvider.getEndpointReference()

지정된 클래스는 W3CEndpointReference 에서 할당되지 않습니다.

Dispatch.invoke()

Dispatch 인스턴스의 구성 오류 또는 서비스와 통신하는 동안 오류가 발생했습니다.

Dispatch.invokeAsync()

Dispatch 인스턴스의 구성에 오류가 있습니다.

Dispatch.invokeOneWay()

Dispatch 인스턴스의 구성 오류 또는 서비스와 통신하는 동안 오류가 발생했습니다.

LogicalMessage.getPayload()

제공된 Cryostat BContext 를 사용하여 페이로드를 분리할 때 오류가 발생했습니다. WebServiceException의 cause 필드에는 원래 CryostatBException이 포함되어 있습니다.

LogicalMessage.setPayload()

메시지 페이로드를 설정할 때 오류가 발생했습니다. Cryostat BContext 를 사용할 때 예외가 발생하는 경우 WebServiceException의 cause 필드에는 원래 CryostatBException이 포함됩니다.

WebServiceContext.getEndpointReference()

지정된 클래스는 W3CEndpointReference 에서 할당되지 않습니다.

30.2. 프로토콜 폴트

30.2.1. 개요

요청 처리 중에 오류가 발생하면 프로토콜 예외가 발생합니다. 모든 동기 원격 호출은 프로토콜 예외를 throw할 수 있습니다. 근본적인 원인은 소비자의 메시지 처리 체인 또는 서비스 공급자에서 발생합니다.

Cryostat-WS 사양은 일반 프로토콜 예외를 정의합니다. 또한 ESP 특정 프로토콜 예외 및 HTTP 특정 프로토콜 예외를 지정합니다.

30.2.2. 프로토콜 예외 유형

Cryostat-WS 사양은 세 가지 유형의 프로토콜 예외를 정의합니다. catch하는 예외는 애플리케이션에서 사용하는 전송 및 바인딩에 따라 다릅니다.

표 30.2. “일반 프로토콜 유형 예외” 프로토콜 예외의 세 가지 유형과 이러한 예외가 throw되는 시기에 대해 설명합니다.

Expand
표 30.2. 일반 프로토콜 유형 예외
예외 클래스Thrown 시

javax.xml.ws.ProtocolException

이 예외는 일반 프로토콜 예외입니다. 사용 중인 프로토콜에 관계없이 사용할 수 있습니다. Cryostat 바인딩 또는 HTTP 바인딩을 사용하는 경우 특정 오류 유형으로 캐스팅할 수 있습니다. HTTP 또는 JMS 전송과 함께 XML 바인딩을 사용하는 경우 일반 프로토콜 예외를 보다 구체적인 fault 유형으로 캐스팅할 수 없습니다.

javax.xml.ws.soap.SOAPFaultException

이 예외는 Cryostat 바인딩을 사용할 때 원격 호출에 의해 발생합니다. 자세한 내용은 “Cryostat 프로토콜 예외 사용” 에서 참조하십시오.

javax.xml.ws.http.HTTPException

이 예외는 Apache CXF HTTP 바인딩을 사용하여 RESTful 웹 서비스를 개발할 때 발생합니다. 자세한 내용은 VI 부. RESTful 웹 서비스 개발 에서 참조하십시오.

30.2.3. Cryostat 프로토콜 예외 사용

CryostatFaultException 예외는 Cryostat 오류를 래핑합니다. 기본 Cryostat 오류는 fault 필드에 javax.xml.soap.SOAPFault 개체로 저장됩니다.

서비스 구현에서 애플리케이션에 대해 생성된 사용자 지정 예외에 맞지 않는 예외를 throw해야 하는 경우 예외 작성자를 사용하여 오류를 래핑하고 소비자로 다시 throw할 수 있습니다. 예 30.1. “ESP 프로토콜 예외 발생” 메서드가 잘못된 매개 변수를 통과한 경우 CryostatFaultException을 생성하고 throw하는 코드를 표시합니다.

예 30.1. ESP 프로토콜 예외 발생

public Quote getQuote(String ticker)
{
  ...
  if(tickers.length()<3)
  {
    SOAPFault fault = SOAPFactory.newInstance().createFault();
    fault.setFaultString("Ticker too short");
    throw new SOAPFaultException(fault);
  }
  ...
}
Copy to Clipboard Toggle word wrap

소비자가#159FaultException 예외를 catch하면 래핑된 CryostatFault 예외를 검사하여 예외의 기본 원인을 검색할 수 있습니다. 예 30.2. “Fault from a Cryostat Protocol Exception” 에 표시된 대로 CryostatFault 예외는 CryostatFaultException 예외의 getFault() 메서드를 사용하여 검색됩니다.

예 30.2. Fault from a Cryostat Protocol Exception

...
try
{
  proxy.getQuote(ticker);
}
catch (SOAPFaultException sfe)
{
  SOAPFault fault = sfe.getFault();
  ...
}
Copy to Clipboard Toggle word wrap

31장. 서비스 게시

초록

™-WS 서비스를 독립 실행형 Java 애플리케이션으로 배포하려면 서비스 공급자를 게시하는 코드를 명시적으로 구현해야 합니다.

31.1. 서비스를 게시할 때

Apache CXF는 서비스를 서비스 공급자로 게시하는 다양한 방법을 제공합니다. 서비스를 게시하는 방법은 사용 중인 배포 환경에 따라 다릅니다. Apache CXF에서 지원하는 많은 컨테이너에는 끝점 게시에 대한 쓰기 논리가 필요하지 않습니다. 두 가지 예외가 있습니다.

  • 서버를 독립 실행형 Java 애플리케이션으로 배포
  • 블루프린트 없이 OSGi 컨테이너에 서버 배포

지원되는 컨테이너에 애플리케이션을 배포하는 방법에 대한 자세한 내용은 IV 부. 웹 서비스 엔드 포인트 구성 을 참조하십시오.

31.2. 서비스 게시에 사용되는 API

31.2.1. 개요

javax.xml.ws.Enddpoint 클래스는 Cryostat-WS 서비스 공급자를 게시하는 작업을 수행합니다. 끝점을 게시하려면 다음을 수행합니다.

  1. 서비스 공급자에 대한 끝점 오브젝트를 생성합니다.
  2. 엔드포인트를 게시합니다.
  3. 애플리케이션이 종료되면 끝점을 중지합니다.

Endpoint 클래스는 서비스 공급자를 생성하고 게시하는 방법을 제공합니다. 또한 단일 메서드 호출에서 서비스 공급자를 생성하고 게시할 수 있는 메서드를 제공합니다.

31.2.2. 서비스 공급자 인스턴스화

서비스 공급자는 끝점 오브젝트를 사용하여 인스턴스화됩니다. 다음 방법 중 하나를 사용하여 서비스 공급자에 대한 끝점 오브젝트를 인스턴스화합니다.

  • static Endpoint createObjectimplementorcreate() 메서드는 지정된 서비스 구현에 대한 끝점을 반환합니다. Endpoint 오브젝트는 구현 클래스의 javax.xml.ws.BindingType 주석에서 제공하는 정보를 사용하여 생성됩니다. 주석이 없으면 끝점에서 기본 Cryo stat 1.1/HTTP 바인딩을 사용합니다.
  • staticEndpointcreateURIbindingIDObjectimplementor This create() 메서드는 지정된 바인딩을 사용하여 지정된 구현 오브젝트에 대한 Endpoint 오브젝트를 반환합니다. 이 메서드는 javax.xml.ws.BindingType 주석에서 제공하는 바인딩 정보가 있는 경우 재정의합니다. bindingID 를 확인할 수 없거나 null 인 경우 javax.xml.ws.BindingType 에 지정된 바인딩이 끝점을 생성하는 데 사용됩니다. bindingID 또는 javax.xml.ws.BindingType 을 모두 사용할 수 없는 경우 끝점은 기본 Cryostat 1.1/HTTP 바인딩을 사용하여 생성됩니다.
  • staticEndpointpublishStringaddressObjectimplementor publish() 메서드는 지정된 구현을 위해 Endpoint 개체를 생성하고 게시합니다. Endpoint 오브젝트에 사용되는 바인딩은 제공된 주소 의 URL 체계에 따라 결정됩니다. 구현에 사용할 수 있는 바인딩 목록은 URL 스키마를 지원하는 바인딩에 대해 스캔됩니다. 하나가 발견되면 Endpoint 개체가 생성되고 게시됩니다. 하나를 찾을 수 없으면 메서드가 실패합니다.

    publish() 를 사용하는 것은 create() 메서드 중 하나를 호출한 다음 ???TITLE??? 에서 사용되는 publish() 메서드를 호출하는 것과 동일합니다.

중요

Endpoint 생성 메서드에 전달된 구현 오브젝트는 javax.jws.WebService 로 주석이 달린 클래스의 인스턴스여야 하며 SEI 구현 요구사항을 충족해야 합니다. 그렇지 않으면 javax.xml.ws.WebServiceProvider 로 주석이 달린 클래스의 인스턴스이고 공급자 인터페이스를 구현해야 합니다.

31.2.3. 서비스 공급자 게시

다음 끝점 방법 중 하나를 사용하여 서비스 공급자를 게시할 수 있습니다.

  • publishStringaddresspublish() 메서드는 지정된 주소에 서비스 공급자를 게시합니다.

    중요

    주소 의 URL 스키마는 서비스 공급자의 바인딩 중 하나와 호환되어야 합니다.

  • publishObjectserverContextpublish() 메서드는 지정된 서버 컨텍스트에 제공된 정보를 기반으로 서비스 공급자를 게시합니다. 서버 컨텍스트는 끝점의 주소를 정의해야 하며 컨텍스트는 서비스 공급자의 사용 가능한 바인딩 중 하나와도 호환되어야 합니다.

31.2.4. 게시된 서비스 공급자 중지

서비스 공급자가 더 이상 필요하지 않으면 stop() 메서드를 사용하여 중지해야 합니다. 예 31.1. “게시 끝점을 중지하는 방법” 에 표시된 stop() 메서드는 끝점을 종료하고 사용 중인 모든 리소스를 정리합니다.

예 31.1. 게시 끝점을 중지하는 방법

중지

중요

끝점이 중지되면 다시 게시할 수 없습니다.

31.3. Plain Java 애플리케이션에 서비스 게시

31.3.1. 개요

애플리케이션을 일반 java 애플리케이션으로 배포하려면 애플리케이션의 main() 메서드에 끝점을 게시하기 위한 논리를 구현해야 합니다. Apache CXF는 애플리케이션의 main() 메서드를 작성하는 두 가지 옵션을 제공합니다.

  • wsdl2java 툴에서 생성된 main() 메서드 사용
  • 엔드포인트를 게시하는 사용자 정의 main() 메서드를 작성합니다.

31.3.2. 서버 메인라인 생성

코드 생성기 -server 플래그를 사용하면 도구가 간단한 서버 메인라인을 생성합니다. 예 31.2. “생성된 서버 메인라인” 에 표시된 대로 생성된 서버 메인라인은 지정된 WSDL 계약에서 각 포트 요소에 대해 하나의 서비스 공급자를 게시합니다.

자세한 내용은 44.2절. “cxf-codegen-plugin” 에서 참조하십시오.

예 31.2. “생성된 서버 메인라인” 생성된 서버 메인라인을 표시합니다.

예 31.2. 생성된 서버 메인라인

package org.apache.hello_world_soap_http;

import javax.xml.ws.Endpoint;

public class GreeterServer {

    protected GreeterServer() throws Exception {
        System.out.println("Starting Server");
        Object implementor = new GreeterImpl();
        String address = "http://localhost:9000/SoapContext/SoapPort";
        Endpoint.publish(address, implementor);
    }

    public static void main(String args[]) throws Exception {
        new GreeterServer();
        System.out.println("Server ready...");

        Thread.sleep(5 * 60 * 1000);
        System.out.println("Server exiting");
        System.exit(0);
    }
}
Copy to Clipboard Toggle word wrap

예 31.2. “생성된 서버 메인라인” 의 코드는 다음을 수행합니다.

서비스 구현 오브젝트의 사본을 인스턴스화합니다.

엔드포인트 계약에서 wsdl:port 요소의 주소 하위 항목에 따라 끝점의 주소를 생성합니다.

엔드포인트를 게시합니다.

31.3.3. 서버 메인라인 작성

Java 첫 번째 개발 모델을 사용하거나 생성된 서버 메인라인을 사용하지 않으려면 직접 작성할 수 있습니다. 서버 메인라인을 작성하려면 다음을 수행해야 합니다.

  1. “서비스 공급자 인스턴스화” 서비스 공급자의 javax.xml.ws.Endpoint 오브젝트입니다.
  2. 서비스 공급자를 게시할 때 사용할 선택적 서버 컨텍스트를 생성합니다.
  3. “서비스 공급자 게시” publish() 메서드 중 하나를 사용하는 서비스 공급자입니다.
  4. 애플리케이션을 종료할 준비가 되면 서비스 공급자를 중지합니다.

예 31.3. “사용자 지정 서버 메인라인” 서비스 공급자를 게시하는 코드를 표시합니다.

예 31.3. 사용자 지정 서버 메인라인

package org.apache.hello_world_soap_http;

import javax.xml.ws.Endpoint;

public class GreeterServer
{
  protected GreeterServer() throws Exception
  {
  }

  public static void main(String args[]) throws Exception
  {
    GreeterImpl impl = new GreeterImpl();
    Endpoint endpt.create(impl);
    endpt.publish("http://localhost:9000/SoapContext/SoapPort");

    boolean done = false;
   while(!done)
    {
      ...
    }

   endpt.stop();
    System.exit(0);
  }
}
Copy to Clipboard Toggle word wrap

예 31.3. “사용자 지정 서버 메인라인” 의 코드는 다음을 수행합니다.

서비스 구현 오브젝트의 복사본을 인스턴스화합니다.

서비스 구현을 위해 게시되지 않은 끝점을 생성합니다.

http://localhost:9000/SoapContext/SoapPort 에서 서비스 공급자를 게시합니다.

서버를 종료해야 할 때까지 루프를 수행합니다.

게시된 엔드포인트를 중지합니다.

31.4. OSGi 컨테이너에 서비스 게시

31.4.1. 개요

OSGi 컨테이너에 배포할 애플리케이션을 개발할 때 패키지된 번들의 라이프사이클을 사용하여 끝점의 게시 및 중지를 조정해야 합니다. 번들이 시작될 때 끝점이 게시되고 번들이 중지될 때 끝점이 중지되도록 합니다.

OSGi 번들 활성화기를 구현하여 엔드포인트 라이프사이클을 번들의 라이프사이클에 연결합니다. 번들 활성화기는 OSGi 컨테이너에서 시작될 때 번들에 대한 리소스를 생성하는 데 사용됩니다. 또한 컨테이너에서는 bundle activator를 사용하여 bundles 리소스를 중지할 때 정리합니다.

31.4.2. 번들 활성화기 인터페이스

org.osgi.framework.BundleActivator 인터페이스를 구현하여 애플리케이션에 대한 번들 활성화기를 생성합니다. 예 31.4. “번들 활성화기 인터페이스” 에 표시된 BundleActivator 인터페이스에는 구현해야 하는 두 가지 방법이 있습니다.

예 31.4. 번들 활성화기 인터페이스

interface BundleActivator
{
  public void start(BundleContext context)
  throws java.lang.Exception;

  public void stop(BundleContext context)
  throws java.lang.Exception;
}
Copy to Clipboard Toggle word wrap

start() 메서드는 번들을 시작할 때 컨테이너에서 호출됩니다. 여기에서 끝점을 인스턴스화하고 게시합니다.

stop() 메서드는 번들을 중지할 때 컨테이너에서 호출됩니다. 여기서 끝점을 중지합니다.

31.4.3. 시작 방법 구현

번들 활성화기 시작 방법은 엔드포인트를 게시하는 위치입니다. 끝점을 게시하려면 시작 방법은 다음을 수행해야 합니다.

  1. “서비스 공급자 인스턴스화” 서비스 공급자의 javax.xml.ws.Endpoint 오브젝트입니다.
  2. 서비스 공급자를 게시할 때 사용할 선택적 서버 컨텍스트를 생성합니다.
  3. “서비스 공급자 게시” publish() 메서드 중 하나를 사용하는 서비스 공급자입니다.

예 31.5. “bundleivator Start Method for publishing an Endpoint” 서비스 공급자를 게시하기 위한 코드를 표시합니다.

예 31.5. bundleivator Start Method for publishing an Endpoint

package com.widgetvendor.osgi;

import javax.xml.ws.Endpoint;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class widgetActivator implements BundleActivator
{
  private Endpoint endpt;
  ...

  public void start(BundleContext context)
  {
    WidgetOrderImpl impl = new WidgetOrderImpl();
    endpt = Endpoint.create(impl);
    endpt.publish("http://localhost:9000/SoapContext/SoapPort");
  }

  ...

}
Copy to Clipboard Toggle word wrap

예 31.5. “bundleivator Start Method for publishing an Endpoint” 의 코드는 다음을 수행합니다.

서비스 구현 오브젝트의 복사본을 인스턴스화합니다.

서비스 구현을 위해 게시되지 않은 끝점을 생성합니다.

http://localhost:9000/SoapContext/SoapPort 에 서비스 공급자를 게시합니다.

31.4.4. 중지 방법 구현

bundle activator의 stop 방법은 애플리케이션에서 사용하는 리소스를 정리하는 것입니다. 해당 구현에는 애플리케이션에서 게시한 모든 엔드포인트를 중지하는 논리가 포함되어야 합니다.

예 31.6. “bundleivator Stop Method for Stopping an Endpoint” 게시된 엔드포인트를 중지하는 중지 방법을 표시합니다.

예 31.6. bundleivator Stop Method for Stopping an Endpoint

package com.widgetvendor.osgi;

import javax.xml.ws.Endpoint;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class widgetActivator implements BundleActivator
{
  private Endpoint endpt;
  ...

  public void stop(BundleContext context)
  {
    endpt.stop();
  }

  ...

}
Copy to Clipboard Toggle word wrap

31.4.5. 컨테이너 정보

애플리케이션의 번들에 번들 활성화가 포함되어 있음을 컨테이너에 알려야 합니다. 번들의 매니페스트에 Bundle-Activator 속성을 추가하여 이 작업을 수행합니다. 이 속성은 번들을 활성화할 때 번들에서 사용할 클래스를 컨테이너에 알립니다. 해당 값은 번들 활성화기를 구현하는 클래스의 정규화된 이름입니다.

예 31.7. “bundleivator Manifest Entry” com.widgetvendor.osgi.widgetActivator 클래스로 구현되는 번들의 매니페스트 항목을 표시합니다.

예 31.7. bundleivator Manifest Entry

Bundle-Activator: com.widgetvendor.osgi.widgetActivator
Copy to Clipboard Toggle word wrap

32장. 기본 데이터 바인딩 개념

초록

Apache CXF가 유형 매핑을 처리하는 방법에 적용되는 몇 가지 일반 항목이 있습니다.

32.1. 스키마 정의 포함 및 가져오기

32.1.1. 개요

Apache CXF는 include 및 import 스키마 태그를 사용하여 스키마 정의의 포함 및 가져오기 를 지원합니다. 이러한 태그를 사용하면 외부 파일 또는 리소스의 정의를 스키마 요소의 범위에 삽입할 수 있습니다. 포함과 가져오기의 주요 차이점은 다음과 같습니다.

  • 포함에는 포함된 스키마 요소와 동일한 대상 네임스페이스에 속하는 정의가 포함됩니다.
  • 가져오기는 스키마 요소에서 다른 대상 네임스페이스에 속하는 정의를 가져옵니다.Importing comes in definitions that belong to a different target namespace from the enclosing schema element.

32.1.2. XSD:include 구문

include 지시문에는 다음 구문이 있습니다.

<include schemaLocation="anyURI" />
Copy to Clipboard Toggle word wrap

anyURI 에서 제공하는 참조된 스키마는 포함 스키마와 동일한 대상 네임스페이스에 속하거나 모든 대상 네임스페이스에 속하지 않아야 합니다. 참조된 스키마가 대상 네임스페이스에 속하지 않으면 포함된 스키마의 네임스페이스로 자동으로 채택됩니다.

예 32.1. “다른 스키마를 포함하는 스키마의 예” 다른 XML 스키마 문서를 포함하는 XML 스키마 문서의 예를 보여줍니다.

예 32.1. 다른 스키마를 포함하는 스키마의 예

<definitions targetNamespace="http://schemas.redhat.com/tests/schema_parser"
             xmlns:tns="http://schemas.redhat.com/tests/schema_parser"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns="http://schemas.xmlsoap.org/wsdl/">
  <types>
    <schema targetNamespace="http://schemas.redhat.com/tests/schema_parser"
            xmlns="http://www.w3.org/2001/XMLSchema">
      <include schemaLocation="included.xsd"/>
      <complexType name="IncludingSequence">
        <sequence>
          <element name="includedSeq" type="tns:IncludedSequence"/>
        </sequence>
      </complexType>
    </schema>
  </types>
  ...
</definitions>
Copy to Clipboard Toggle word wrap

예 32.2. “포함 스키마의 예” 포함된 스키마 파일의 내용을 보여줍니다.

예 32.2. 포함 스키마의 예

<schema targetNamespace="http://schemas.redhat.com/tests/schema_parser"
        xmlns="http://www.w3.org/2001/XMLSchema">
  <!-- Included type definitions -->
  <complexType name="IncludedSequence">
    <sequence>
      <element name="varInt" type="int"/>
      <element name="varString" type="string"/>
    </sequence>
  </complexType>
</schema>
Copy to Clipboard Toggle word wrap

32.1.3. XSD:import 구문

import 지시문에는 다음 구문이 있습니다.

<import namespace="namespaceAnyURI"
        schemaLocation="schemaAnyURI" />
Copy to Clipboard Toggle word wrap

가져온 정의는 namespaceAnyURI 대상 네임스페이스에 속해야 합니다. namespaceAnyURI 가 비어 있거나 지정되지 않은 상태로 남아 있는 경우 가져온 스키마 정의는 정규화되지 않습니다.

예 32.3. “다른 스키마를 가져오는 스키마의 예” 다른 XML 스키마를 가져오는 XML 스키마의 예를 보여줍니다.

예 32.3. 다른 스키마를 가져오는 스키마의 예

<definitions targetNamespace="http://schemas.redhat.com/tests/schema_parser"
             xmlns:tns="http://schemas.redhat.com/tests/schema_parser"
             xmlns:imp="http://schemas.redhat.com/tests/imported_types"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns="http://schemas.xmlsoap.org/wsdl/">
  <types>
    <schema targetNamespace="http://schemas.redhat.com/tests/schema_parser"
            xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.redhat.com/tests/imported_types"
              schemaLocation="included.xsd"/>
      <complexType name="IncludingSequence">
        <sequence>
          <element name="includedSeq" type="imp:IncludedSequence"/>
        </sequence>
      </complexType>
    </schema>
  </types>
  ...
</definitions>
Copy to Clipboard Toggle word wrap

예 32.4. “가져온 스키마의 예” 가져온 스키마 파일의 내용을 표시합니다.

예 32.4. 가져온 스키마의 예

<schema targetNamespace="http://schemas.redhat.com/tests/imported_types"
        xmlns="http://www.w3.org/2001/XMLSchema">
  <!-- Included type definitions -->
  <complexType name="IncludedSequence">
    <sequence>
      <element name="varInt" type="int"/>
      <element name="varString" type="string"/>
    </sequence>
  </complexType>
</schema>
Copy to Clipboard Toggle word wrap

32.1.4. 참조되지 않은 스키마 문서 사용

서비스의 WSDL 문서에서 참조되지 않는 스키마 문서에 정의된 유형을 사용하는 것은 3단계 프로세스입니다.

  1. xsd2wsdl 툴을 사용하여 스키마 문서를 WSDL 문서로 변환합니다.
  2. 생성된 WSDL 문서에서 wsdl2java 툴을 사용하여 유형에 대해 Java를 생성합니다.

    중요

    wsdl2java 툴에서 WSDL 문서에서 서비스를 정의하지 않는다는 경고가 표시됩니다. 이 경고를 무시할 수 있습니다.

  3. 생성된 클래스를 classpath에 추가합니다.

32.2. XML 네임스페이스 매핑

32.2.1. 개요

XML 스키마 유형, 그룹 및 요소 정의는 네임스페이스를 사용하여 범위가 지정됩니다. 네임스페이스를 사용하면 동일한 이름을 사용하는 엔터티 간에 이름이 충돌할 수 있습니다. Java 패키지는 비슷한 용도로 사용됩니다. 따라서 Apache CXF는 스키마 문서의 대상 네임스페이스를 스키마 문서에 정의된 구조를 구현하는 데 필요한 클래스가 포함된 패키지에 매핑됩니다.

32.2.2. 패키지 이름 지정

생성된 패키지의 이름은 다음 알고리즘을 사용하여 스키마의 대상 네임스페이스에서 파생됩니다.

  1. URI 스키마가 있는 경우 제거됩니다.

    참고

    Apache CXF는 http:, https:, urn: 스키마만 제거합니다.

    예를 들어 네임스페이스 http:\\www.widgetvendor.com\types\widgetTypes.xsd\\widgetvendor.com\types\widgetTypes.xsd 가 됩니다.

  2. 후행 파일 유형 식별자(있는 경우)가 제거됩니다.

    예를 들어 \\www.widgetvendor.com\types\widgetTypes.xsd\\widgetvendor.com\types\widgetTypes 가 됩니다.

  3. 결과 문자열은 /: 을 구분 기호로 사용하여 문자열 목록으로 나뉩니다.

    따라서 \\www.widgetvendor.com\types\widgetTypes{"www.widegetvendor.com", "types", "widgetTypes"} 목록이 됩니다.

  4. 목록의 첫 번째 문자열이 인터넷 도메인 이름이면 다음과 같이 컴파일됩니다.

    1. leading 192.0.2. . 이/가 제거되었습니다.
    2. 나머지 문자열은 구분 기호를 사용하여 구성 요소 부분으로 나뉩니다 .
    3. 목록의 순서가 역순으로 설정됩니다.

      따라서 {"www.widegetvendor.com", "types", "widgetTypes"}{"com", "widegetvendor", "types", "widgetTypes"}이 됩니다.

      참고

      인터넷 도메인 이름은 .com,.net,.edu,.org,.gov 또는 두 문자 국가 코드 중 하나로 끝납니다.

  5. 문자열은 모든 소문자로 변환됩니다.

    따라서 {"com", "widegetvendor", "types", "widgetTypes"}{"com", "widegetvendor", "types", "widgettypes"} 이 됩니다.

  6. 문자열은 다음과 같이 유효한 Java 패키지 이름 구성 요소로 정규화됩니다.

    1. 문자열에 특수 문자가 포함된 경우 특수 문자는 밑줄(_)으로 변환됩니다.
    2. 문자열이 Java 키워드인 경우 키워드 앞에 밑줄(_)이 추가됩니다.
    3. 문자열이 숫자로 시작하는 경우 문자열 앞에 밑줄(_)이 붙습니다.
  7. 문자열은 구분 기호를 사용하여 연결됩니다 .

    따라서 {"com", "widegetvendor", "types", "widgettypes"} 는 패키지 이름 com.widgetvendor.types.widgettypes.

네임스페이스 http:\\www.widgetvendor.com\types\widgetTypes.xsd 네임스페이스에 정의된 XML 스키마 구조는 Java 패키지 com.widgetvendor.types.widgettypes 에 매핑됩니다.

32.2.3. 패키지 콘텐츠

CryostatB 생성된 패키지에는 다음이 포함됩니다.

  • 스키마에 정의된 각 복잡한 유형을 구현하는 클래스

    복잡한 유형 매핑에 대한 자세한 내용은 35장. 복잡한 유형 사용 을 참조하십시오.

  • 열거면을 사용하여 정의된 모든 간단한 형식에 대한 열거 형식입니다.An enum type for any simple types defined using the enumeration facet

    열거를 매핑하는 방법에 대한 자세한 내용은 34.3절. “열거” 을 참조하십시오.

  • 스키마에서 개체를 인스턴스화하는 메서드를 포함하는 공용 ObjectFactory 클래스입니다.A public ObjectFactory class that contains methods for instantiating objects from the schema.

    ObjectFactory 클래스에 대한 자세한 내용은 32.3절. “오브젝트 Cryostat” 을 참조하십시오.

  • 패키지의 클래스에 대한 메타데이터를 제공하는 package-info.java 파일

32.3. 오브젝트 Cryostat

32.3.1. 개요

CryostatB는 개체 팩토리를 사용하여 개체 팩토리 인스턴스를 인스턴스화하는 메커니즘을 제공합니다. 오브젝트 팩토리에는 패키지의 범위에 정의된 모든 XML 스키마 구조를 인스턴스화하는 방법이 포함되어 있습니다. 유일한 예외는 열거가 개체 팩토리에서 생성 메서드를 가져오지 않는다는 것입니다.

32.3.2. 복잡한 유형 팩토리 방법

XML 스키마 복잡한 유형을 구현하기 위해 생성된 각 Java 클래스의 경우 오브젝트 팩토리에는 클래스 인스턴스를 생성하기 위한 메서드가 포함됩니다. 이 방법은 다음 형식을 사용합니다.

typeName createtypeName();
Copy to Clipboard Toggle word wrap

예를 들어 스키마에 widgetType 이라는 복잡한 유형이 포함된 경우 Apache CXF는 이를 구현하기 위해 Cryostat Type 이라는 클래스를 생성합니다. 예 32.5. “복잡한 유형 오브젝트의 항목” 오브젝트 팩토리에서 생성된 생성 방법을 보여줍니다.

예 32.5. 복잡한 유형 오브젝트의 항목

public class ObjectFactory
{
  ...
  WidgetType createWidgetType()
  {
    return new WidgetType();
  }
  ...
}
Copy to Clipboard Toggle word wrap

32.3.3. 요소 팩토리 방법

스키마의 전역 범위에 선언된 요소의 경우 Apache CXF는 개체 팩토리에 팩토리 메서드를 삽입합니다. 33장. XML Cryostat 사용 에서 설명한 것처럼 XML 스키마 요소는 Cryostat B Cryostat<T> 오브젝트에 매핑 됩니다. 생성 방법은 다음과 같습니다.

public JAXBElement<elementType> createelementName(elementType value);
Copy to Clipboard Toggle word wrap

예를 들어 xsd:string 유형의 주석 이라는 요소가 있는 경우 Apache CXF는 에 표시된 오브젝트 팩토리 메서드를 생성합니다. 예 32.6. “요소 Object Cryostat Entry”

예 32.6. 요소 Object Cryostat Entry

public class ObjectFactory
{
    ...
    @XmlElementDecl(namespace = "...", name = "comment")
    public JAXBElement<String> createComment(String value) {
        return new JAXBElement<String>(_Comment_QNAME, String.class, null, value);
    }
    ...
}
Copy to Clipboard Toggle word wrap

32.4. 런타임 Marshaller에 클래스 추가

32.4.1. 개요

Apache CXF 런타임에서 XML 데이터를 읽고 쓸 때 XML 스키마 유형을 대표 Java 유형과 연결하는 맵을 사용합니다. 기본적으로 맵에는 WSDL 계약 스키마 요소의 대상 네임스페이스에 정의된 모든 유형이 포함됩니다. 또한 WSDL 계약으로 가져온 모든 스키마의 네임스페이스에서 생성된 모든 유형을 포함합니다.

애플리케이션의 스키마 요소에서 사용하는 스키마 네임스페이스 이외의 네임스페이스에서 유형을 추가하는 것은 @ CryostatSee also 주석을 사용하여 수행됩니다. 애플리케이션이 애플리케이션의 WSDL 문서 범위를 벗어나 생성된 유형으로 작업해야 하는 경우 @ CryostatSee also 주석을 편집하여 CryostatB 맵에 추가할 수 있습니다.

32.4.2. @ CryostatSee also 주석 사용

@ CryostatSee also 주석은 서비스의 SEI에 추가할 수 있습니다. 여기에는 CryostatB 컨텍스트에 포함할 쉼표로 구분된 클래스 목록이 포함되어 있습니다. 예 32.7. “CryostatB 컨텍스트에 클래스 추가의 구문” @ CryostatSeeAlso 주석을 사용하는 구문이 표시됩니다.

예 32.7. CryostatB 컨텍스트에 클래스 추가의 구문

import javax.xml.bind.annotation.XmlSeeAlso;
     @WebService()
     @XmlSeeAlso({Class1.class, Class2.class, ..., ClassN.class})
     public class GeneratedSEI {
         ...
     }
Copy to Clipboard Toggle word wrap

CryostatB 생성 클래스에 액세스할 수 있는 경우 필요한 유형을 지원하기 위해 생성된 ObjectFactory 클래스를 사용하는 것이 더 효율적입니다. ObjectFactory 클래스를 포함하면 개체 팩토리에 알려진 모든 클래스가 포함됩니다.

32.4.3. 예제

예 32.8. “CryostatB 컨텍스트에 클래스 추가”@ CryostatSee 로 주석이 달린 SEI를 표시합니다.

예 32.8. CryostatB 컨텍스트에 클래스 추가

...
import javax.xml.bind.annotation.XmlSeeAlso;
...
    @WebService()
    @XmlSeeAlso({org.apache.schemas.types.test.ObjectFactory.class, org.apache.schemas.tests.group_test.ObjectFactory.class})
    public interface Foo {
        ...
    }
Copy to Clipboard Toggle word wrap

33장. XML Cryostat 사용

초록

XML 스키마 요소는 XML 문서에서 요소의 인스턴스를 정의하는 데 사용됩니다. 요소는 XML 스키마 문서의 전역 범위에서 정의되거나 복잡한 유형의 멤버로 정의됩니다. 전역 범위에 정의되면 Apache CXF는 이를 보다 쉽게 조작할 수 있도록 하는 element 클래스에 매핑됩니다.

33.1. 개요

XML 문서의 요소 인스턴스는 XML 스키마 문서의 전역 범위에 있는 XML 스키마 요소 요소에 의해 정의되므로 Java 개발자가 요소에서 더 쉽게 작업할 수 있도록 Apache CXF는 전역적으로 범위가 지정된 요소를 특수 CryostatB 요소 클래스 또는 해당 콘텐츠 유형과 일치하도록 생성된 Java 클래스에 매핑됩니다.

요소 매핑 방법은 type 속성에서 참조하는 명명된 형식을 사용하거나 요소가 인라인 형식 정의를 사용하여 정의되는지에 따라 달라집니다.How the element is mapped depends on if the element is defined using a named type referenced by the type attribute or if the element is defined using an in-line type definition. 인라인 유형 정의로 정의된 요소는 Java 클래스에 매핑됩니다.

스키마의 다른 요소에서 인라인 유형을 재사용할 수 없기 때문에 이름이 지정된 형식을 사용하여 요소를 정의하는 것이 좋습니다.

33.2. XML 스키마 매핑

XML 스키마 요소에서는 요소 요소를 사용하여 정의됩니다. 요소 요소에는 하나의 필수 특성이 있습니다. name 은 XML 문서에 표시되는 대로 요소의 이름을 지정합니다.

name 특성 요소 요소 외에도 표 33.1. “요소를 정의하는 데 사용되는 속성” 에 나열된 선택적 속성이 있습니다.

Expand
표 33.1. 요소를 정의하는 데 사용되는 속성
속성설명

type

요소의 형식을 지정합니다. 유형은 모든 XML 스키마 기본 유형 또는 계약에 정의된 이름이 지정된 복잡한 유형일 수 있습니다. 이 속성을 지정하지 않으면 인라인 유형 정의를 포함해야 합니다.

nillable

요소에서 요소를 완전히 제외할 수 있는지 여부를 지정합니다. nillabletrue 로 설정된 경우 스키마를 사용하여 생성된 모든 문서에서 요소를 생략할 수 있습니다.

abstract

인스턴스 문서에서 요소를 사용할 수 있는지 여부를 지정합니다. true 는 인스턴스 문서에 요소가 표시될 수 없음을 나타냅니다. 대신 substitutionGroup 속성에 이 요소의 QName이 포함된 다른 요소가 이 요소의 위치에 표시되어야 합니다. 이 특성을 코드 생성에 미치는 방법에 대한 자세한 내용은 “추상 요소의 Java 매핑” 을 참조하십시오.

substitutionGroup

이 요소로 대체할 수 있는 요소의 이름을 지정합니다. 유형 대체 사용에 대한 자세한 내용은 37장. 요소 하위 항목 을 참조하십시오.

default

요소의 기본값을 지정합니다. 이 특성을 코드 생성에 미치는 방법에 대한 자세한 내용은 “기본값을 사용하여 요소의 Java 매핑” 을 참조하십시오.

수정됨

요소의 고정 값을 지정합니다.

예 33.1. “간단한 XML 스키마 요소 정의” 간단한 요소 정의를 표시합니다.

예 33.1. 간단한 XML 스키마 요소 정의

<element name="joeFred" type="xsd:string" />
Copy to Clipboard Toggle word wrap

또한 요소는 인라인 유형 정의를 사용하여 자체 유형을 정의할 수도 있습니다. 인라인 유형은 complexType 요소 또는 simpleType 요소를 사용하여 지정됩니다. 데이터 유형이 복잡하거나 간단한지 여부를 지정하면 각 데이터 유형에 사용할 수 있는 도구를 사용하여 필요한 모든 유형의 데이터를 정의할 수 있습니다.

예 33.2. “인라인 유형을 사용한 XML 스키마 요소 정의” 인라인 유형 정의를 사용하여 요소 정의를 표시합니다.

예 33.2. 인라인 유형을 사용한 XML 스키마 요소 정의

<element name="skate">
  <complexType>
    <sequence>
      <element name="numWheels" type="xsd:int" />
      <element name="brand" type="xsd:string" />
    </sequence>
  </complexType>
</element>
Copy to Clipboard Toggle word wrap

33.3. 이름이 지정된 유형이 있는 요소의 Java 매핑

기본적으로 전역적으로 정의된 요소는 템플릿 클래스가 요소 요소의 type 속성 값에 따라 결정됩니다. 기본 유형의 경우 템플릿 클래스는 “래퍼 클래스” 에 설명된 래퍼 클래스 매핑을 사용하여 파생됩니다. 복잡한 유형의 경우 복잡한 유형을 지원하기 위해 생성된 Java 클래스는 템플릿 클래스로 사용됩니다.

매핑을 지원하고 요소의 QName에 대한 불필요한 걱정을 완화하기 위해 예 33.3. “글로벌 범위 요소를 위한 Object Cryostat 방법” 와 같이 전역적으로 정의된 각 요소에 대해 오브젝트 팩토리 방법이 생성됩니다.

예 33.3. 글로벌 범위 요소를 위한 Object Cryostat 방법

public class ObjectFactory {

    private final static QName _name_QNAME = new QName("targetNamespace", "localName");

    ...

    @XmlElementDecl(namespace = "targetNamespace", name = "localName")
    public JAXBElement<type> createname(type value);

}
Copy to Clipboard Toggle word wrap

예를 들어 예 33.1. “간단한 XML 스키마 요소 정의” 에 정의된 요소는 예 33.4. “간단한 요소를 위한 Object Cryostat” 에 표시된 오브젝트 팩토리 메서드를 생성합니다.

예 33.4. 간단한 요소를 위한 Object Cryostat

public class ObjectFactory {

    private final static QName _JoeFred_QNAME = new QName("...", "joeFred");

    ...

    @XmlElementDecl(namespace = "...", name = "joeFred")
    public JAXBElement<String> createJoeFred(String value);

}
Copy to Clipboard Toggle word wrap

예 33.5. “글로벌 범위 요소 사용” Java에서 전역 범위 요소를 사용하는 예를 보여줍니다.

예 33.5. 글로벌 범위 요소 사용

JAXBElement<String> element = createJoeFred("Green");
String color = element.getValue();
Copy to Clipboard Toggle word wrap

33.4. WSDL에서 이름이 지정된 형식으로 요소 사용

전역 범위 요소가 메시지 부분을 정의하는 데 사용되는 경우 생성된 Java 매개변수는 Cryostat B Cryostat<T>의 인스턴스가 아닙니다. 대신 일반 Java 유형 또는 클래스에 매핑됩니다.

예 33.6. “Element를 메시지 부분으로 사용” 에 표시된 WSDL 조각에 따라 결과 메서드에는 문자열 유형의 매개변수가 있습니다.

예 33.6. Element를 메시지 부분으로 사용

<?xml version="1.0" encoding=";UTF-8"?>
<wsdl:definitions name="HelloWorld"
                  targetNamespace="http://apache.org/hello_world_soap_http"
                  xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:tns="http://apache.org/hello_world_soap_http"
                  xmlns:x1="http://apache.org/hello_world_soap_http/types"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <schema targetNamespace="http://apache.org/hello_world_soap_http/types"
            xmlns="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"><element name="sayHi">
      <element name="sayHi" type="string"/>
      <element name="sayHiResponse" type="string"/>
    </schema>
  </wsdl:types>

  <wsdl:message name="sayHiRequest">
    <wsdl:part element="x1:sayHi" name="in"/>
  </wsdl:message>
  <wsdl:message name="sayHiResponse">
    <wsdl:part element="x1:sayHiResponse" name="out"/>
  </wsdl:message>

  <wsdl:portType name="Greeter">
    <wsdl:operation name="sayHi">
      <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
      <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>
Copy to Clipboard Toggle word wrap

예 33.7. “글로벌 요소를 일부로 사용하는 Java 방법” sayHi 작업에 대해 생성된 메서드 서명을 표시합니다.

예 33.7. 글로벌 요소를 일부로 사용하는 Java 방법

문자열sayHi문자열

33.5. 인라인 유형으로 요소의 Java 매핑

인라인 유형을 사용하여 요소를 정의하면 다른 유형을 Java에 매핑하는 데 사용되는 것과 동일한 규칙에 따라 Java에 매핑됩니다. 간단한 유형의 규칙은 34장. 간단한 유형 사용 에 설명되어 있습니다. 복잡한 유형의 규칙은 35장. 복잡한 유형 사용 에 설명되어 있습니다.

인라인 유형 정의가 있는 요소에 대해 Java 클래스가 생성되면 생성된 클래스는 @ CryostatRoot Cryostat 주석으로 장식됩니다. @ CryostatRoot Cryostat 주석에는 namenamespace 라는 두 가지 유용한 속성이 있습니다. 이러한 속성은 표 33.2. “@ CryostatRoot Cryostat 주석에 대한 속성” 에 설명되어 있습니다.

Expand
표 33.2. @ CryostatRoot Cryostat 주석에 대한 속성
속성설명

name

XML Schema 요소의 name 특성 값을 지정합니다.

namespace

요소가 정의된 네임스페이스를 지정합니다. 이 요소가 대상 네임스페이스에 정의되어 있으면 속성이 지정되지 않습니다.

요소가 다음 조건 중 하나 이상을 충족하는 경우 @ CryostatRoot Cryostat 주석은 사용되지 않습니다.

  • 요소의 nillable 속성이 true로 설정됩니다.
  • 요소는 대체 그룹의 헤드 요소입니다.

    대체 그룹에 대한 자세한 내용은 37장. 요소 하위 항목 을 참조하십시오.

33.6. 추상 요소의 Java 매핑

요소의 abstract 속성이 true 로 설정되면 형식의 인스턴스를 인스턴스화하는 개체 팩토리 메서드가 생성되지 않습니다. 인라인 유형을 사용하여 요소를 정의하면 인라인 유형을 지원하는 Java 클래스가 생성됩니다.

33.7. 기본값을 사용하여 요소의 Java 매핑

요소의 기본 특성이 사용되는 경우 defaultValue 속성은 생성된 @ CryostatDecl 주석에 추가됩니다. 예를 들어 예 33.8. “기본 값이 있는 XML 스키마 요소” 에 정의된 요소는 예 33.9. “Object Cryostat Method for an Element with a Default Value” 에 표시된 오브젝트 팩토리 메서드를 생성합니다.

예 33.8. 기본 값이 있는 XML 스키마 요소

<element name="size" type="xsd:int" default="7"/>
Copy to Clipboard Toggle word wrap

예 33.9. Object Cryostat Method for an Element with a Default Value

   @XmlElementDecl(namespace = "...", name = "size", defaultValue = "7")
   public JAXBElement<Integer> createUnionJoe(Integer value) {
       return new JAXBElement<Integer>(_Size_QNAME, Integer.class, null, value);
   }
Copy to Clipboard Toggle word wrap

34장. 간단한 유형 사용

초록

XML 스키마 간단한 유형은 xsd:int 와 같은 XML 스키마 기본 유형이거나 simpleType 요소를 사용하여 정의됩니다. 하위 또는 속성을 포함하지 않는 요소를 지정하는 데 사용됩니다. 일반적으로 네이티브 Java 구문에 매핑되며 이를 구현하기 위해 특수 클래스 생성이 필요하지 않습니다. 열거된 단순 형식은 Java enum 형식에 매핑되므로 생성된 코드를 생성하지 않습니다.

34.1. 기본 유형

34.1.1. 개요

XML 스키마 기본 유형 중 하나를 사용하여 메시지 부분을 정의하면 생성된 매개 변수의 유형이 해당 Java 네이티브 유형에 매핑됩니다. 복잡한 유형의 범위 내에서 정의된 매핑 요소가 매핑할 때 동일한 패턴이 사용됩니다. 결과 필드는 해당 Java 네이티브 유형입니다.

34.1.2. 매핑

표 34.1. “XML Schema Primitive Type to Java Native Type Mapping” XML Schema 기본 유형과 Java 네이티브 유형 간의 매핑을 나열합니다.

Expand
표 34.1. XML Schema Primitive Type to Java Native Type Mapping
XML 스키마 유형Java 유형

xsd:string

문자열

xsd:integer

BigInteger

xsd:int

int

xsd:long

long

xsd:short

short

xsd:decimal

BigDecimal

xsd:float

float

xsd:double

double

xsd:boolean

boolean

xsd:byte

byte

xsd:QName

QName

xsd:dateTime

XMLGregorianCalendar

xsd:base64Binary

byte[]

xsd:hexBinary

byte[]

xsd:unsignedInt

long

xsd:unsignedShort

int

xsd:unsignedByte

short

xsd:time

XMLGregorianCalendar

xsd:date

XMLGregorianCalendar

xsd:g

XMLGregorianCalendar

xsd:anySimpleType [a]

개체

xsd:anySimpleType [b]

문자열

xsd:duration

duration

xsd:NOTATION

QName

[a] 이 유형의 요소입니다.
[b] 이 유형의 속성입니다.

34.1.3. 래퍼 클래스

XML 스키마 기본 유형을 Java 기본 유형에 매핑하면 가능한 모든 XML 스키마 구성에 대해 작동하지 않습니다. XML 스키마 기본 유형을 Java 기본 유형의 해당 래퍼 유형에 매핑해야 하는 경우가 많습니다. 이러한 경우는 다음과 같습니다.

  • 다음과 같이 nillable 속성이 true 로 설정된 요소:

    <element name="finned" type="xsd:boolean"
             nillable="true" />
    Copy to Clipboard Toggle word wrap
  • min Cryostat 특성이 0 으로 설정된 요소 요소 및 max Cryostat 특성이 1 로 설정된 요소 요소 또는 표시된 대로 max Cryostat 속성이 지정되지 않았습니다.

    <element name="plane" type="xsd:string" minOccurs="0" />
    Copy to Clipboard Toggle word wrap
  • 다음과 같이 use 속성이 선택적 또는 지정하지 않고 기본 특성이나 고정 특성이 지정되지 않은 속성 요소입니다.

    <element name="date">
      <complexType>
        <sequence/>
        <attribute name="calType" type="xsd:string"
                   use="optional" />
      </complexType>
    </element>
    Copy to Clipboard Toggle word wrap

표 34.2. “Java 래퍼 클래스 매핑에 기본 스키마 유형” 이 경우 XML Schema 기본 유형이 Java 래퍼 클래스에 매핑되는 방법을 보여줍니다.

Expand
표 34.2. Java 래퍼 클래스 매핑에 기본 스키마 유형
스키마 유형Java 유형

xsd:int

java.lang.Integer

xsd:long

java.lang.Long

xsd:short

java.lang.Short

xsd:float

java.lang.Float

xsd:double

java.lang.Double

xsd:boolean

java.lang.Boolean

xsd:byte

java.lang.Byte

xsd:unsignedByte

java.lang.Short

xsd:unsignedShort

java.lang.Integer

xsd:unsignedInt

java.lang.Long

xsd:unsignedLong

java.math.BigInteger

xsd:duration

java.lang.String

34.2. 제한 사항에 따라 정의된 간단한 유형

34.2.1. 개요

XML 스키마를 사용하면 다른 기본 유형 또는 간단한 유형에서 새 유형을 파생하여 간단한 유형을 만들 수 있습니다. 간단한 유형은 simpleType 요소를 사용하여 설명합니다.

새 유형은 하나 이상의 facet로 기본 유형을 제한하여 설명합니다. 이러한 facet는 새 유형에 저장할 수 있는 유효한 값을 제한합니다. 예를 들어 간단한 유형인 SSN 을 정의할 수 있습니다. 정확히 9자 문자열입니다.

각 기본 XML 스키마 유형에는 선택적 facet 세트가 있습니다.

34.2.2. 절차

자체 간단한 유형을 정의하려면 다음을 수행합니다.

  1. 새 간단한 유형의 기본 유형을 확인합니다.
  2. 선택한 기본 유형에 대해 사용 가능한 측면을 기반으로 새 유형을 정의하는 제한 사항을 결정합니다.
  3. 이 섹션에 표시된 구문을 사용하여 계약의 유형 섹션에 적절한 simpleType 요소를 입력합니다.

34.2.3. XML 스키마에서 간단한 유형 정의

예 34.1. “간단한 유형 구문” 간단한 유형을 설명하는 구문을 보여줍니다.

예 34.1. 간단한 유형 구문

<simpleType name="typeName">
  <restriction base="baseType">
    <facet value="value" />
    <facet value="value" />
    ...
  </restriction>
</simpleType>
Copy to Clipboard Toggle word wrap

type 설명은 simpleType 요소로 묶여 있으며 name 속성 값으로 식별됩니다. 새로운 단순 유형이 정의되는 기본 유형은 xsd:restriction 요소의 기본 특성에 따라 지정됩니다. 각 facet 요소는 restriction 요소 내에서 지정됩니다. 사용 가능한 facet 및 유효한 설정은 기본 유형에 따라 다릅니다. 예를 들어 xsd:string 은 다음을 포함한 여러 측면이 있습니다.

  • length
  • minLength
  • maxLength
  • 패턴
  • whitespace

예 34.2. “우편 번호 간단한 유형” 미국 상태에 사용되는 두 문자 우편 코드를 나타내는 간단한 유형에 대한 정의를 표시합니다. 두 개의 대문자만 포함할 수 있습니다. TX 는 유효한 값이지만 tx 또는 tX 는 유효하지 않습니다.

예 34.2. 우편 번호 간단한 유형

<xsd:simpleType name="postalCode">
  <xsd:restriction base="xsd:string">
    <xsd:pattern value="[A-Z]{2}" />
  </xsd:restriction>
</xsd:simpleType>
Copy to Clipboard Toggle word wrap

34.2.4. Java에 매핑

Apache CXF는 사용자 정의 간단한 유형을 간단한 유형의 기본 유형의 Java 유형에 매핑합니다. 따라서 예 34.2. “우편 번호 간단한 유형” 에 표시된 간단한 유형 mailCode를 사용하는 모든 메시지는 postal Code 의 기본 유형이 xsd:string 이므로 문자열에 매핑됩니다. 예를 들어 예 34.3. “간단한 유형의 신용 요청” 에 표시된 WSDL 조각은 문자열 의 매개변수 postalCode 를 사용하는 Java 메서드 state() 를 생성합니다.

예 34.3. 간단한 유형의 신용 요청

<message name="stateRequest">
  <part name="postalCode" type="postalCode" />
</message>
...
<portType name="postalSupport">
  <operation name="state">
    <input message="tns:stateRequest" name="stateRec" />
    <output message="tns:stateResponse" name="credResp" />
  </operation>
</portType>
Copy to Clipboard Toggle word wrap

34.2.5. facet 강제

기본적으로 Apache CXF는 간단한 유형을 제한하는 데 사용되는 facet를 적용하지 않습니다. 그러나 스키마 검증을 활성화하여 facet를 적용하도록 Apache CXF 엔드포인트를 구성할 수 있습니다.

스키마 유효성 검사를 사용하도록 Apache CXF 끝점을 구성하려면 schema-validation-enabled 속성을 true 로 설정합니다. 예 34.4. “스키마 유효성 검사를 사용하도록 서비스 공급자 구성” 스키마 검증을 사용하는 서비스 공급자에 대한 구성 표시

예 34.4. 스키마 유효성 검사를 사용하도록 서비스 공급자 구성

<jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
                wsdlLocation="wsdl/hello_world.wsdl"
                createdFromAPI="true">
  <jaxws:properties>
    <entry key="schema-validation-enabled" value="BOTH" />
  </jaxws:properties>
</jaxws:endpoint>
Copy to Clipboard Toggle word wrap

스키마 검증 구성에 대한 자세한 내용은 24.3.4.7절. “스키마 유효성 검사 유형 값” 을 참조하십시오.

34.3. 열거

34.3.1. 개요

XML 스키마에서 열거된 형식은 xsd:enumeration facet를 사용하여 정의된 간단한 유형입니다. atomic 간단한 유형과 달리 Java enums에 매핑됩니다.

34.3.2. XML 스키마에 열거된 유형 정의

열거는 xsd:enumeration facet를 사용하는 간단한 유형입니다. 각 xsd:enumeration facet는 열거된 유형에 대해 하나의 가능한 값을 정의합니다.

예 34.5. “XML Schema Defined Enumeration” 열거된 유형의 정의를 표시합니다. 다음과 같은 가능한 값이 있습니다.

  • big
  • 대규모
  • Mungo
  • gargantuan

예 34.5. XML Schema Defined Enumeration

<simpleType name="widgetSize">
  <restriction base="xsd:string">
    <enumeration value="big"/>
    <enumeration value="large"/>
    <enumeration value="mungo"/>
    <enumeration value="gargantuan"/>
  </restriction>
Copy to Clipboard Toggle word wrap

34.3.3. Java에 매핑

기본 유형이 xsd:string 인 XML 스키마 열거는 Java enum 유형에 자동으로 매핑됩니다. 38.4절. “열거 매핑 사용자 정의” 에 설명된 사용자 지정을 사용하여 다른 기본 유형의 열거를 Java enum 유형에 매핑하도록 코드 생성기에 지시할 수 있습니다.

enum 유형은 다음과 같이 생성됩니다.

  1. 유형 이름은 간단한 유형 정의의 name 속성에서 가져오고 Java 식별자로 변환됩니다.

    일반적으로 이는 XML 스키마 이름의 첫 번째 문자를 대문자로 변환하는 것을 의미합니다. XML 스키마 이름의 첫 문자가 유효하지 않은 문자이면 아래에 있는_)가 이름에 추가됩니다.

  2. 각 열거 facet의 경우 열거 상수는 value 특성의 값을 기반으로 생성됩니다.For each enumeration facet, an enum constant is generated based on the value of the value attribute.

    상수의 이름은 값의 소문자를 모두 대문자로 변환하여 파생됩니다.

  3. 열거의 기본 유형에서 매핑된 Java 유형을 가져오는 생성자가 생성됩니다.A constructor is generated that takes the Java type mapped from the enumeration's base type.
  4. value() 라는 공용 메서드는 형식의 인스턴스로 표시되는 facet 값에 액세스하기 위해 생성됩니다.

    value() 메서드의 반환 유형은 XML 스키마 유형의 기본 유형입니다.

  5. facet 값을 기반으로 enum 형식의 인스턴스를 만드는 데 fromValue() 라는 공용 메서드가 생성됩니다.A public method called fromValue() is generated to create an instance of the enum type based on a facet value.

    value() 메서드의 매개 변수 유형은 XML 스키마 유형의 기본 유형입니다.

  6. 클래스는 @ CryostatEnum 주석으로 데코레이팅됩니다.

예 34.5. “XML Schema Defined Enumeration” 에 정의된 열거 유형은 예 34.6. “문자열 기반 XML 스키마 열거에 대해 생성된 Enumerated 유형” 에 표시된 enum 유형에 매핑됩니다.

예 34.6. 문자열 기반 XML 스키마 열거에 대해 생성된 Enumerated 유형

@XmlType(name = "widgetSize")
@XmlEnum
public enum WidgetSize {

    @XmlEnumValue("big")
    BIG("big"),
    @XmlEnumValue("large")
    LARGE("large"),
    @XmlEnumValue("mungo")
    MUNGO("mungo"),
    @XmlEnumValue("gargantuan")
    GARGANTUAN("gargantuan");
    private final String value;

    WidgetSize(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static WidgetSize fromValue(String v) {
        for (WidgetSize c: WidgetSize.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}
Copy to Clipboard Toggle word wrap

34.4. 목록

34.4.1. 개요

XML 스키마는 공백으로 구분된 간단한 형식 목록인 데이터 유형을 정의하는 메커니즘을 지원합니다. 목록 유형을 사용하는 요소 primeList 의 예는 예 34.7. “목록 유형 예” 에 표시됩니다.

예 34.7. 목록 유형 예

<primeList>1 3 5 7 9 11 13<\primeList>
Copy to Clipboard Toggle word wrap

XML 스키마 목록 유형은 일반적으로 Java List<T> 개체에 매핑 됩니다. 이 패턴에 대한 유일한 변형은 메시지 부분이 XML 스키마 목록 유형의 인스턴스에 직접 매핑되는 경우입니다.

34.4.2. XML 스키마에서 목록 유형 정의

XML 스키마 목록 유형은 간단한 유형이므로 simpleType 요소를 사용하여 정의됩니다. 목록 유형을 정의하는 데 사용되는 가장 일반적인 구문은 예 34.8. “XML 스키마 목록 유형의 구문” 에 표시됩니다.

예 34.8. XML 스키마 목록 유형의 구문

<simpleType name="listType">
  <list itemType="atomicType">
    <facet value="value" />
    <facet value="value" />
    ...
  </list>
</simpleType>
Copy to Clipboard Toggle word wrap

atomicType 에 지정된 값은 목록에 있는 요소의 유형을 정의합니다. xsd:int 또는 xsd:string 과 같은 기본 XML 스키마 원자 유형 중 하나이거나 목록이 아닌 사용자 정의 간단한 유형 중 하나일 수 있습니다.

목록 형식에 나열된 요소 유형을 정의하는 것 외에도 facet를 사용하여 목록 유형의 속성을 추가로 제한할 수도 있습니다. 표 34.3. “자주 묻는 질문 (FAQ)” 목록 유형에서 사용하는 facet를 표시합니다.

Expand
표 34.3. 자주 묻는 질문 (FAQ)
facet효과

length

목록 유형 인스턴스의 요소 수를 정의합니다.

minLength

목록 유형의 인스턴스에 허용되는 최소 요소 수를 정의합니다.

maxLength

목록 유형의 인스턴스에 허용되는 최대 요소 수를 정의합니다.

열거

목록 유형의 인스턴스에서 요소에 허용되는 값을 정의합니다.

패턴

목록 유형의 인스턴스에 있는 요소의 사전 형식을 정의합니다. 패턴은 정규식을 사용하여 정의됩니다.

예를 들어 예 34.7. “목록 유형 예” 에 표시된 simpleList 요소에 대한 정의는 예 34.9. “목록 유형 정의” 에 표시됩니다.

예 34.9. 목록 유형 정의

<simpleType name="primeListType">
  <list itemType="int"/>
</simpleType>
<element name="primeList" type="primeListType"/>
Copy to Clipboard Toggle word wrap

예 34.8. “XML 스키마 목록 유형의 구문” 에 표시된 구문 외에도 예 34.10. “목록 유형에 대한 대체 구문” 에 표시된 덜 일반적인 구문을 사용하여 목록 유형을 정의할 수도 있습니다.

예 34.10. 목록 유형에 대한 대체 구문

<simpleType name="listType">
  <list>
    <simpleType>
      <restriction base="atomicType">
        <facet value="value"/>
        <facet value="value"/>
        ...
      </restriction>
    </simpleType>
  </list>
  </simpleType>
Copy to Clipboard Toggle word wrap

34.4.3. 목록 유형 요소를 Java에 매핑

요소가 목록 유형을 정의하면 목록 유형이 컬렉션 속성에 매핑됩니다. 컬렉션 속성은 Java List<T> 개체 입니다. List<T>에서 사용하는 템플릿 클래스는 목록의 기본 유형에서 매핑된 래퍼 클래스입니다. 예를 들어 예 34.9. “목록 유형 정의” 에 정의된 목록 유형은 List<Integer>에 매핑됩니다.

래퍼 유형 매핑에 대한 자세한 내용은 “래퍼 클래스” 을 참조하십시오.

34.4.4. 목록 유형 매개변수를 Java에 매핑

메시지 부분이 목록 유형으로 정의되거나 목록 유형의 요소에 매핑되면 결과 메서드 매개변수가 List<T > 오브젝트 대신 배열에 매핑됩니다. 배열의 기본 유형은 목록 유형의 기본 클래스의 래퍼 클래스입니다.

예를 들어 예 34.11. “목록 유형 메시지 파트가 있는 WSDL” 의 WSDL 조각은 예 34.12. “목록 유형 매개 변수가 있는 Java 메서드” 에 표시된 메서드 서명을 생성합니다.

예 34.11. 목록 유형 메시지 파트가 있는 WSDL

<definitions ...>
  ...
  <types ...>
    <schema ... >
      <simpleType name="primeListType">
        <list itemType="int"/>
      </simpleType>
      <element name="primeList" type="primeListType"/>
    </schemas>
  </types>
  <message name="numRequest"> <part name="inputData" element="xsd1:primeList" /> </message>
  <message name="numResponse">;
    <part name="outputData" type="xsd:int">
  ...
  <portType name="numberService">
    <operation name="primeProcessor">
      <input name="numRequest" message="tns:numRequest" />
      <output name="numResponse" message="tns:numResponse" />
    </operation>
    ...
  </portType>
  ...
</definitions>
Copy to Clipboard Toggle word wrap

예 34.12. 목록 유형 매개 변수가 있는 Java 메서드

public interface NumberService {

    @XmlList
    @WebResult(name = "outputData", targetNamespace = "", partName = "outputData")
    @WebMethod
    public int primeProcessor(
        @WebParam(partName = "inputData", name = "primeList", targetNamespace = "...") java.lang.Integer[] inputData
    );
}
Copy to Clipboard Toggle word wrap

34.5. unions

34.5.1. 개요

XML 스키마에서 공용체는 여러 가지 간단한 유형 중 하나일 수 있는 데이터 형식을 설명할 수 있는 구문입니다. 예를 들어 값이 정수 1 또는 문자열 first 인 형식을 정의할 수 있습니다. 공용 연결은 Java 문자열s에 매핑됩니다.

34.5.2. XML 스키마로 정의

XML 스키마 결합은 simpleType 요소를 사용하여 정의됩니다. 공용 공용체의 멤버 유형을 정의하는 하나 이상의 union 요소를 포함합니다.Contains at least one union element that defines the member types of the union. 공용체의 멤버 유형은 공용체의 인스턴스에 저장될 수 있는 유효한 데이터 유형입니다. union 요소의 memberTypes 특성을 사용하여 정의됩니다. memberTypes 속성 값에는 정의된 하나 이상의 간단한 형식 이름 목록이 포함되어 있습니다. 예 34.13. “간단한 연합 유형” 정수 또는 문자열을 저장할 수 있는 공용체의 정의를 표시합니다.Shows the definition of a union that can store either an integer or a string.

예 34.13. 간단한 연합 유형

<simpleType name="orderNumUnion">
  <union memberTypes="xsd:string xsd:int" />
</simpleType>
Copy to Clipboard Toggle word wrap

명명된 형식을 멤버 유형으로 지정하는 것 외에도 anonymous simple type을 union의 멤버 유형으로 정의할 수도 있습니다.In addition to specifying named types as a member type of a union, you can also define an anonymous simple type as a member type of a union. 이 작업은 union 요소 내에 anonymous type 정의를 추가하여 수행됩니다. 예 34.14. “익명의 멤버 유형과의 연결” 유효한 정수의 가능한 값을 1에서 10까지 제한하는 익명 멤버 유형이 포함된 union의 예를 보여줍니다.

예 34.14. 익명의 멤버 유형과의 연결

<simpleType name="restrictedOrderNumUnion">
  <union memberTypes="xsd:string">
    <simpleType>
      <restriction base="xsd:int">
        <minInclusive value="1" />
        <maxInclusive value="10" />
      </restriction>
    </simpleType>
  </union>
</simpleType>
Copy to Clipboard Toggle word wrap

34.5.3. Java에 매핑

XML 스키마 결합 유형은 Java String 개체에 매핑됩니다. 기본적으로 Apache CXF는 생성된 오브젝트의 콘텐츠를 검증하지 않습니다. Apache CXF가 콘텐츠의 유효성을 검사하려면 “facet 강제” 에 설명된 대로 스키마 검증을 사용하도록 런타임을 구성해야 합니다.

34.6. 간단한 유형 하위 항목

34.6.1. 개요

XML은 xsi:type 특성을 사용하여 호환되는 유형 간에 간단한 유형 대체를 허용합니다. 그러나 간단한 유형의 기본 매핑은 Java 기본 유형에 대한 기본 매핑은 간단한 유형 대체를 완전히 지원하지 않습니다. 런타임은 기본 단순 유형 대체를 처리할 수 있지만 정보가 손실됩니다. 코드 생성기는 무해한 단순 유형 대체를 용이하게 하는 Java 클래스를 생성하도록 사용자 지정할 수 있습니다.

34.6.2. 기본 매핑 및 마샬링

Java 기본 유형은 유형 대체를 지원하지 않으므로 간단한 유형 대체에 대한 간단한 유형 대체를 지원하기 위한 간단한 유형의 기본 매핑에 문제가 있습니다. Java 가상 머신은 유형을 정의하는 스키마에서 허용하더라도 int 를 예상하는 변수에 잠시 전달하려는 경우 이를 수행합니다.

Java 유형 시스템에서 부과한 제한 사항을 해결하기 위해 요소의 xsi:type 속성 값이 다음 조건 중 하나를 충족할 때 Apache CXF를 사용하면 간단한 유형 대체를 허용합니다.

  • 요소의 스키마 유형과 호환되는 기본 형식을 지정합니다.
  • 요소의 스키마 유형에서 제한에 따라 파생되는 형식을 지정합니다.
  • 요소의 스키마 유형에서 확장으로 파생되는 복잡한 형식을 지정합니다.

런타임에서 형식 대체를 수행할 때 요소의 xsi:type 속성에 지정된 형식에 대한 지식이 유지되지 않습니다. 형식 대체가 복잡한 형식에서 단순 형식에 해당하는 경우 단순 형식과 직접 관련된 값만 유지됩니다.If the type substitution is from a complex type to a simple type, only the value directly related to the simple type is preserved. 확장에 의해 추가된 다른 모든 요소 및 특성은 손실됩니다.

34.6.3. 무해한 유형 대체 지원

다음과 같은 방법으로 간단한 유형 생성을 사용자 정의하여 간단한 유형 대체의 무해한 지원을 용이하게 할 수 있습니다.

  • globalBindings 사용자 지정 요소의 mapSimpleTypeDeftrue 로 설정합니다.

    이는 코드 생성기가 전역 범위에 정의된 모든 이름의 단순 형식에 대해 Java 값 클래스를 생성하도록 지시합니다.

    자세한 내용은 38.3절. “간단한 유형에 대한 Java 클래스 생성” 에서 참조하십시오.

  • javaType 요소를 globalBindings 사용자 지정 요소에 추가합니다.

    이렇게 하면 코드 생성기가 XML 스키마 기본 유형의 모든 인스턴스를 개체의 특정 클래스에 매핑하도록 지시합니다.

    자세한 내용은 38.2절. “XML 스키마의 Java 클래스 지정” 에서 참조하십시오.

  • 사용자 지정할 특정 요소에 baseType 사용자 지정 요소를 추가합니다.

    baseType 사용자 지정 요소를 사용하면 속성을 나타내기 위해 생성된 Java 유형을 지정할 수 있습니다. 간단한 유형 대체에 대한 최상의 호환성을 위해 java.lang.Object 를 기본 유형으로 사용합니다.

    자세한 내용은 38.6절. “요소 또는 속성의 기본 유형 지정” 에서 참조하십시오.

35장. 복잡한 유형 사용

초록

복잡한 형식은 여러 요소를 포함할 수 있으며 특성을 가질 수 있습니다.Complex types can contain multiple elements and they can have attributes. 이는 유형 정의로 표시되는 데이터를 저장할 수 있는 Java 클래스에 매핑됩니다. 일반적으로 매핑은 콘텐츠 모델의 요소 및 특성을 나타내는 속성 집합을 사용하여 8080에 연결됩니다.

35.1. 기본 복잡한 유형 매핑

35.1.1. 개요

XML 스키마 복잡한 유형은 간단한 유형보다 더 복잡한 정보를 포함하는 구성을 정의합니다. 가장 간단한 복잡한 유형은 속성이 있는 빈 요소를 정의합니다. 보다 복잡한 유형은 요소의 컬렉션으로 구성됩니다.

기본적으로 XML 스키마 복잡한 유형은 Java 클래스에 매핑되며, 멤버 변수는 XML 스키마 정의에 나열된 각 요소 및 속성을 나타냅니다. 클래스에는 각 멤버 변수에 대한 setter 및 get zone이 있습니다.

35.1.2. XML 스키마로 정의

XML 스키마 복잡한 유형은 complexType 요소를 사용하여 정의됩니다. complexType 요소는 데이터의 구조를 정의하는 데 사용되는 나머지 요소를 래핑합니다. 이름이 지정된 형식 정의의 부모 요소 또는 요소에 저장된 정보의 구조를 정의하는 요소 요소의 자식으로 나타날 수 있습니다. complexType 요소가 명명된 유형을 정의하는 데 사용되는 경우 name 특성을 사용해야 합니다. name 속성은 유형을 참조하는 데 필요한 고유 식별자를 지정합니다.

하나 이상의 요소를 포함하는 복잡한 유형 정의에는 표 35.1. “복잡한 유형에서 발생하는 방법 정의의 요소” 에 설명된 하위 요소 중 하나가 있습니다. 이러한 요소는 지정된 요소가 유형의 인스턴스에 표시되는 방식을 결정합니다.

Expand
표 35.1. 복잡한 유형에서 발생하는 방법 정의의 요소
element설명

all

복잡한 형식의 일부로 정의된 모든 요소가 형식의 인스턴스에 표시되어야 합니다. 그러나 어떤 순서로든 나타날 수 있습니다.

선택

복잡한 형식의 일부로 정의된 요소 중 하나만 형식 인스턴스에 표시될 수 있습니다.

순서

복잡한 형식의 일부로 정의된 모든 요소는 형식의 인스턴스에 표시되어야 하며 형식 정의에 지정된 순서로도 표시되어야 합니다.

참고

복잡한 유형 정의에서 특성만 사용하는 경우 표 35.1. “복잡한 유형에서 발생하는 방법 정의의 요소” 에 설명된 요소 중 하나가 필요하지 않습니다.

요소가 표시되는 방식을 결정한 후 하나 이상의 요소 요소 하위 요소를 정의에 추가하여 요소를 정의합니다.

예 35.1. “XML 스키마 복잡성 유형” XML 스키마로 복잡한 유형 정의를 보여줍니다.

예 35.1. XML 스키마 복잡성 유형

<complexType name="sequence">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="street" type="xsd:short" />
    <element name="city" type="xsd:string" />
    <element name="state" type="xsd:string" />
    <element name="zipCode" type="xsd:string" />
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap

35.1.3. Java에 매핑

XML 스키마 복잡한 유형은 Java 클래스에 매핑됩니다. 복잡한 유형 정의의 각 요소는 Java 클래스의 멤버 변수에 매핑됩니다. 복잡한 유형의 각 요소에 대해 getter 및 setter 메서드도 생성됩니다.

생성된 모든 Java 클래스는 @ CryostatType 주석으로 데코레이팅됩니다. 이름이 지정된 복합 유형에 대한 매핑인 경우 주석 이름은 complexType 요소의 name 속성 값으로 설정됩니다. 복잡한 유형이 요소 정의의 일부로 정의된 경우 @ CryostatType 주석의 name 속성 값은 요소 요소의 name 속성 값입니다.

참고

“인라인 유형으로 요소의 Java 매핑” 에 설명된 대로, 요소 정의의 일부로 정의된 복잡한 유형에 대해 생성되는 경우 생성된 클래스는 @ CryostatRoot >-< 주석으로 분류됩니다.

런타임에 XML 스키마 복잡한 유형의 요소를 처리하는 방법을 나타내는 지침을 제공하기 위해 코드 생성기는 클래스와 해당 멤버 변수를 해독하는 데 사용되는 주석을 변경합니다.

모든 복잡한 유형

모든 복잡한 유형은 all 요소를 사용하여 정의됩니다. 여기에는 다음과 같이 주석이 있습니다.

  • @ CryostatType 주석의 propOrder 속성이 비어 있습니다.
  • 각 요소는 @ Cryostat 주석으로 데코레이팅됩니다.
  • @ Cryostat&gt;-< 주석의 필수 속성은 true 로 설정됩니다.

    예 35.2. “모든 복잡한 유형의 매핑” 두 개의 요소가 있는 모든 복잡한 형식에 대한 매핑을 표시합니다.

    예 35.2. 모든 복잡한 유형의 매핑

    @XmlType(name = "all", propOrder = {
    
    })
    public class All {
        @XmlElement(required = true)
        protected BigDecimal amount;
        @XmlElement(required = true)
        protected String type;
    
        public BigDecimal getAmount() {
            return amount;
        }
    
        public void setAmount(BigDecimal value) {
            this.amount = value;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String value) {
            this.type = value;
        }
    }
    Copy to Clipboard Toggle word wrap
복잡한 유형 선택

선택 복잡한 유형은 choice 요소를 사용하여 정의됩니다. 여기에는 다음과 같이 주석이 있습니다.

  • @ CryostatType 주석의 propOrder 속성은 요소의 이름이 XML 스키마 정의에 표시되는 순서대로 나열됩니다.
  • 멤버 변수에는 주석이 없습니다.

    예 35.3. “선택 복잡한 유형 매핑” 두 개의 요소가 포함된 선택한 복잡한 형식에 대한 매핑을 표시합니다.

    예 35.3. 선택 복잡한 유형 매핑

    @XmlType(name = "choice", propOrder = {
        "address",
        "floater"
    })
    public class Choice {
    
        protected Sequence address;
        protected Float floater;
    
        public Sequence getAddress() {
            return address;
        }
    
        public void setAddress(Sequence value) {
            this.address = value;
        }
    
        public Float getFloater() {
            return floater;
        }
    
        public void setFloater(Float value) {
            this.floater = value;
        }
    
    }
    Copy to Clipboard Toggle word wrap
시퀀스 복잡한 유형

시퀀스 복합 형식은 시퀀스 요소를 사용하여 정의됩니다.A sequence complex type is defined using the sequence element. 여기에는 다음과 같이 주석이 추가됩니다.

  • @ CryostatType 주석의 propOrder 속성은 요소의 이름이 XML 스키마 정의에 표시되는 순서대로 나열됩니다.
  • 각 요소는 @ Cryostat 주석으로 데코레이팅됩니다.
  • @ Cryostat&gt;-< 주석의 필수 속성은 true 로 설정됩니다.

    예 35.4. “시퀀스 복잡한 유형의 매핑” 예 35.1. “XML 스키마 복잡성 유형” 에 정의된 복잡한 유형의 매핑을 보여줍니다.

    예 35.4. 시퀀스 복잡한 유형의 매핑

    @XmlType(name = "sequence", propOrder = {
        "name",
        "street",
        "city",
        "state",
        "zipCode"
    })
    public class Sequence {
    
        @XmlElement(required = true)
        protected String name;
        protected short street;
        @XmlElement(required = true)
        protected String city;
        @XmlElement(required = true)
        protected String state;
        @XmlElement(required = true)
        protected String zipCode;
    
        public String getName() {
            return name;
        }
    
        public void setName(String value) {
            this.name = value;
        }
    
        public short getStreet() {
            return street;
        }
    
        public void setStreet(short value) {
            this.street = value;
        }
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String value) {
            this.city = value;
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String value) {
            this.state = value;
        }
    
        public String getZipCode() {
            return zipCode;
        }
    
        public void setZipCode(String value) {
            this.zipCode = value;
        }
    }
    Copy to Clipboard Toggle word wrap

35.2. 속성

35.2.1. 개요

Apache CXF는 complexType 요소의 범위 내에서 속성 요소 및 attribute Group 요소의 사용을 지원합니다. XML 문서 특성 선언에 대한 구조를 정의할 때 태그 내에서 지정된 정보를 태그에 포함하는 값이 아닌 추가 수단을 제공합니다. 예를 들어 XML 스키마에서 XML 요소 <valuecurrency="euro">410<\value>를 설명하는 경우 통화 속성은 예 35.5. “XML 스키마 정의 및 속성” 에 표시된 대로 특성 요소를 사용하여 설명합니다.

attributeGroup 요소를 사용하면 스키마에서 정의한 모든 복잡한 유형에서 참조할 수 있는 재사용 가능한 속성 그룹을 정의할 수 있습니다. 예를 들어 모두 특성 categorypubDate 를 사용하는 일련의 요소를 정의하는 경우 이러한 특성을 사용하여 특성 그룹을 정의하고 이를 사용하는 모든 요소에서 참조할 수 있습니다. 이는 예 35.7. “특성 그룹 정의” 에 표시됩니다.

애플리케이션 논리 개발에 사용할 데이터 유형을 설명하는 경우 use 특성이 선택 사항으로 설정되거나 필수 로 설정된 속성은 구조의 요소로 처리됩니다. 복잡한 형식 설명에 포함된 각 특성 선언에 대해 적절한 getter 및 setter 메서드와 함께 속성에 대한 클래스에서 요소가 생성됩니다.

35.2.2. XML 스키마에서 속성 정의

XML Schema 특성 요소에는 특성을 식별하는 데 사용되는 하나의 필수 특성인 name 이 있습니다. 또한 표 35.2. “XML 스키마에서 특성을 정의하는 데 사용되는 선택적 속성” 에 설명된 4개의 선택적 속성이 있습니다.

Expand
표 35.2. XML 스키마에서 특성을 정의하는 데 사용되는 선택적 속성
속성설명

사용

속성이 필요한지 여부를 지정합니다. 유효한 값은 필수 값,선택 사항 또는 금지입니다. 선택 사항이 기본값입니다.

type

특성에서 사용할 수 있는 값의 유형을 지정합니다. 사용하지 않는 경우 속성의 스키마 유형을 행으로 정의해야 합니다.

default

속성에 사용할 기본값을 지정합니다. 특성 요소의 use 속성이 선택 사항으로 설정된 경우에만 사용됩니다.

수정됨

속성에 사용할 고정 값을 지정합니다. 특성 요소의 use 속성이 선택 사항으로 설정된 경우에만 사용됩니다.

예 35.5. “XML 스키마 정의 및 속성” 값이 문자열인 속성, 통화, 특성을 정의하는 요소를 표시합니다.

예 35.5. XML 스키마 정의 및 속성

<element name="value">
  <complexType>
    <xsd:simpleContent>
      <xsd:extension base="xsd:integer">
        <xsd:attribute name="currency" type="xsd:string"
                       use="required"/>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:element>
Copy to Clipboard Toggle word wrap

type 속성이 특성 요소에서 생략된 경우 데이터 형식을 인라인으로 설명해야 합니다. 예 35.6. “인라인 데이터 설명이 있는 속성” autobiography,non-fiction 또는 fiction 값을 사용할 수 있는 속성, 카테고리 의 특성 요소를 표시합니다.

예 35.6. 인라인 데이터 설명이 있는 속성

<attribute name="category" use="required">
  <simpleType>
    <restriction base="xsd:string">
      <enumeration value="autobiography"/>
      <enumeration value="non-fiction"/>
      <enumeration value="fiction"/>
    </restriction>
  </simpleType>
</attribute>
Copy to Clipboard Toggle word wrap

35.2.3. XML 스키마에서 특성 그룹 사용

복잡한 유형 정의에서 특성 그룹을 사용하는 작업은 다음 두 단계로 구성됩니다.

  1. 특성 그룹을 정의합니다.

    특성 그룹은 여러 특성 하위 요소가 있는 attribute Group 요소를 사용하여 정의됩니다. attributeGroup 에는 특성 그룹을 참조하는 데 사용되는 문자열을 정의하는 name 속성이 필요합니다. 특성 요소는 특성 그룹의 멤버를 정의하고 “XML 스키마에서 속성 정의” 에 표시된 대로 지정됩니다. 예 35.7. “특성 그룹 정의” 속성 그룹 catalogIndecies 에 대한 설명을 표시합니다. 특성 그룹에는 두 개의 멤버가 있습니다. category, which is optional, and pubDate, which is required.

    예 35.7. 특성 그룹 정의

    <attributeGroup name="catalogIndices">
      <attribute name="category" type="catagoryType" />
      <attribute name="pubDate" type="dateTime"
                 use="required" />
    </attributeGroup>
    Copy to Clipboard Toggle word wrap
  2. 특성 그룹을 복잡한 유형의 정의에 사용합니다.

    ref 속성과 함께 attributeGroup 요소를 사용하여 복잡한 유형 정의에서 특성 그룹을 사용합니다. ref 속성의 값은 형식 정의의 일부로 사용할 특성 그룹이 지정된 이름입니다. 예를 들어 복잡한 유형 dvdType 에서 특성 group catalogIndecies 를 사용하려면 예 35.8. “특성 그룹을 사용하는 복잡한 유형” 에 표시된 대로 <attributeGroup ref="catalogIndecies" />를 사용합니다.

    예 35.8. 특성 그룹을 사용하는 복잡한 유형

    <complexType name="dvdType">
      <sequence>
        <element name="title" type="xsd:string" />
        <element name="director" type="xsd:string" />
        <element name="numCopies" type="xsd:int" />
      </sequence>
      <attributeGroup ref="catalogIndices" />
    </complexType>
    Copy to Clipboard Toggle word wrap

35.2.4. 속성을 Java에 매핑

속성은 멤버 요소가 Java에 매핑되는 것과 거의 동일한 방식으로 Java에 매핑됩니다. 필수 특성 및 선택적 속성은 생성된 Java 클래스에서 멤버 변수에 매핑됩니다. 멤버 변수는 @ CryostatAttribute 주석으로 데코레이팅됩니다. 속성이 필요한 경우 @ CryostatAttribute 주석의 required 속성이 true 로 설정됩니다.

예 35.9. “techdoc 설명” 에 정의된 복잡한 유형은 예 35.10. “techDoc Java Class” 에 표시된 Java 클래스에 매핑됩니다.

예 35.9. techdoc 설명

<complexType name="techDoc">
  <all>
    <element name="product" type="xsd:string" />
    <element name="version" type="xsd:short" />
  </all>
  <attribute name="usefullness" type="xsd:float"
             use="optional" default="0.01" />
</complexType>
Copy to Clipboard Toggle word wrap

예 35.10. techDoc Java Class

@XmlType(name = "techDoc", propOrder = {

})
public class TechDoc {

    @XmlElement(required = true)
    protected String product;
    protected short version;
    @XmlAttribute protected Float usefullness;

    public String getProduct() {
        return product;
    }

    public void setProduct(String value) {
        this.product = value;
    }

    public short getVersion() {
        return version;
    }

    public void setVersion(short value) {
        this.version = value;
    }

    public float getUsefullness() { if (usefullness == null) { return 0.01F; } else { return usefullness; } }

    public void setUsefullness(Float value) {
        this.usefullness = value;
    }
}
Copy to Clipboard Toggle word wrap

예 35.10. “techDoc Java Class” 에 표시된 대로 기본 속성 및 고정 속성은 코드 생성기가 속성에 대해 생성된 getter 메서드에 코드를 추가하도록 지시합니다. 이 추가 코드를 사용하면 값이 설정되지 않은 경우 지정된 값이 반환됩니다.

중요

고정 속성은 default 속성과 동일하게 취급됩니다. 고정 속성을 Java 상수로 처리하려면 38.5절. “고정 값 속성 매핑 사용자 정의” 에 설명된 사용자 지정을 사용할 수 있습니다.

35.2.5. 특성 그룹을 Java에 매핑

특성 그룹은 그룹 멤버가 유형 정의에 명시적으로 사용된 것처럼 Java에 매핑됩니다. 특성 그룹에 세 개의 멤버가 있고 복잡한 형식에 사용되는 경우 해당 유형에 대해 생성된 클래스에는 특성 그룹의 각 멤버에 대해 getter 및 setter 메서드와 함께 멤버 변수가 포함됩니다. 예를 들어 예 35.8. “특성 그룹을 사용하는 복잡한 유형” 에 정의된 복잡한 유형은 Apache CXF에서 멤버 변수 categorypubDate 를 포함하는 클래스를 생성하여 예 35.11. “dvdType Java Class” 에 표시된 대로 특성 그룹의 멤버를 지원합니다.

예 35.11. dvdType Java Class

@XmlType(name = "dvdType", propOrder = {
    "title",
    "director",
    "numCopies"
})
public class DvdType {

    @XmlElement(required = true)
    protected String title;
    @XmlElement(required = true)
    protected String director;
    protected int numCopies;
    @XmlAttribute protected CatagoryType category; @XmlAttribute(required = true) @XmlSchemaType(name = "dateTime") protected XMLGregorianCalendar pubDate;

    public String getTitle() {
        return title;
    }

    public void setTitle(String value) {
        this.title = value;
    }

    public String getDirector() {
        return director;
    }

    public void setDirector(String value) {
        this.director = value;
    }

    public int getNumCopies() {
        return numCopies;
    }

    public void setNumCopies(int value) {
        this.numCopies = value;
    }

    public CatagoryType getCatagory() {
        return catagory;
    }

    public void setCatagory(CatagoryType value) {
        this.catagory = value;
    }

    public XMLGregorianCalendar getPubDate() {
        return pubDate;
    }

    public void setPubDate(XMLGregorianCalendar value) {
        this.pubDate = value;
    }

}
Copy to Clipboard Toggle word wrap

35.3. 간단한 유형에서 복잡한 유형 파생

35.3.1. 개요

Apache CXF는 간단한 유형에서 복잡한 유형의 파생 기능을 지원합니다. 간단한 유형은 정의에 따라 하위 요소나 속성이 모두 없습니다. 따라서 간단한 유형에서 복잡한 유형을 유도하는 주요 이유 중 하나는 간단한 유형에 특성을 추가하는 것입니다.

간단한 유형에서 복잡한 유형을 유도하는 두 가지 방법이 있습니다.

35.3.2. 확장을 통해 파생

예 35.12. “확장을 통해 단순 유형에서 복잡한 유형 파생” 통화 특성을 포함하는 xsd:decimal primitive type의 확장에 의해 파생되는 복잡한 유형 internationalPrice 의 예를 보여줍니다.

예 35.12. 확장을 통해 단순 유형에서 복잡한 유형 파생

<complexType name="internationalPrice">
    <simpleContent>
        <extension base="xsd:decimal">
            <attribute name="currency" type="xsd:string"/>
        </extension>
    </simpleContent>
    </complexType>
Copy to Clipboard Toggle word wrap

simpleContent 요소는 새 형식에 하위 요소가 포함되어 있지 않음을 나타냅니다. extension 요소는 새 유형이 xsd:decimal 을 확장하도록 지정합니다.

35.3.3. 제한을 통해 파생

예 35.13. “제한 사항별 간단한 유형에서 복잡한 유형 파생” xsd:string 의 제한에 의해 파생되는 복잡한 유형 idType 의 예를 보여줍니다. 정의된 유형은 xsd:string의 가능한 값을 10자 길이의 값으로 제한합니다. 또한 유형에 특성을 추가합니다.

예 35.13. 제한 사항별 간단한 유형에서 복잡한 유형 파생

<complexType name="idType">
  <simpleContent>
    <restriction base="xsd:string">
     <length value="10" />
     <attribute name="expires" type="xsd:dateTime" />
    </restriction>
  </simpleContent>
</complexType>
Copy to Clipboard Toggle word wrap

예 35.12. “확장을 통해 단순 유형에서 복잡한 유형 파생” 에서와 마찬가지로 simpleContent 요소는 새 유형에 하위가 포함되어 있지 않음을 나타냅니다. 이 예제에서는 제한 요소를 사용하여 새 형식에 사용되는 가능한 값을 제한합니다. 특성 요소는 새 형식에 요소를 추가합니다.

35.3.4. Java에 매핑

간단한 유형에서 파생된 복잡한 유형은 @ CryostatType 주석으로 데코레이팅되는 Java 클래스에 매핑됩니다. 생성된 클래스에는 복잡한 형식이 파생되는 간단한 형식의 멤버 변수 value 가 포함됩니다. member 변수는 @ CryostatValue 주석으로 데코레이팅됩니다. 또한 클래스에는 getValue() 메서드 및 setValue() 메서드가 있습니다. 또한 생성된 클래스에는 간단한 유형을 확장하는 각 속성에 대해 member 변수와 연결된 getter 및 setter 메서드가 있습니다.

예 35.14. “idType Java Class” 예 35.13. “제한 사항별 간단한 유형에서 복잡한 유형 파생” 에 정의된 idType 유형에 대해 생성된 Java 클래스를 표시합니다.

예 35.14. idType Java Class

@XmlType(name = "idType", propOrder = {
    "value"
})
public class IdType {

    @XmlValue
    protected String value;
    @XmlAttribute
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar expires;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public XMLGregorianCalendar getExpires() {
        return expires;
    }

    public void setExpires(XMLGregorianCalendar value) {
        this.expires = value;
    }

}
Copy to Clipboard Toggle word wrap

35.4. 복잡한 유형에서 복잡한 유형 파생

35.4.1. 개요

XML 스키마를 사용하면 complexContent 요소를 사용하여 다른 복잡한 형식을 확장하거나 제한하여 새로운 복잡한 형식을 파생할 수 있습니다. 파생된 복잡한 유형을 나타내는 Java 클래스를 생성할 때 Apache CXF는 기본 유형의 클래스를 확장합니다. 이러한 방식으로 생성된 Java 코드는 XML 스키마에서 의도한 상속 계층 구조를 유지합니다.

35.4.2. 스키마 구문

complexContent 요소 및 확장 요소 또는 제한 요소를 사용하여 다른 복잡한 형식에서 복잡한 형식을 파생합니다.You derive complex types from other complex types by using the complexContent element, and either the extension element or the restriction element. complexContent 요소는 포함된 데이터 설명이 두 개 이상의 필드를 포함하도록 지정합니다. complexContent 요소의 하위 요소인 extension 요소 및 제한 요소는 새 유형을 생성하기 위해 수정할 기본 유형을 지정합니다. 기본 유형은 base 속성으로 지정됩니다.

35.4.3. 복잡한 유형 확장

복잡한 형식을 확장하려면 extension 요소를 사용하여 새 형식을 구성하는 추가 요소 및 특성을 정의합니다. 복잡한 유형 설명에서 허용되는 모든 요소는 새 형식의 정의의 일부로 사용할 수 있습니다. 예를 들어 새 형식에 익명 열거를 추가하거나 선택 요소를 사용하여 새 필드 중 하나만 사용할 수 있도록 지정할 수 있습니다.For example, you can add an anonymous enumeration to the new type, or you can use the choice element to specify that only one of the new fields can be valid at a time.

예 35.15. “확장을 통해 복잡한 유형 파생” 두 가지 복잡한 유형인 widgetOrderInfowidgetOrderBillInfo 를 정의하는 XML 스키마 조각을 보여줍니다. widgetOrderBillInfowidgetOrderInfo 를 확장하여 orderNumberamtDue 라는 두 개의 새로운 요소를 포함하도록 파생됩니다.

예 35.15. 확장을 통해 복잡한 유형 파생

<complexType name="widgetOrderInfo">
  <sequence>
    <element name="amount" type="xsd:int"/>
    <element name="order_date" type="xsd:dateTime"/>
    <element name="type" type="xsd1:widgetSize"/>
    <element name="shippingAddress" type="xsd1:Address"/>
  </sequence>
  <attribute name="rush" type="xsd:boolean" use="optional" />
</complexType>
<complexType name="widgetOrderBillInfo">
  <complexContent>
    <extension base="xsd1:widgetOrderInfo">
      <sequence>
        <element name="amtDue" type="xsd:decimal"/>
        <element name="orderNumber" type="xsd:string"/>
      </sequence>
      <attribute name="paid" type="xsd:boolean"
                 default="false" />
    </extension>
  </complexContent>
</complexType>
Copy to Clipboard Toggle word wrap

35.4.4. 복잡한 유형 제한

복잡한 유형을 제한하려면 restriction 요소를 사용하여 기본 유형의 요소 또는 특성의 가능한 값을 제한합니다. 복잡한 유형을 제한할 때 기본 유형의 모든 요소 및 특성을 나열해야 합니다. 각 요소에 대해 정의에 제한적인 특성을 추가할 수 있습니다. 예를 들어 요소에 max#187 특성을 추가하여 발생할 수 있는 횟수를 제한할 수 있습니다. 고정 특성을 사용하여 하나 이상의 요소가 사전 결정된 값을 갖도록 할 수도 있습니다.

예 35.16. “제한별 복잡한 유형 정의” 다른 복잡한 유형을 제한하여 복잡한 형식을 정의하는 예를 보여줍니다. 제한된 유형인 wallawallaAddresscity 요소, state 요소 및 zipCode 요소에 대한 값이 고정되어 있기 때문에 walla walla의 주소에만 사용할 수 있습니다.

예 35.16. 제한별 복잡한 유형 정의

<complexType name="Address">
  <sequence>
    <element name="name" type="xsd:string"/>
    <element name="street" type="xsd:short" maxOccurs="3"/>
    <element name="city" type="xsd:string"/>
    <element name="state" type="xsd:string"/>
    <element name="zipCode" type="xsd:string"/>
  </sequence>
</complexType>
<complexType name="wallawallaAddress">
  <complexContent>
    <restriction base="xsd1:Address">
      <sequence>
        <element name="name" type="xsd:string"/>
        <element name="street" type="xsd:short"
                 maxOccurs="3"/>
        <element name="city" type="xsd:string"
                 fixed="WallaWalla"/>
        <element name="state" type="xsd:string"
                 fixed="WA" />
        <element name="zipCode" type="xsd:string"
                 fixed="99362" />
      </sequence>
    </restriction>
  </complexContent>
</complexType>
Copy to Clipboard Toggle word wrap

35.4.5. Java에 매핑

모든 복잡한 유형에서와 마찬가지로 Apache CXF는 다른 복잡한 유형에서 파생된 복잡한 유형을 나타내는 클래스를 생성합니다. 파생된 복잡한 형식에 대해 생성된 Java 클래스는 생성된 Java 클래스를 확장하여 기본 복잡한 유형을 지원합니다. 기본 Java 클래스도 @ CryostatSeeAlso 주석을 포함하도록 수정되었습니다. 기본 클래스의 @ CryostatSeeAlso 주석은 기본 클래스를 확장하는 모든 클래스를 나열합니다.

새로운 complex 유형이 확장에 의해 파생되면 생성된 클래스에는 추가된 모든 요소 및 속성에 대한 멤버 변수가 포함됩니다. 새 멤버 변수는 다른 모든 요소와 동일한 매핑에 따라 생성됩니다.

새로운 complex 유형이 제한에 의해 파생되면 생성된 클래스에는 새 멤버 변수가 없습니다. 생성된 클래스는 단순히 추가 기능을 제공하지 않는 쉘입니다. XML 스키마에 정의된 제한 사항이 적용되도록 하는 것은 전적으로 사용자에게 달려 있습니다.

예를 들어 예 35.15. “확장을 통해 복잡한 유형 파생” 의 스키마는 두 개의 Java 클래스를 생성합니다. 즉, OrderInfo 및 Cryostat BillOrderInfo. widgetOrderBillInfo widgetOrderInfo 의 확장에 의해 파생되기 때문에 CryostatOrderInfo를 확장합니다. 예 35.17. “WidgetOrderBillInfo” widgetOrderBillInfo 에 대한 생성된 클래스를 표시합니다.

예 35.17. WidgetOrderBillInfo

@XmlType(name = "widgetOrderBillInfo", propOrder = {
    "amtDue",
    "orderNumber"
})
public class WidgetOrderBillInfo
    extends WidgetOrderInfo
{
    @XmlElement(required = true)
    protected BigDecimal amtDue;
    @XmlElement(required = true)
    protected String orderNumber;
    @XmlAttribute
    protected Boolean paid;

    public BigDecimal getAmtDue() {
        return amtDue;
    }

    public void setAmtDue(BigDecimal value) {
        this.amtDue = value;
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String value) {
        this.orderNumber = value;
    }

    public boolean isPaid() {
        if (paid == null) {
            return false;
        } else {
            return paid;
        }
    }

    public void setPaid(Boolean value) {
        this.paid = value;
    }
}
Copy to Clipboard Toggle word wrap

35.5. 발생 제한

35.5.1. Occurrence 제약 조건 스키마 지원

XML 스키마를 사용하면 복잡한 유형 정의를 구성하는 XML 스키마 요소 중 4개에 대해 발생 제약 조건을 지정할 수 있습니다.

35.5.2. 모든 요소에 대한 발생 제한

35.5.2.1. XML 스키마

all 요소로 정의된 복합 형식은 모든 요소에서 정의한 구조의 여러 발생을 허용하지 않습니다. 그러나 min#187 특성을 0 으로 설정하여 all 요소에서 정의하는 구조를 선택적으로 설정할 수 있습니다.

35.5.2.2. Java에 매핑

모든 요소의 min#187 속성을 0 으로 설정하면 생성된 Java 클래스에는 영향을 미치지 않습니다.

35.5.3. 선택 요소에 대한 발생 제한

35.5.3.1. 개요

기본적으로 선택 요소의 결과는 복잡한 형식의 인스턴스에서 한 번만 표시될 수 있습니다. 선택한 요소가 선택 요소에 의해 정의된 구조를 나타내기 위해 선택한 요소의 수를 변경할 수 있습니다. min #187 특성 및 해당 mx Cryostat 특성을 사용하여 표시할 수 있습니다. 이러한 특성을 사용하여 선택 유형이 복잡한 유형의 인스턴스에서 무제한으로 0까지 발생할 수 있도록 지정할 수 있습니다. 선택 유형에 대해 선택한 요소는 해당 유형의 각 항목에 대해 같을 필요가 없습니다.

35.5.3.2. XML 스키마에서 사용

min#187 속성은 선택 유형이 표시되어야 하는 최소 횟수를 지정합니다. 값은 양의 정수일 수 있습니다. min#187 특성을 0 으로 설정하면 선택 유형이 복잡한 형식의 인스턴스 내에 표시되지 않도록 지정합니다.

max#187 속성은 선택 유형이 표시될 수 있는 최대 횟수를 지정합니다. 값은 0이 아닌 정수이거나 바인딩되지 않은 정수일 수 있습니다. max#187 특성을 unbounded 로 설정하면 선택 유형이 무한한 횟수로 표시될 수 있습니다.

예 35.18. “선택 Occurrence 제한” 선택 유형의 정의인 Cryostat Event를 선택할 수 있으며 발생 제약 조건이 표시됩니다. 전체 선택 유형을 0에서 바인딩되지 않은 시간에 반복할 수 있습니다.

예 35.18. 선택 Occurrence 제한

<complexType name="ClubEvent">
  <choice minOccurs="0" maxOccurs="unbounded">
    <element name="MemberName" type="xsd:string"/>
    <element name="GuestName" type="xsd:string"/>
  </choice>
</complexType>
Copy to Clipboard Toggle word wrap
35.5.3.3. Java에 매핑

단일 인스턴스 선택 구조와 달리 여러 번 발생할 수 있는 XML 스키마 선택 구조는 단일 멤버 변수를 사용하여 Java 클래스에 매핑됩니다. 이 단일 멤버 변수는 시퀀스의 여러 항목에 대해 모든 데이터를 포함하는 List<T > 개체입니다. 예를 들어 예 35.18. “선택 Occurrence 제한” 에 정의된 시퀀스가 두 번 발생하면 목록에 두 개의 항목이 있습니다.

Java 클래스의 멤버 변수의 이름은 멤버 요소의 이름을 연결하여 파생됩니다. 요소 이름은 Or 로 구분되며 변수 이름의 첫 문자는 소문자로 변환됩니다. 예를 들어 예 35.18. “선택 Occurrence 제한” 에서 생성된 멤버 변수의 이름은 memberNameOrGuestName 입니다.

목록에 저장된 오브젝트 유형은 멤버 요소의 유형 간의 관계에 따라 다릅니다. 예를 들면 다음과 같습니다.

  • 멤버 요소가 동일한 유형인 경우 생성된 목록에는 Cryostat B Cryostat<T> 오브젝트가 포함됩니다. Cryostat B Cryostat<T > 개체의 기본 유형은 멤버 요소의 유형의 일반 매핑에 따라 결정됩니다.
  • 멤버 요소가 서로 다른 유형이며 Java 표현에서 공통 인터페이스를 구현하는 경우 목록에 공통 인터페이스의 개체가 포함됩니다.
  • 멤버 요소가 서로 다른 유형이며 Java 표현에서 공통 기본 클래스를 확장하면 목록에 공통 기본 클래스의 오브젝트가 포함됩니다.
  • 다른 조건이 충족되지 않으면 목록에 Object 개체가 포함됩니다.

생성된 Java 클래스에는 member 변수에 대한 getter 메서드만 있습니다. getter 메서드는 라이브 목록에 대한 참조를 반환합니다. 반환된 목록에 대한 수정 사항은 실제 객체에 영향을 미칩니다.

Java 클래스는 @ CryostatType 주석으로 데코레이팅됩니다. 주석의 name 속성은 XML 스키마 정의의 상위 요소에서 name 속성 값으로 설정됩니다. 주석의 propOrder 속성에는 시퀀스의 요소를 나타내는 단일 멤버 변수가 포함되어 있습니다.

선택한 구조의 요소를 나타내는 멤버 변수는 @ Cryostat Cryostats 주석으로 데코레이팅됩니다. @ Cryostat Cryostats 주석에는 콤마로 구분된 @ Cryostat annotations 목록이 포함되어 있습니다. 목록에는 유형의 XML 스키마 정의에 정의된 각 멤버 요소에 대해 하나의 @ #159 Cryostat 주석이 있습니다. 목록 의 @ Cryostat annotations에는 XML 스키마 요소 요소의 name 속성 값으로 설정되고 XML 스키마 요소 요소의 매핑에서 생성되는 Java 클래스로 설정된 해당 type 속성이 있습니다.

예 35.19. “Occurrence 제약 조건을 사용하여 Java 표현” 예 35.18. “선택 Occurrence 제한” 에 정의된 XML 스키마 선택 구조에 대한 Java 매핑을 보여줍니다.

예 35.19. Occurrence 제약 조건을 사용하여 Java 표현

@XmlType(name = "ClubEvent", propOrder = {
    "memberNameOrGuestName"
})
public class ClubEvent {

    @XmlElementRefs({
        @XmlElementRef(name = "GuestName", type = JAXBElement.class),
        @XmlElementRef(name = "MemberName", type = JAXBElement.class)
    })
    protected List<JAXBElement<String>> memberNameOrGuestName;

    public List<JAXBElement<String>> getMemberNameOrGuestName() {
        if (memberNameOrGuestName == null) {
            memberNameOrGuestName = new ArrayList<JAXBElement<String>>();
        }
        return this.memberNameOrGuestName;
    }

}
Copy to Clipboard Toggle word wrap
35.5.3.4. min Cryostat 0으로 설정

min#187 요소만 지정되고 해당 값이 0 이면 코드 생성기는 min #187 속성이 설정되지 않은 것처럼 Java 클래스를 생성합니다.

35.5.4. Cryostat에 대한 발생 제한

35.5.4.1. 개요

요소 요소의 min #187 특성 및 max Cryostat 특성을 사용하여 복잡한 유형의 특정 요소가 표시되는 횟수를 지정할 수 있습니다. 두 속성의 기본값은 1 입니다.

35.5.4.2. min Cryostat 0으로 설정

complex 유형의 member 요소의 min Cryostat 속성 중 하나를 0 으로 설정하면 해당 Java 멤버 변수를 데코딩하는 @ Cryostat 주석이 변경됩니다. 필수 속성을 true 로 설정하는 대신 @ Cryostat 주석필수 속성이 false 로 설정됩니다.

35.5.4.3. min Cryostat를 1보다 큰 값으로 설정합니다.

XML 스키마에서는 요소의 min#187 특성을 둘 이상의 값으로 설정하여 형식 인스턴스에서 요소를 두 번 이상 발생 하도록 지정할 수 있습니다. 그러나 생성된 Java 클래스는 XML 스키마 제약 조건을 지원하지 않습니다. Apache CXF는 min #187 속성이 설정되지 않은 것처럼 지원 Java 멤버 변수를 생성합니다.

35.5.4.4. max#187 set가 있는 요소

멤버 요소가 복잡한 유형의 인스턴스에서 여러 번 표시되도록 하려면 요소의 max Cryostat 특성을 1보다 큰 값으로 설정합니다. max#187 특성의 값을 unbounded 로 설정하여 멤버 요소가 무제한으로 표시될 수 있도록 지정할 수 있습니다.

코드 생성기는 max #187 특성이 1보다 큰 값으로 멤버 요소를 List<T > 개체인 Java 멤버 변수에 매핑합니다. 목록의 기본 클래스는 요소의 유형을 Java에 매핑하여 결정됩니다. XML 스키마 기본 유형의 경우 “래퍼 클래스” 에 설명된 대로 래퍼 클래스가 사용됩니다. 예를 들어 멤버 요소가 xsd:int 유형의 경우 생성된 멤버 변수는 List<Integer> 개체입니다.For example, if the member element is of type xsd:int the generated member variable is a List<Integer > object.

35.5.5. 시퀀스에 대한 발생 제한

35.5.5.1. 개요

기본적으로 시퀀스 요소의 내용은 복잡한 형식의 인스턴스에서 한 번만 나타날 수 있습니다.By default, the contents of a sequence element can only appear once in an instance of a complex type. 시퀀스 요소에서 정의한 요소 시퀀스를 변경할 수 있는 횟수를 변경할 수 있습니다. min #187 속성 및 max Cryostat 특성을 사용하여 표시할 수 있습니다. 이러한 특성을 사용하여 시퀀스 유형이 복잡한 형식의 인스턴스에서 무제한 0으로 발생할 수 있도록 지정할 수 있습니다.Using these attributes you can occur that the sequence type can occur zero to an unlimited number of times in an instance of a complex type.

35.5.5.2. XML 스키마 사용

min#187 속성은 정의된 복합 형식의 인스턴스에서 시퀀스가 발생해야 하는 최소 횟수를 지정합니다. 값은 양의 정수일 수 있습니다. min#187 특성을 0 으로 설정하면 시퀀스가 복잡한 형식의 인스턴스 내에 표시되지 않도록 지정합니다.

max#187 속성은 정의된 복잡한 형식의 인스턴스에서 시퀀스가 발생할 수 있는 횟수에 대한 상한을 지정합니다. 값은 0이 아닌 정수이거나 바인딩되지 않은 정수일 수 있습니다. max#187 특성을 unbounded 로 설정하면 시퀀스가 무한한 횟수만큼 표시될 수 있습니다.

예 35.20. “Occurrence 제약 조건이 있는 순서” 시퀀스 발생 제약 조건이 있는 시퀀스 유형 Cryostat의 정의를 표시합니다. 시퀀스는 0에서 2 번 반복할 수 있습니다.

예 35.20. Occurrence 제약 조건이 있는 순서

<complexType name="CultureInfo">
  <sequence minOccurs="0" maxOccurs="2">
    <element name="Name" type="string"/>
    <element name="Lcid" type="int"/>
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap
35.5.5.3. Java에 매핑

단일 인스턴스 순서와 달리 여러 번 발생할 수 있는 XML 스키마 시퀀스는 단일 멤버 변수를 사용하여 Java 클래스에 매핑됩니다. 이 단일 멤버 변수는 시퀀스의 여러 항목에 대해 모든 데이터를 포함하는 List<T > 개체입니다. 예를 들어 예 35.20. “Occurrence 제약 조건이 있는 순서” 에 정의된 시퀀스가 두 번 발생하면 목록에 4개의 항목이 포함됩니다.

Java 클래스의 멤버 변수의 이름은 멤버 요소의 이름을 연결하여 파생됩니다. 요소 이름은 AND로 구분되고 변수 이름의 첫 문자는 소문자로 변환됩니다. 예를 들어 예 35.20. “Occurrence 제약 조건이 있는 순서” 에서 생성된 멤버 변수의 이름은 nameAndLcid 입니다.

목록에 저장된 오브젝트 유형은 멤버 요소의 유형 간의 관계에 따라 다릅니다. 예를 들면 다음과 같습니다.

  • 멤버 요소가 동일한 유형인 경우 생성된 목록에는 Cryostat B Cryostat<T> 오브젝트가 포함됩니다. Cryostat B Cryostat<T > 개체의 기본 유형은 멤버 요소의 유형의 일반 매핑에 따라 결정됩니다.
  • 멤버 요소가 서로 다른 유형이며 Java 표현에서 공통 인터페이스를 구현하는 경우 목록에 공통 인터페이스의 개체가 포함됩니다.
  • 멤버 요소가 서로 다른 유형이며 Java 표현에서 공통 기본 클래스를 확장하면 목록에 공통 기본 클래스의 오브젝트가 포함됩니다.
  • 다른 조건이 충족되지 않으면 목록에 Object 개체가 포함됩니다.

생성된 Java 클래스에는 member 변수에 대한 getter 메서드만 있습니다. getter 메서드는 라이브 목록에 대한 참조를 반환합니다. 반환된 목록에 대한 수정 사항은 실제 객체에 영향을 미칩니다.

Java 클래스는 @ CryostatType 주석으로 데코레이팅됩니다. 주석의 name 속성은 XML 스키마 정의의 상위 요소에서 name 속성 값으로 설정됩니다. 주석의 propOrder 속성에는 시퀀스의 요소를 나타내는 단일 멤버 변수가 포함되어 있습니다.

시퀀스의 요소를 나타내는 멤버 변수는 @ Cryostat Cryostats 주석으로 데코레이팅됩니다. @ Cryostat Cryostats 주석에는 콤마로 구분된 @ Cryostat annotations 목록이 포함되어 있습니다. 목록에는 유형의 XML 스키마 정의에 정의된 각 멤버 요소에 대해 하나의 @ #159 Cryostat 주석이 있습니다. 목록 의 @ Cryostat annotations에는 XML 스키마 요소 요소의 name 속성 값으로 설정되고 XML 스키마 요소 요소의 매핑에서 생성되는 Java 클래스로 설정된 해당 type 속성이 있습니다.

예 35.21. “Occurrence 제약 조건을 사용한 시퀀스 표현” 예 35.20. “Occurrence 제약 조건이 있는 순서” 에 정의된 XML 스키마 시퀀스의 Java 매핑을 보여줍니다.

예 35.21. Occurrence 제약 조건을 사용한 시퀀스 표현

@XmlType(name = "CultureInfo", propOrder = {
    "nameAndLcid"
})
public class CultureInfo {

    @XmlElements({
        @XmlElement(name = "Name", type = String.class),
        @XmlElement(name = "Lcid", type = Integer.class)
    })
    protected List<Serializable> nameAndLcid;

    public List<Serializable> getNameAndLcid() {
        if (nameAndLcid == null) {
            nameAndLcid = new ArrayList<Serializable>();
        }
        return this.nameAndLcid;
    }

}
Copy to Clipboard Toggle word wrap
35.5.5.4. min Cryostat 0으로 설정

min#187 요소만 지정되고 해당 값이 0 이면 코드 생성기는 min #187 속성이 설정되지 않은 것처럼 Java 클래스를 생성합니다.

35.6. 모델 그룹 사용

35.6.1. 개요

XML 스키마 모델 그룹은 사용자 정의 복잡한 유형의 요소 그룹을 참조할 수 있는 편리한 바로 가기입니다. 예를 들어 애플리케이션의 여러 유형에 공통된 요소 그룹을 정의한 다음 그룹을 반복적으로 참조할 수 있습니다. 모델 그룹은 group 요소를 사용하여 정의되며 복잡한 유형 정의와 유사합니다. 모델 그룹을 Java로 매핑하는 것도 복잡한 유형의 매핑과 유사합니다.

35.6.2. XML 스키마에서 모델 그룹 정의

name 속성이 있는 group 요소를 사용하여 XML 스키마에서 모델 그룹을 정의합니다. name 특성의 값은 스키마 전체에서 그룹을 참조하는 데 사용되는 문자열입니다. group 요소는 complexType 요소와 마찬가지로 sequence 요소, all 요소 또는 선택 요소를 즉시 자식으로 포함할 수 있습니다.

자식 요소 내에서 요소 요소를 사용하여 그룹의 멤버를 정의합니다.In the child element, you define the members of the group using element elements. 그룹의 각 멤버에 대해 하나의 요소를 지정합니다. 그룹 멤버는 min #187 및 max#187를 포함한 요소 요소에 대해 표준 특성 중 하나를 사용할 수 있습니다. 따라서 그룹에 세 개의 요소가 있고 그 중 하나가 최대 세 번 발생할 수 있는 경우 세 개의 요소 요소가 있는 그룹을 정의합니다. 예 35.22. “XML 스키마 모델 그룹” 세 개의 요소가 있는 모델 그룹을 표시합니다.

예 35.22. XML 스키마 모델 그룹

<group name="passenger">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="clubNum" type="xsd:long" />
    <element name="seatPref" type="xsd:string"
             maxOccurs="3" />
  </sequence>
</group>
Copy to Clipboard Toggle word wrap

35.6.3. 유형 정의에서 모델 그룹 사용

모델 그룹이 정의되면 복잡한 유형 정의의 일부로 사용할 수 있습니다. 복잡한 유형 정의에서 모델 그룹을 사용하려면 ref 특성과 함께 group 요소를 사용합니다. ref 속성의 값은 해당 값이 정의될 때 그룹에 지정된 이름입니다. 예를 들어 예 35.22. “XML 스키마 모델 그룹” 에 정의된 그룹을 사용하려면 {ref="tns:passenger" > 에 표시된 대로 예 35.23. “모델 그룹이 포함된 복잡한 유형” 를 사용합니다.

예 35.23. 모델 그룹이 포함된 복잡한 유형

<complexType name="reservation">
  <sequence>
    <group ref="tns:passenger" />
    <element name="origin" type="xsd:string" />
    <element name="destination" type="xsd:string" />
    <element name="fltNum" type="xsd:long" />
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap

유형 정의에 모델 그룹을 사용하면 그룹이 유형의 멤버가 됩니다. 따라서 예약 인스턴스에는 4개의 멤버 요소가 있습니다. 첫 번째 요소는 여객 요소이며 예 35.22. “XML 스키마 모델 그룹” 에 표시된 그룹에 의해 정의된 멤버 요소를 포함합니다. 예약 인스턴스의 예는 예 35.24. “모델 그룹이 있는 Type의 인스턴스” 에 표시되어 있습니다.

예 35.24. 모델 그룹이 있는 Type의 인스턴스

<reservation>
  <passenger> <name>A. Smart</name> <clubNum>99</clubNum> <seatPref>isle1</seatPref> </passenger>
  <origin>LAX</origin>
  <destination>FRA</destination>
  <fltNum>34567</fltNum>
</reservation>
Copy to Clipboard Toggle word wrap

35.6.4. Java에 매핑

기본적으로 모델 그룹은 복잡한 유형 정의에 포함된 경우에만 Java 아티팩트에 매핑됩니다. 모델 그룹을 포함하는 복잡한 유형에 대한 코드를 생성할 때 Apache CXF는 모델 그룹의 멤버 변수를 유형에 대해 생성된 Java 클래스에 간단하게 포함합니다. 모델 그룹을 나타내는 멤버 변수에는 모델 그룹의 정의에 따라 주석이 추가됩니다.

예 35.25. “유형 그룹” 예 35.23. “모델 그룹이 포함된 복잡한 유형” 에 정의된 복잡한 유형에 대해 생성된 Java 클래스를 표시합니다.

예 35.25. 유형 그룹

@XmlType(name = "reservation", propOrder = {
    "name",
    "clubNum",
    "seatPref",
    "origin",
    "destination",
    "fltNum"
})
public class Reservation {

    @XmlElement(required = true)
    protected String name;
    protected long clubNum;
    @XmlElement(required = true)
    protected List<String> seatPref;
    @XmlElement(required = true)
    protected String origin;
    @XmlElement(required = true)
    protected String destination;
    protected long fltNum;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public long getClubNum() {
        return clubNum;
    }

    public void setClubNum(long value) {
        this.clubNum = value;
    }

    public List<String> getSeatPref() {
        if (seatPref == null) {
            seatPref = new ArrayList<String>();
        }
        return this.seatPref;
    }

    public String getOrigin() {
        return origin;
    }

    public void setOrigin(String value) {
        this.origin = value;
    }

    public String getDestination() {
        return destination;
    }

    public void setDestination(String value) {
        this.destination = value;
    }

    public long getFltNum() {
        return fltNum;
    }

    public void setFltNum(long value) {
        this.fltNum = value;
    }
Copy to Clipboard Toggle word wrap

35.6.5. 여러 발생

그룹 요소의 max Cryostat 속성을 둘 이상의 값으로 설정하여 모델 그룹이 두 번 이상 표시되도록 지정할 수 있습니다. 모델 그룹 Apache CXF의 여러 발생을 허용하려면 모델 그룹을 List<T> 오브젝트에 매핑 합니다. List<T > 오브젝트는 그룹의 첫 번째 하위 규칙에 따라 생성됩니다.

36장. 와일드카드 유형 사용

초록

스키마 작성자가 정의된 형식에 바인딩 요소 또는 특성을 지연하려고 하는 인스턴스가 있습니다. 이러한 경우 XML 스키마는 와일드카드 위치 소유자를 지정하기 위한 세 가지 메커니즘을 제공합니다. 모두 XML 스키마 기능을 유지하는 방식으로 Java에 매핑됩니다.

36.1. 모든 사람 사용

36.1.1. 개요

XML 스키마는 모든 요소가 복잡한 유형 정의에서 와일드카드 위치 소유자를 만드는 데 사용됩니다. XML 요소가 XML 스키마에 대해 인스턴스화되는 경우 유효한 XML 요소일 수 있습니다. 모든 요소는 인스턴스화된 XML 요소의 콘텐츠 또는 이름에 제한이 없습니다.

예를 들어 예 36.1. “모든 요소를 사용하여 정의된 XML 스키마 유형” 에 정의된 복잡한 유형이 있는 경우 예 36.2. “모든 요소가 포함된 XML 문서” 에 표시된 XML 요소 중 하나를 인스턴스화할 수 있습니다.

예 36.1. 모든 요소를 사용하여 정의된 XML 스키마 유형

<element name="FlyBoy">
  <complexType>
    <sequence>
      <any />
      <element name="rank" type="xsd:int" />
    </sequence>
  </complexType>
</element>
Copy to Clipboard Toggle word wrap

예 36.2. 모든 요소가 포함된 XML 문서

<FlyBoy>
  <learJet>CL-215</learJet>
  <rank>2</rank>
</element>
<FlyBoy>
  <viper>Mark II</viper>
  <rank>1</rank>
</element>
Copy to Clipboard Toggle word wrap

XML 스키마는 Java Object 개체 또는 Java org.w3c.dom. Cryostat 개체에 매핑 됩니다.

36.1.2. XML 스키마로 지정

시퀀스 복잡한 유형 및 선택 복잡한 유형을 정의할 때 any element를 사용할 수 있습니다. 대부분의 경우 모든 요소는 빈 요소입니다. 그러나 주석 요소를 자식으로 사용할 수 있습니다.

표 36.1. “XML 스키마의 모든 요소” 모든 요소의 특성에 대해 설명합니다.

Expand
표 36.1. XML 스키마의 모든 요소
속성설명

namespace

XML 문서에서 요소를 인스턴스화하는 데 사용할 수 있는 요소의 네임스페이스를 지정합니다. 유효한 값은 다음과 같습니다.

##any
네임스페이스의 요소를 사용할 수 있도록 지정합니다. 이는 기본값입니다.
##other
부모 요소의 네임스페이스 이외의 모든 네임스페이스의 요소를 사용할 수 있도록 지정합니다.
##local
네임스페이스가 없는 요소를 사용해야 합니다.
##targetNamespace
부모 요소의 네임스페이스의 요소를 사용해야 합니다.
공백으로 구분된 URI 목록 #\#local\#\#targetNamespace
나열된 네임스페이스의 요소를 사용할 수 있도록 지정합니다.

maxOccurs

요소의 인스턴스가 부모 요소에 나타날 수 있는 최대 횟수를 지정합니다. 기본값은 1 입니다. 요소의 인스턴스가 무제한으로 표시될 수 있도록 지정하려면 특성의 값을 바인딩되지 않은 상태로 설정할 수 있습니다.

minOccurs

요소 인스턴스가 부모 요소에 나타날 수 있는 최소 횟수를 지정합니다. 기본값은 1 입니다.

processContents

유효성을 검사해야 하는 모든 요소를 인스턴스화하는 데 사용되는 요소를 지정합니다. 유효한 값은 다음과 같습니다.

Strict
적절한 스키마에 대해 요소의 유효성을 검사하도록 지정합니다. 이는 기본값입니다.
lax
적절한 스키마에 대해 요소의 유효성을 검사하도록 지정합니다. 유효성을 검사할 수 없는 경우 오류가 발생하지 않습니다.
skip
요소의 유효성을 검사하지 않도록 지정합니다.

예 36.3. “Any Element로 정의된 complex type” 모든 요소로 정의된 복잡한 유형을 표시합니다.

예 36.3. Any Element로 정의된 complex type

<complexType name="surprisePackage">
  <sequence>
    <any processContents="lax" />
    <element name="to" type="xsd:string" />
    <element name="from" type="xsd:string" />
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap

36.1.3. Java에 매핑

XML 스키마 를 사용하면 모든 요소가 이름이 지정된 Java 속성이 생성됩니다. 속성에 getter 및 setter 메서드가 연결되어 있습니다. 결과 속성의 유형은 요소의 processContents 속성 값에 따라 달라집니다. 임의의 요소의 processContents 속성이 skip 으로 설정된 경우 요소가 org.w3c.dom.dom. Cryostat 오브젝트에 매핑 됩니다. processContents 속성의 다른 모든 값에 대해 모든 요소가 Java Object 개체에 매핑됩니다.

생성된 속성은 @ CryostatAny Cryostat 주석으로 데코레이팅됩니다. 이 주석에는 데이터를 마샬링할 때 런타임에 수행할 작업을 지시하는 선택적 lax 속성이 있습니다. 기본값은 false 로, 런타임에서 데이터를 org.w3c.dom. Cryostat 개체로 자동으로 마샬링하도록 지시합니다. laxtrue 로 설정하면 런타임에서 데이터를 CryostatB 유형으로 마샬링하도록 지시합니다. 임의의 요소의 processContents 속성이 skip 으로 설정되면 lax 속성이 기본값으로 설정됩니다. processContents 속성의 다른 모든 값에 대해 laxtrue 로 설정됩니다.

예 36.4. “모든 요소가 포함된 Java 클래스” 예 36.3. “Any Element로 정의된 complex type” 에 정의된 복잡한 유형이 Java 클래스에 매핑되는 방법을 보여줍니다.

예 36.4. 모든 요소가 포함된 Java 클래스

public class SurprisePackage {

    @XmlAnyElement(lax = true) protected Object any;
    @XmlElement(required = true)
    protected String to;
    @XmlElement(required = true)
    protected String from;

    public Object getAny() { return any; }

    public void setAny(Object value) { this.any = value; }

    public String getTo() {
        return to;
    }

    public void setTo(String value) {
        this.to = value;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String value) {
        this.from = value;
    }

}
Copy to Clipboard Toggle word wrap

36.1.4. 마샬링

모든 요소의 Java 속성에 laxfalse 로 설정되어 있거나 속성이 지정되지 않은 경우 런타임에서 XML 데이터를 CryostatB 개체로 구문 분석하려고 하지 않습니다. 데이터는 항상 Cryostat Element 오브젝트에 저장됩니다.

모든 요소의 Java 속성에 laxtrue 로 설정된 경우 런타임은 XML 데이터를 적절한 CryostatB 객체로 마샬링하려고 시도합니다. 런타임은 다음 절차를 사용하여 적절한 Cryostat 클래스를 식별하려고 합니다.

  1. 런타임에 알려진 요소 목록에 대해 XML 요소의 요소 태그를 확인합니다. 일치하는 항목을 찾으면 런타임에서 XML 데이터를 요소의 적절한 CryostatB 클래스로 마샬링합니다.
  2. XML 요소의 xsi:type 특성을 확인합니다. 일치하는 항목을 찾으면 런타임에서 XML 요소를 해당 유형의 적절한 CryostatB 클래스로 마샬링합니다.
  3. 일치하는 항목을 찾을 수 없는 경우 XML 데이터를 Cryostat Element 개체로 마샬링합니다.

일반적으로 애플리케이션의 런타임은 계약에 포함된 스키마에서 생성된 모든 유형에 대해 알고 있습니다. 여기에는 계약의 wsdl:types 요소에 정의된 유형, 포함을 통해 계약에 추가된 모든 데이터 유형, 다른 스키마 가져오기를 통해 계약에 추가된 모든 유형이 포함됩니다. 32.4절. “런타임 Marshaller에 클래스 추가” 에 설명된 @ CryostatSeeAlso 주석을 사용하여 런타임에서 추가 유형을 인식할 수도 있습니다.

36.1.5. unmarshalling

모든 요소의 Java 속성에 laxfalse 로 설정되어 있거나 속성이 지정되지 않은 경우 런타임은 Cryostat Element 개체만 허용합니다. 다른 유형의 오브젝트를 사용하려고 하면 마샬링 오류가 발생합니다.

모든 요소의 Java 속성에 laxtrue 로 설정된 경우 런타임은 Java 데이터 유형과 해당 형식의 XML 스키마 구조 간의 내부 맵을 사용하여 이 요소에 쓸 XML 구조를 결정합니다. 런타임에서 클래스를 알고 XML 스키마 구조에 매핑할 수 있는 경우 데이터를 작성하고 xsi:type 속성을 삽입하여 요소가 포함하는 데이터 유형을 식별합니다.

런타임에서 Java 개체를 알려진 XML 스키마 구조에 매핑할 수 없는 경우 마샬링 예외가 발생합니다. 32.4절. “런타임 Marshaller에 클래스 추가” 에 설명된 @ CryostatSeeAlso 주석을 사용하여 런타임 맵에 형식을 추가할 수 있습니다.

36.2. XML Schema anyType 유형 사용

36.2.1. 개요

XML Schema 유형 xsd:anyType 은 모든 XML 스키마 유형의 루트 유형입니다. 모든 프리미티브는 모든 사용자가 정의한 복잡한 유형과 마찬가지로 이 유형의 파생체입니다. 결과적으로 xsd:anyType 으로 정의된 요소는 스키마 문서에 정의된 모든 복잡한 유형뿐만 아니라 XML 스키마 프리미티브의 형태로 데이터를 포함할 수 있습니다.

Java에서 가장 일치하는 유형은 Object 클래스입니다. 다른 모든 Java 클래스가 하위 형식의 클래스입니다.

36.2.2. XML 스키마에서 사용

다른 XML 스키마 복잡한 유형과 마찬가지로 xsd:anyType 유형을 사용합니다. 요소의 type 요소의 값으로 사용할 수 있습니다. 다른 유형이 정의된 기본 유형으로도 사용할 수 있습니다.

예 36.5. “와일드카드 요소가 포함된 복잡한 유형” Xsd :anyType 유형의 요소를 포함하는 복잡한 유형의 예를 보여줍니다.

예 36.5. 와일드카드 요소가 포함된 복잡한 유형

<complexType name="wildStar">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="ship" type="xsd:anyType" />
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap

36.2.3. Java에 매핑

xsd:anyType 유형의 요소는 Object 오브젝트에 매핑됩니다. 예 36.6. “Java 카드 요소 표시” 예 36.5. “와일드카드 요소가 포함된 복잡한 유형” 에서 Java 클래스에 대한 매핑을 표시합니다.

예 36.6. Java 카드 요소 표시

public class WildStar {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true) protected Object ship;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public Object getShip() { return ship; }

    public void setShip(Object value) { this.ship = value; }
}
Copy to Clipboard Toggle word wrap

이 매핑을 사용하면 와일드카드 요소를 나타내는 속성에 모든 데이터를 배치할 수 있습니다. Apache CXF 런타임은 데이터를 사용 가능한 Java 표현으로 마샬링 및 비마태링합니다.

36.2.4. 마샬링

Apache CXF가 XML 데이터를 Java 유형으로 마샬링하면 모든Type 요소를 알려진 CryostatB 객체로 마샬링합니다. anyType 요소가 생성된 오브젝트로 마샬링될 수 있는지 확인하기 위해 런타임은 요소의 xsi:type 특성을 검사하여 요소에서 데이터를 구성하는 데 사용되는 실제 유형을 결정합니다. xsi:type 속성이 없으면 런타임은 인트로스펙션을 통해 요소의 실제 데이터 유형을 식별하려고 합니다. 요소의 실제 데이터 유형이 애플리케이션's CryostatB 컨텍스트에서 알려진 유형 중 하나로 결정되면 해당 요소는 적절한 유형의 개체로 마샬링됩니다.

런타임에서 요소의 실제 데이터 유형을 확인할 수 없거나 요소의 실제 데이터 형식이 알려진 유형이 아닌 경우 런타임은 콘텐츠를 org.w3c.dom. Cryostat 개체로 마샬링합니다. 그런 다음 192.0.2. APis를 사용하여 요소의 콘텐츠를 작업해야합니다.

애플리케이션 런타임은 일반적으로 계약에 포함된 스키마에서 생성된 모든 유형을 알고 있습니다. 여기에는 계약의 wsdl:types 요소에 정의된 유형, 포함을 통해 계약에 추가된 모든 데이터 유형, 다른 스키마 문서 가져오기를 통해 계약에 추가된 모든 유형이 포함됩니다. 32.4절. “런타임 Marshaller에 클래스 추가” 에 설명된 @ CryostatSeeAlso 주석을 사용하여 런타임에서 추가 유형을 인식할 수도 있습니다.

36.2.5. unmarshalling

Apache CXF에서 XML 데이터로 Java 유형을 unmarshalshal하면 Java 데이터 유형과 XML 스키마 구조 간의 내부 맵을 사용하여 이니어에 쓸 XML 구조를 결정합니다. 런타임에서 클래스를 알고 XML 스키마 구조에 클래스를 매핑할 수 있는 경우 데이터를 작성하고 xsi:type 속성을 삽입하여 요소가 포함하는 데이터 유형을 식별합니다. 데이터가 org.w3c.dom. Cryostat 개체에 저장된 경우 런타임은 개체에 의해 표시되는 XML 구조를 작성하지만 xsi:type 특성은 포함하지 않습니다.

런타임에서 Java 개체를 알려진 XML 스키마 구조에 매핑할 수 없는 경우 마샬링 예외가 발생합니다. 32.4절. “런타임 Marshaller에 클래스 추가” 에 설명된 @ CryostatSeeAlso 주석을 사용하여 런타임 맵에 형식을 추가할 수 있습니다.

36.3. 바인딩되지 않은 속성 사용

36.3.1. 개요

XML 스키마에는 복잡한 유형 정의에서 임의의 특성에 대한 위치 소유자를 남겨 둘 수 있는 메커니즘이 있습니다. 이 메커니즘을 사용하면 특성을 가질 수 있는 복잡한 유형을 정의할 수 있습니다. 예를 들어 세 가지 특성을 지정하지 않고 <robot name="epsilon" />, <robot age="10000" /> 또는 <robot type="weevil" /> 요소를 정의하는 유형을 생성할 수 있습니다. 이는 데이터의 유연성이 필요한 경우 특히 유용할 수 있습니다.

36.3.2. XML 스키마로 정의

선언되지 않은 속성은 anyAttribute 요소를 사용하여 XML 스키마에 정의됩니다. 특성 요소를 사용할 수 있는 모든 곳에서 사용할 수 있습니다. anyAttribute 요소에는 예 36.7. “선언되지 않은 속성이 있는 complex type” 에 표시된 대로 속성이 없습니다.

예 36.7. 선언되지 않은 속성이 있는 complex type

<complexType name="arbitter">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="rate" type="xsd:float" />
  </sequence>
  <anyAttribute />
</complexType>
Copy to Clipboard Toggle word wrap

정의된 유형인 arbitter 에는 두 개의 요소가 있으며 모든 유형의 하나의 특성을 가질 수 있습니다. 예 36.8. “Wild Card 특성으로 정의된 Cryostat의 예” 에 표시된 요소 3개 요소는 모두 복잡한 유형 arbitter 에서 생성할 수 있습니다.

예 36.8. Wild Card 특성으로 정의된 Cryostat의 예

<officer rank="12"><name>...</name><rate>...</rate></officer>
<lawyer type="divorce"><name>...</name><rate>...</rate></lawyer>
<judge><name>...</name><rate>...</rate></judge>
Copy to Clipboard Toggle word wrap

36.3.3. Java에 매핑

anyAttribute 요소가 포함된 복잡한 유형이 Java에 매핑되면 코드 생성기는 otherAttributes 라는 멤버를 생성된 클래스에 추가합니다. otherAttributes 유형은 java.util.Map<QName, String >이며 맵의 라이브 인스턴스를 반환하는 getter 메서드가 있습니다. getter에서 반환된 맵이 적용되므로 맵에 대한 모든 수정 사항이 자동으로 적용됩니다. 예 36.9. “선언되지 않은 속성을 사용하는 복잡한 유형 클래스” 예 36.7. “선언되지 않은 속성이 있는 complex type” 에 정의된 복잡한 유형에 대해 생성된 클래스를 표시합니다.

예 36.9. 선언되지 않은 속성을 사용하는 복잡한 유형 클래스

public class Arbitter {

    @XmlElement(required = true)
    protected String name;
    protected float rate;

    @XmlAnyAttribute private Map<QName, String> otherAttributes = new HashMap<QName, String>();

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public float getRate() {
        return rate;
    }

    public void setRate(float value) {
        this.rate = value;
    }

    public Map<QName, String> getOtherAttributes() { return otherAttributes; }

}
Copy to Clipboard Toggle word wrap

36.3.4. 선언되지 않은 속성 작업

생성된 클래스의 otherAttributes 멤버는 Map 오브젝트로 채워져 있어야 합니다. 맵은 QNames 를 사용하여 키가 지정됩니다. 맵을 가져온 후 오브젝트에 설정된 모든 속성에 액세스하고 오브젝트에서 새 속성을 설정할 수 있습니다.

예 36.10. “선언되지 않은 속성 작업” 선언되지 않은 특성으로 작업하기 위한 샘플 코드를 보여줍니다.

예 36.10. 선언되지 않은 속성 작업

Arbitter judge = new Arbitter();
Map<QName, String> otherAtts = judge.getOtherAttributes();

QName at1 = new QName("test.apache.org", "house");
QName at2 = new QName("test.apache.org", "veteran");

otherAtts.put(at1, "Cape");
otherAtts.put(at2, "false");

String vetStatus = otherAtts.get(at2);
Copy to Clipboard Toggle word wrap

예 36.10. “선언되지 않은 속성 작업” 의 코드는 다음을 수행합니다.

선언되지 않은 속성이 포함된 맵을 가져옵니다.

특성을 사용할 QNames를 생성합니다.

속성 값을 맵으로 설정합니다.

특성 중 하나에 대한 값을 검색합니다.

37장. 요소 하위 항목

초록

XML 스키마 대체 그룹을 사용하면 최상위 수준 또는 헤드 요소를 교체할 수 있는 요소 그룹을 정의할 수 있습니다. 이 기능은 공통 기본 유형 또는 상호 교환이 필요한 요소를 공유하는 여러 요소가 있는 경우에 유용합니다.

37.1. XML 스키마의 대체 그룹

37.1.1. 개요

대체 그룹은 해당 스키마에서 생성된 문서의 다른 요소를 교체할 수 있는 요소를 지정할 수 있는 XML 스키마의 기능입니다. 교체 가능 요소는 head 요소라고 하며 스키마의 전역 범위에 정의되어 있어야 합니다. 대체 그룹의 요소는 head 요소와 동일한 유형 또는 헤드 요소의 유형에서 파생되어야 합니다.

본질적으로 대체 그룹을 사용하면 일반 요소를 사용하여 지정할 수 있는 요소 컬렉션을 빌드할 수 있습니다. 예를 들어 세 가지 유형의 위젯을 판매한 회사의 주문 시스템을 구축하는 경우 세 가지 위젯 유형에 대한 공통 데이터 세트가 포함된 일반 위젯 요소를 정의할 수 있습니다. 그런 다음 각 위젯 유형에 대해 보다 구체적인 데이터 세트를 포함하는 대체 그룹을 정의할 수 있습니다. 계약에서 각 위젯 유형에 대한 특정 순서 작업을 정의하는 대신 일반 위젯 요소를 메시지 부분으로 지정할 수 있습니다. 실제 메시지가 작성되면 메시지에 대체 그룹의 요소가 포함될 수 있습니다.

37.1.2. 구문

대체 그룹은 XML 스키마 요소 요소의 substitutionGroup 특성을 사용하여 정의됩니다. substitutionGroup 특성의 값은 정의 중인 요소가 대체되는 요소의 이름입니다. 예를 들어 head 요소가 위젯 인 경우, tree Widget 이라는 요소에 substitutionGroup="widget"을 추가하면 위젯 요소가 사용되는 모든 위치에서 이 요소를 대체할 수 있습니다. 이는 예 37.1. “하위 그룹 사용” 에 표시됩니다.

예 37.1. 하위 그룹 사용

<element name="widget" type="xsd:string" />
<element name="woodWidget" type="xsd:string"
         substitutionGroup="widget" />
Copy to Clipboard Toggle word wrap

37.1.3. 유형 제한 사항

대체 그룹의 요소는 head 요소와 동일한 유형 또는 헤드 요소의 유형에서 파생되어야 합니다. 예를 들어 head 요소가 xsd:int 유형의 경우 대체 그룹의 모든 멤버가 xsd:int 또는 xsd:int에서 파생된 유형이어야 합니다. 대체 그룹의 요소는 헤드 요소의 유형에서 파생되는 유형인 예 37.2. “복잡한 유형이 있는 대체 그룹” 에 표시된 대체 그룹을 정의할 수도 있습니다.

예 37.2. 복잡한 유형이 있는 대체 그룹

<complexType name="widgetType">
  <sequence>
    <element name="shape" type="xsd:string" />
    <element name="color" type="xsd:string" />
  </sequence>
</complexType>
<complexType name="woodWidgetType">
  <complexContent>
    <extension base="widgetType">
      <sequence>
        <element name="woodType" type="xsd:string" />
      </sequence>
    </extension>
  </complexContent>
</complexType>
<complexType name="plasticWidgetType">
  <complexContent>
    <extension base="widgetType">
      <sequence>
        <element name="moldProcess" type="xsd:string" />
      </sequence>
    </extension>
  </complexContent>
</complexType>
<element name="widget" type="widgetType" />
<element name="woodWidget" type="woodWidgetType"
         substitutionGroup="widget" />
<element name="plasticWidget" type="plasticWidgetType"
         substitutionGroup="widget" />
<complexType name="partType">
  <sequence>
    <element ref="widget" />
  </sequence>
</complexType>
<element name="part" type="partType" />
Copy to Clipboard Toggle word wrap

대체 그룹인 위젯 의 head 요소는 widgetType 유형으로 정의됩니다. 대체 그룹의 각 요소는 widgetType 을 확장하여 해당 유형의 위젯을 정렬하는 데 고유한 데이터를 포함합니다.

예 37.2. “복잡한 유형이 있는 대체 그룹” 의 스키마에 따라 예 37.3. “하위 그룹을 사용하는 XML 문서”파트 요소가 유효합니다.

예 37.3. 하위 그룹을 사용하는 XML 문서

<part>
  <widget>
    <shape>round</shape>
    <color>blue</color>
  </widget>
</part>
<part>
  <plasticWidget>
    <shape>round</shape>
    <color>blue</color>
    <moldProcess>sandCast</moldProcess>
  </plasticWidget>
</part>
<part>
  <woodWidget>
    <shape>round</shape>
    <color>blue</color>
    <woodType>elm</woodType>
  </woodWidget>
</part>
Copy to Clipboard Toggle word wrap

37.1.4. 추상 헤드 요소

스키마를 사용하여 생성된 문서에 표시되지 않는 추상 헤드 요소를 정의할 수 있습니다. 추상 헤드 요소는 일반 클래스의 보다 구체적인 구현을 정의하는 기반으로 사용되므로 Java의 추상 클래스와 유사합니다. 추상 헤드는 최종 제품의 일반 요소 사용을 방지합니다.

예 37.4. “추상 헤드 정의” 와 같이 요소 요소의 abstract 특성을 true 로 설정하여 추상 헤드 요소를 선언합니다. 이 스키마를 사용하여 유효한 검토 요소는 positiveComment 요소 또는 negativeComment 요소를 포함할 수 있지만 주석 요소를 포함할 수 없습니다.

예 37.4. 추상 헤드 정의

<element name="comment" type="xsd:string" abstract="true" />
<element name="positiveComment" type="xsd:string"
         substitutionGroup="comment" />
<element name="negtiveComment" type="xsd:string"
         substitutionGroup="comment" />
<element name="review">
  <complexContent>
    <all>
      <element name="custName" type="xsd:string" />
      <element name="impression" ref="comment" />
    </all>
  </complexContent>
</element>
Copy to Clipboard Toggle word wrap

37.2. Java의 대체 그룹

37.2.1. 개요

Apache CXF는 CryostatB 사양에 지정된 대로 와일드카드 정의에 대한 support for wildcard 정의 기능과 함께 Java의 네이티브 클래스 계층 구조를 사용하는 대체 그룹을 지원합니다. 대체 그룹의 멤버는 모두 공통 기본 유형을 공유해야 하므로 요소의 유형을 지원하기 위해 생성된 클래스는 공통 기본 유형도 공유합니다. 또한 Apache CXF는 head 요소의 인스턴스를 Cryostat B Cryostat<?에 매핑합니다.<?는 T> 속성을 확장합니다.

37.2.2. 생성된 오브젝트 팩토리 방법

대체 그룹이 포함된 패키지를 지원하기 위해 생성된 오브젝트 팩토리에는 대체 그룹의 각 요소에 대한 메서드가 있습니다. 헤드 요소를 제외하고 대체 그룹의 각 멤버에 대해 표 37.1. “Dec declarationing a CryostatB Element의 속성은 Sub Group의 멤버입니다.” 에 설명된 대로 오브젝트 팩토리 메서드를 데코팅하는 @ Cryostat CryostatDecl 주석에는 두 가지 추가 속성이 포함되어 있습니다.

Expand
표 37.1. Dec declarationing a CryostatB Element의 속성은 Sub Group의 멤버입니다.
속성설명

substitutionHeadNamespace

head 요소가 정의된 네임스페이스를 지정합니다.

substitutionHeadName

head 요소의 name 속성 값을 지정합니다.

대체 그룹의 @#159 CryostatDecl 의 head 요소에 대한 개체 팩토리 메서드에는 기본 namespace 속성과 기본 name 속성만 포함됩니다.

요소 인스턴스화 방법 외에도 개체 팩토리에는 헤드 요소를 나타내는 개체를 인스턴스화하는 방법이 포함되어 있습니다.In addition to the element instantiation methods, the object factory contains a method for instantiating an object representing the head element. 대체 그룹의 멤버가 모두 복잡한 유형인 경우 오브젝트 팩토리에는 사용된 각 복잡한 유형의 인스턴스를 인스턴스화하는 방법도 포함됩니다.

예 37.5. “하위 그룹에 대한 Object Cryostat 방법” 예 37.2. “복잡한 유형이 있는 대체 그룹” 에 정의된 대체 그룹에 대한 오브젝트 팩토리 메서드를 표시합니다.

예 37.5. 하위 그룹에 대한 Object Cryostat 방법

public class ObjectFactory {

    private final static QName _Widget_QNAME = new QName(...);
    private final static QName _PlasticWidget_QNAME = new QName(...);
    private final static QName _WoodWidget_QNAME = new QName(...);

    public ObjectFactory() {
    }

    public WidgetType createWidgetType() {
        return new WidgetType();
    }

    public PlasticWidgetType createPlasticWidgetType() {
        return new PlasticWidgetType();
    }

    public WoodWidgetType createWoodWidgetType() {
        return new WoodWidgetType();
    }

    @XmlElementDecl(namespace="...", name = "widget")
    public JAXBElement<WidgetType> createWidget(WidgetType value) {
        return new JAXBElement<WidgetType>(_Widget_QNAME, WidgetType.class, null, value);
    }

    @XmlElementDecl(namespace = "...", name = "plasticWidget", substitutionHeadNamespace = "...", substitutionHeadName = "widget")
    public JAXBElement<PlasticWidgetType> createPlasticWidget(PlasticWidgetType value) {
        return new JAXBElement<PlasticWidgetType>(_PlasticWidget_QNAME, PlasticWidgetType.class, null, value);
    }

    @XmlElementDecl(namespace = "...", name = "woodWidget", substitutionHeadNamespace = "...", substitutionHeadName = "widget")
    public JAXBElement<WoodWidgetType> createWoodWidget(WoodWidgetType value) {
        return new JAXBElement<WoodWidgetType>(_WoodWidget_QNAME, WoodWidgetType.class, null, value);
    }

}
Copy to Clipboard Toggle word wrap

37.2.3. 인터페이스의 대체 그룹

대체 그룹의 head 요소가 작업 메시지 중 하나에서 메시지 부분으로 사용되는 경우 결과 메서드 매개변수는 해당 요소를 지원하기 위해 생성된 클래스의 개체가 됩니다. 반드시 T> 클래스를 확장합니다. 런타임은 Java의 네이티브 유형 계층 구조를 사용하여 유형 대체를 지원하며 Java는 지원되지 않는 유형을 사용하려고 하는 모든 시도를 catch합니다.

런타임에서 요소 대체를 지원하는 데 필요한 모든 클래스를 인식하도록 SEI는 @ CryostatSeeAlso 주석으로 데코레이팅됩니다. 이 주석은 런타임에서 마샬링에 필요한 클래스 목록을 지정합니다. @ CryostatSeeAlso 주석 사용에 대한 자세한 내용은 32.4절. “런타임 Marshaller에 클래스 추가” 을 참조하십시오.

예 37.7. “하위 그룹을 사용하여 생성된 인터페이스” 예 37.6. “하위 그룹을 사용하는 WSDL 인터페이스” 에 표시된 인터페이스에 대해 생성된 SEI를 표시합니다. 인터페이스에서는 예 37.2. “복잡한 유형이 있는 대체 그룹” 에 정의된 대체 그룹을 사용합니다.

예 37.6. 하위 그룹을 사용하는 WSDL 인터페이스

<message name="widgetMessage">
    <part name="widgetPart" element="xsd1:widget" />
  </message>
  <message name="numWidgets">
    <part name="numInventory" type="xsd:int" />
  </message>
  <message name="badSize">
    <part name="numInventory" type="xsd:int" />
  </message>
  <portType name="orderWidgets">
    <operation name="placeWidgetOrder">
      <input message="tns:widgetOrder" name="order" />
      <output message="tns:widgetOrderBill" name="bill" />
      <fault message="tns:badSize" name="sizeFault" />
    </operation>
    <operation name="checkWidgets">
      <input message="tns:widgetMessage" name="request" />
      <output message="tns:numWidgets" name="response" />
    </operation>
  </portType>
Copy to Clipboard Toggle word wrap

예 37.7. 하위 그룹을 사용하여 생성된 인터페이스

@WebService(targetNamespace = "...", name = "orderWidgets")
@XmlSeeAlso({com.widgetvendor.types.widgettypes.ObjectFactory.class})
public interface OrderWidgets {

    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @WebResult(name = "numInventory", targetNamespace = "", partName = "numInventory")
    @WebMethod
    public int checkWidgets(
        @WebParam(partName = "widgetPart", name = "widget", targetNamespace = "...")
        com.widgetvendor.types.widgettypes.WidgetType widgetPart
    );
}
Copy to Clipboard Toggle word wrap

예 37.7. “하위 그룹을 사용하여 생성된 인터페이스” 에 표시된 SEI는 @ CryostatSeeAlso 주석에 오브젝트 팩토리를 나열합니다. 네임스페이스의 오브젝트 팩토리를 나열하면 해당 네임스페이스에 대해 생성된 모든 클래스에 액세스할 수 있습니다.

37.2.4. 복잡한 유형의 대체 그룹

대체 그룹의 head 요소가 복잡한 유형의 요소로 사용되는 경우 코드 생성기는 요소를 T> 속성에 매핑합니다. 대체 그룹을 지원하기 위해 생성된 클래스의 인스턴스가 포함된 속성에 매핑되지 않습니다.

예를 들어 예 37.8. “하위 그룹을 사용하는 복잡한 유형” 에 정의된 복잡한 유형은 예 37.9. “하위 그룹을 사용하여 복잡한 유형의 Java 클래스” 에 표시된 Java 클래스를 생성합니다. 복잡한 유형은 예 37.2. “복잡한 유형이 있는 대체 그룹” 에 정의된 대체 그룹을 사용합니다.

예 37.8. 하위 그룹을 사용하는 복잡한 유형

<complexType name="widgetOrderInfo">
  <sequence>
    <element name="amount" type="xsd:int"/>
    <element ref="xsd1:widget"/>
  </sequence>
</complexType>
Copy to Clipboard Toggle word wrap

예 37.9. 하위 그룹을 사용하여 복잡한 유형의 Java 클래스

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "widgetOrderInfo", propOrder = {"amount","widget",})
public class WidgetOrderInfo {

    protected int amount;
    @XmlElementRef(name = "widget", namespace = "...", type = JAXBElement.class) protected JAXBElement<? extends WidgetType> widget;
    public int getAmount() {
        return amount;
    }

    public void setAmount(int value) {
        this.amount = value;
    }

    public JAXBElement<? extends WidgetType> getWidget() { return widget; }

    public void setWidget(JAXBElement<? extends WidgetType> value) { this.widget = ((JAXBElement<? extends WidgetType> ) value); }

}
Copy to Clipboard Toggle word wrap

37.2.5. 대체 그룹 속성 설정

대체 그룹으로 작업하는 방법은 코드 생성기가 그룹을 직접 Java 클래스에 매핑했는지 아니면 T> 클래스를 확장했는지 에 따라 달라집니다. 요소가 생성된 값 클래스의 개체에 간단히 매핑되면 유형 계층 구조의 일부인 다른 Java 개체로 작업하는 것과 동일한 방식으로 개체로 작업합니다. 상위 클래스의 하위 클래스를 대체할 수 있습니다. 오브젝트를 검사하여 정확한 클래스를 확인하고 적절하게 캐스팅할 수 있습니다.

CryostatB 사양은 오브젝트 팩토리 메서드를 사용하여 생성된 클래스의 개체를 인스턴스화하는 것이 좋습니다.

코드 생성기가 T> 오브젝트를 확장하여 대체 그룹의 인스턴스를 유지하기 위해 확장하면 element의 값을 Cryostat B Cryostat<? extends T > 오브젝트로 래핑해야 합니다. 이를 수행하는 가장 좋은 방법은 오브젝트 팩토리에서 제공하는 요소 생성 방법을 사용하는 것입니다. 해당 값을 기반으로 요소를 만들 수 있는 간단한 수단을 제공합니다.

예 37.10. “하위 그룹의 멤버 설정” 대체 그룹 인스턴스를 설정하는 코드를 표시합니다.

예 37.10. 하위 그룹의 멤버 설정

ObjectFactory of = new ObjectFactory();
PlasticWidgetType pWidget = of.createPlasticWidgetType();
pWidget.setShape = "round';
pWidget.setColor = "green";
pWidget.setMoldProcess = "injection";

JAXBElement<PlasticWidgetType> widget = of.createPlasticWidget(pWidget);

WidgetOrderInfo order = of.createWidgetOrderInfo();
order.setWidget(widget);
Copy to Clipboard Toggle word wrap

예 37.10. “하위 그룹의 멤버 설정” 의 코드는 다음을 수행합니다.

오브젝트 팩토리를 인스턴스화합니다.

ScanSetting WidgetType 오브젝트 를 인스턴스화합니다.

opm B Cryostat<PlasticWidgetType > 오브젝트를 인스턴스화하여 가발성 위젯 요소를 유지합니다.

개체를 인스턴스화합니다.

Cryostat OrderInfo 오브젝트의 위젯을 목형 위젯 요소를 보유하고 있는 CryostatB Cryostat 오브젝트로 설정합니다.

37.2.6. 대체 그룹 속성의 값 가져오기

개체 팩토리 메서드는 T> 개체에서 요소의 값을 추출할 때 도움이 되지 않습니다. Cryostat B Cryostat<?는 T> 오브젝트의 getValue() 메서드를 확장합니다. 다음 옵션은 getValue() 메서드에서 반환하는 오브젝트 유형을 결정합니다.

  • 가능한 모든 클래스의 isInstance() 메서드를 사용하여 요소의 value 개체의 클래스를 확인합니다.
  • Cryostat B Cryostat<? extends T > object's getName() 메서드를 사용하여 요소의 이름을 확인합니다.

    getName() 메서드는 QName을 반환합니다. 요소의 로컬 이름을 사용하여 value 오브젝트에 대한 적절한 클래스를 확인할 수 있습니다.

  • Cryostat B Cryostat<? extends T > object's getDec declarationedType() 메서드를 사용하여 value 오브젝트의 클래스를 확인합니다.

    getDec declarationedType() 메서드는 요소의 value 개체의 Class 개체를 반환합니다.

    주의

    getDec declarationedType() 메서드는 value 개체의 실제 클래스에 관계없이 head 요소에 대한 기본 클래스를 반환할 가능성이 있습니다.

예 37.11. “하위 그룹의 멤버의 가치 얻기” 대체 그룹에서 값을 검색하는 코드를 표시합니다. 요소의 value 개체의 적절한 클래스를 확인하기 위해 예제에서는 요소의 getName() 메서드를 사용합니다.

예 37.11. 하위 그룹의 멤버의 가치 얻기

String elementName = order.getWidget().getName().getLocalPart();
if (elementName.equals("woodWidget")
{
  WoodWidgetType widget=order.getWidget().getValue();
}
else if (elementName.equals("plasticWidget")
{
  PlasticWidgetType widget=order.getWidget().getValue();
}
else
{
  WidgetType widget=order.getWidget().getValue();
}
Copy to Clipboard Toggle word wrap

37.3. 위젯 벤더 예

37.3.1. 위젯 순서 지정 인터페이스

이 섹션에서는 Apache CXF에서 실제 애플리케이션을 해결하기 위해 사용되는 대체 그룹의 예를 보여줍니다. 서비스 및 소비자는 예 37.2. “복잡한 유형이 있는 대체 그룹” 에 정의된 위젯 대체 그룹을 사용하여 개발됩니다. 서비스는 checkWidgetsplaceWidgetOrder 의 두 가지 작업을 제공합니다. 예 37.12. “위젯 순서 지정 인터페이스” 주문 서비스의 인터페이스를 표시합니다.

예 37.12. 위젯 순서 지정 인터페이스

<message name="widgetOrder">
  <part name="widgetOrderForm" type="xsd1:widgetOrderInfo"/>
</message>
<message name="widgetOrderBill">
  <part name="widgetOrderConformation"
        type="xsd1:widgetOrderBillInfo"/>
</message>
<message name="widgetMessage">
  <part name="widgetPart" element="xsd1:widget" />
</message>
<message name="numWidgets">
  <part name="numInventory" type="xsd:int" />
</message>
<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
  </operation>
  <operation name="checkWidgets">
    <input message="tns:widgetMessage" name="request" />
    <output message="tns:numWidgets" name="response" />
  </operation>
</portType>
Copy to Clipboard Toggle word wrap

예 37.13. “위젯 순서 SEI” 인터페이스에 대해 생성된 Java SEI를 표시합니다.

예 37.13. 위젯 순서 SEI

@WebService(targetNamespace = "http://widgetVendor.com/widgetOrderForm", name = "orderWidgets")
@XmlSeeAlso({com.widgetvendor.types.widgettypes.ObjectFactory.class})
public interface OrderWidgets {

    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @WebResult(name = "numInventory", targetNamespace = "", partName = "numInventory")
    @WebMethod
    public int checkWidgets(
        @WebParam(partName = "widgetPart", name = "widget", targetNamespace = "http://widgetVendor.com/types/widgetTypes")
        com.widgetvendor.types.widgettypes.WidgetType widgetPart
    );

    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    @WebResult(name = "widgetOrderConformation", targetNamespace = "", partName = "widgetOrderConformation")
    @WebMethod
    public com.widgetvendor.types.widgettypes.WidgetOrderBillInfo placeWidgetOrder(
        @WebParam(partName = "widgetOrderForm", name = "widgetOrderForm", targetNamespace = "")
        com.widgetvendor.types.widgettypes.WidgetOrderInfo widgetOrderForm
    ) throws BadSize;
}
Copy to Clipboard Toggle word wrap
참고

이 예제에서는 대체 그룹만 사용하기 때문에 일부 비즈니스 논리는 표시되지 않습니다.

37.3.2. checkWidgets 작업

37.3.2.1. 개요

checkWidgets 는 대체 그룹의 헤드 멤버인 매개변수가 있는 간단한 작업입니다. 이 작업은 대체 그룹의 멤버인 개별 매개변수를 처리하는 방법을 보여줍니다. 소비자는 매개변수가 대체 그룹의 유효한 멤버인지 확인해야 합니다. 서비스는 요청에 대체 그룹의 멤버를 올바르게 결정해야 합니다.

37.3.2.2. 소비자 구현

생성된 메서드 서명은 대체 그룹의 헤드 요소를 지원하는 Java 클래스를 사용합니다. 대체 그룹의 멤버 요소는 헤드 요소 또는 헤드 요소의 유형에서 파생된 형식의 동일한 유형 중 하나이므로, 헤드 요소를 지원하기 위해 생성된 Java 클래스의 멤버를 지원하도록 생성된 Java 클래스가 생성됩니다. Java의 유형 계층 구조는 부모 클래스 대신 하위 클래스 사용을 기본적으로 지원합니다.

Apache CXF가 대체 그룹 및 Java 유형 계층 구조에 대한 유형을 생성하는 방법 때문에 클라이언트는 특수 코드를 사용하지 않고 checkWidgets() 를 호출할 수 있습니다. checkWidgets() 를 호출하는 논리를 개발할 때 위젯 대체 그룹을 지원하기 위해 생성된 클래스 중 하나의 개체를 전달할 수 있습니다.

예 37.14. “소비자 Invoking checkWidgets() checkWidgets() 를 호출하는 소비자를 표시합니다.

예 37.14. 소비자 Invoking checkWidgets()

System.out.println("What type of widgets do you want to order?");
System.out.println("1 - Normal");
System.out.println("2 - Wood");
System.out.println("3 - Plastic");
System.out.println("Selection [1-3]");
String selection = reader.readLine();
String trimmed = selection.trim();
char widgetType = trimmed.charAt(0);
switch (widgetType)
{
  case '1':
  {
    WidgetType widget = new WidgetType();
    ...
    break;
  }
  case '2':
  {
    WoodWidgetType widget = new WoodWidgetType();
    ...
    break;
  }
  case '3':
  {
    PlasticWidgetType widget = new PlasticWidgetType();
    ...
    break;
  }
  default :
    System.out.println("Invaid Widget Selection!!");
}

proxy.checkWidgets(widgets);
Copy to Clipboard Toggle word wrap
37.3.2.3. 서비스 구현

서비스의 checkWidgets() 구현에서는 위젯 설명을 array Type 오브젝트로 가져오고, 위젯 의 인벤토리를 확인하고, 주식에 있는 위젯 수를 반환합니다. 동일한 기본 클래스에서 대체 그룹 상속을 구현하는 데 사용되는 모든 클래스를 사용하므로 특정 API를 사용하지 않고 checkWidgets() 를 구현할 수 있습니다.

위젯에 대한 대체 그룹의 멤버를 지원하기 위해 생성된 모든 클래스는 widget Type 클래스를 확장합니다. 이 사실 때문에 instanceof 를 사용하여 전달된 위젯 유형을 결정하고 적절한 경우 widgetPart 오브젝트를 보다 제한적인 유형으로 캐스팅할 수 있습니다. 적절한 유형의 오브젝트가 있으면 올바른 종류의 위젯의 인벤토리를 확인할 수 있습니다.

예 37.15. “checkWidgets()의 서비스 구현” 가능한 구현을 보여줍니다.

예 37.15. checkWidgets()의 서비스 구현

public int checkWidgets(WidgetType widgetPart)
{
  if (widgetPart instanceof WidgetType)
  {
    return checkWidgetInventory(widgetType);
  }
  else if (widgetPart instanceof WoodWidgetType)
  {
    WoodWidgetType widget = (WoodWidgetType)widgetPart;
    return checkWoodWidgetInventory(widget);
  }
  else if (widgetPart instanceof PlasticWidgetType)
  {
    PlasticWidgetType widget = (PlasticWidgetType)widgetPart;
    return checkPlasticWidgetInventory(widget);
  }
}
Copy to Clipboard Toggle word wrap

37.3.3. placeWidgetOrder 작업

37.3.3.1. 개요

placeWidgetOrder 는 대체 그룹을 포함하는 두 가지 복잡한 유형을 사용합니다. 이 작업은 Java 구현에서 이러한 구조를 사용하는 방법을 보여줍니다. 소비자와 서비스 모두 대체 그룹의 멤버를 가져오고 설정해야 합니다.

37.3.3.2. 소비자 구현

placeWidgetOrder() 를 호출하려면 소비자가 위젯 대체 그룹의 한 요소를 포함하는 위젯 순서를 구성해야 합니다. 주문에 위젯을 추가할 때 소비자는 대체 그룹의 각 요소에 대해 생성된 오브젝트 팩토리 메서드를 사용해야 합니다. 이렇게 하면 런타임 및 서비스에서 순서를 올바르게 처리할 수 있습니다. 예를 들어, 대체 위젯에 대해 주문이 배치되는 경우 ObjectFactory.createPlasticWidget() 방법은 주문에 추가하기 전에 요소를 만드는 데 사용됩니다.

예 37.16. “하위 그룹 멤버 설정” shows consumer code for setting the widget property of the Cryo statOrderInfo 개체입니다.

예 37.16. 하위 그룹 멤버 설정

ObjectFactory of = new ObjectFactory();

WidgetOrderInfo order = new of.createWidgetOrderInfo();
...
System.out.println();
System.out.println("What color widgets do you want to order?");
String color = reader.readLine();
System.out.println();
System.out.println("What shape widgets do you want to order?");
String shape = reader.readLine();
System.out.println();
System.out.println("What type of widgets do you want to order?");
System.out.println("1 - Normal");
System.out.println("2 - Wood");
System.out.println("3 - Plastic");
System.out.println("Selection [1-3]");
String selection = reader.readLine();
String trimmed = selection.trim();
char widgetType = trimmed.charAt(0);
switch (widgetType)
{
  case '1':
  {
    WidgetType widget = of.createWidgetType();
    widget.setColor(color);
    widget.setShape(shape);
    JAXB<WidgetType> widgetElement = of.createWidget(widget); order.setWidget(widgetElement);
    break;
  }
  case '2':
  {
    WoodWidgetType woodWidget = of.createWoodWidgetType();
    woodWidget.setColor(color);
    woodWidget.setShape(shape);
    System.out.println();
    System.out.println("What type of wood are your widgets?");
    String wood = reader.readLine();
    woodWidget.setWoodType(wood);
    JAXB<WoodWidgetType> widgetElement = of.createWoodWidget(woodWidget); order.setWoodWidget(widgetElement);
    break;
  }
  case '3':
  {
    PlasticWidgetType plasticWidget = of.createPlasticWidgetType();
    plasticWidget.setColor(color);
    plasticWidget.setShape(shape);
    System.out.println();
    System.out.println("What type of mold to use for your
                        widgets?");
    String mold = reader.readLine();
    plasticWidget.setMoldProcess(mold);
    JAXB<WidgetType> widgetElement = of.createPlasticWidget(plasticWidget); order.setPlasticWidget(widgetElement);
    break;
  }
  default :
    System.out.println("Invaid Widget Selection!!");
    }
Copy to Clipboard Toggle word wrap
37.3.3.3. 서비스 구현

placeWidgetOrder() 메서드는 order를 처리하고, order를 처리하며, Consumer OrderBillInfo 개체의 형태로 소비자에게 청구를 반환합니다. 주문은 일반 위젯, 성형 위젯 또는 가사 위젯 일 수 있습니다. 정렬된 위젯 유형은 widgetOrderForm 오브젝트의 위젯 속성에 저장된 오브젝트 유형에 따라 결정됩니다. 위젯 속성은 대체 그룹이며 위젯 요소를 포함할 수 있습니다.

구현에서는 가능한 요소 중 순서에 저장할 수 있는 요소를 결정해야 합니다. 이 작업은 Cryostat B Cryostat<?를 사용하여 T> 오브젝트의 getName() 메서드를 확장하여 요소의 QName을 결정합니다. 그런 다음 QName을 사용하여 대체 그룹의 요소를 순서대로 확인할 수 있습니다. 청구에 포함된 요소를 알고 있으면 해당 값을 적절한 유형의 오브젝트로 추출할 수 있습니다.

예 37.17. “placeWidgetOrder()구현” 가능한 구현을 보여줍니다.

예 37.17. placeWidgetOrder()구현

public com.widgetvendor.types.widgettypes.WidgetOrderBillInfo placeWidgetOrder(WidgetOrderInfo widgetOrderForm)
{
  ObjectFactory of = new ObjectFactory();

  WidgetOrderBillInfo bill = new WidgetOrderBillInfo()

   // Copy the shipping address and the number of widgets
   // ordered from widgetOrderForm to bill
   ...

  int numOrdered = widgetOrderForm.getAmount();

  String elementName = widgetOrderForm.getWidget().getName().getLocalPart();
  if (elementName.equals("woodWidget")
  {
    WoodWidgetType widget=order.getWidget().getValue();
    buildWoodWidget(widget, numOrdered);

    // Add the widget info to bill
    JAXBElement<WoodWidgetType> widgetElement = of.createWoodWidget(widget);
    bill.setWidget(widgetElement);

    float amtDue = numOrdered * 0.75;
    bill.setAmountDue(amtDue);
  }
  else if (elementName.equals("plasticWidget")
  {
    PlasticWidgetType widget=order.getWidget().getValue();
    buildPlasticWidget(widget, numOrdered);

    // Add the widget info to bill
    JAXBElement<PlasticWidgetType> widgetElement = of.createPlasticWidget(widget);
    bill.setWidget(widgetElement);

    float amtDue = numOrdered * 0.90;
    bill.setAmountDue(amtDue);
  }
  else
  {
    WidgetType widget=order.getWidget().getValue();
    buildWidget(widget, numOrdered);

    // Add the widget info to bill
    JAXBElement<WidgetType> widgetElement = of.createWidget(widget);
    bill.setWidget(widgetElement);

    float amtDue = numOrdered * 0.30;
    bill.setAmountDue(amtDue);
  }

  return(bill);
}
Copy to Clipboard Toggle word wrap

예 37.17. “placeWidgetOrder()구현” 의 코드는 다음을 수행합니다.

개체 팩토리를 인스턴스화하여 요소를 생성합니다.

청구를 유지할 수 있도록OrderBillInfo 개체를 인스턴스화합니다.

정렬된 위젯의 수를 가져옵니다.

순서에 저장된 요소의 로컬 이름을 가져옵니다.

요소가 다크 Widget 요소인지 확인합니다.

순서에서 적절한 유형의 오브젝트로 요소의 값을 추출합니다.

bill에 배치된 Cryo statB Cryostat<T > 오브젝트를 만듭니다.

bill 오브젝트의 위젯 속성을 설정합니다.

bill 오브젝트의 amountDue 속성을 설정합니다.

38장. 유형 생성 방법 사용자 정의

초록

기본 CryostatB 매핑은 XML 스키마를 사용하여 Java 애플리케이션의 개체를 정의할 때 발생하는 대부분의 사례를 해결합니다. 기본 매핑이 충분하지 않은 인스턴스의 경우 CryostatB는 광범위한 사용자 지정 메커니즘을 제공합니다.

38.1. 유형 매핑 사용자 정의의 기본 사항

38.1.1. 개요

CryostatB 사양은 Java 유형이 XML 스키마 구성에 매핑되는 방법을 사용자 지정하는 여러 XML 요소를 정의합니다. 이러한 요소는 XML 스키마 구문을 사용하여 인라인으로 지정할 수 있습니다. XML 스키마 정의를 수정할 수 없거나 수정하지 않으려면 외부 바인딩 문서에서 사용자 지정을 지정할 수 있습니다.

38.1.2. 네임스페이스

CryostatB 데이터 바인딩을 사용자 지정하는 데 사용되는 요소는 http://java.sun.com/xml/ns/jaxb 네임스페이스에 정의됩니다. 예 38.1. “CryostatB 사용자 지정 네임스페이스” 에 표시된 것과 유사한 네임스페이스 선언을 추가해야 합니다. 이는 CryostatB 사용자 지정을 정의하는 모든 XML 문서의 루트 요소에 추가됩니다.

예 38.1. CryostatB 사용자 지정 네임스페이스

xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
Copy to Clipboard Toggle word wrap

38.1.3. 버전 선언

CryostatB 사용자 지정을 사용하는 경우 사용 중인 CryostatB 버전을 지정해야 합니다. 이 작업은 외부 바인딩 선언의 root 요소에 jaxb:version 속성을 추가하여 수행됩니다. 인라인 사용자 지정을 사용하는 경우 사용자 지정을 포함하는 스키마 요소에 jaxb:version 속성을 포함해야 합니다. 속성 값은 항상 2.0 입니다.

예 38.2. “CryostatB 사용자 지정 버전 지정” 스키마 요소에 사용되는 jaxb:version 속성의 예를 보여줍니다.

예 38.2. CryostatB 사용자 지정 버전 지정

< schema ...
        jaxb:version="2.0">
Copy to Clipboard Toggle word wrap

38.1.4. 인라인 사용자 정의 사용

코드 생성기가 XML 스키마를 구성하는 방법을 사용자 지정하는 가장 직접적인 방법은 사용자 지정 요소를 XML 스키마 정의에 직접 추가하는 것입니다. CryostatB 사용자 지정 요소는 수정되는 XML 스키마 구문의 xsd:appinfo 요소 내에 배치됩니다.

예 38.3. “사용자 지정 XML 스키마” 다음 예에서는 인라인 CryostatB 사용자 지정을 포함하는 스키마의 예를 보여줍니다.

예 38.3. 사용자 지정 XML 스키마

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <complexType name="size">
    <annotation> <appinfo> <jaxb:class name="widgetSize" /> </appinfo> </annotation>
    <sequence>
      <element name="longSize" type="xsd:string" />
      <element name="numberSize" type="xsd:int" />
    </sequence>
  </complexType>
<schema>
Copy to Clipboard Toggle word wrap

38.1.5. 외부 바인딩 선언 사용

형식을 정의하는 XML 스키마 문서를 변경할 수 없거나 변경하지 않는 경우 외부 바인딩 선언을 사용하여 사용자 지정을 지정할 수 있습니다. 외부 바인딩 선언은 여러 중첩된 jaxb:bindings 요소로 구성됩니다. 예 38.4. “CryostatB 외부 바인딩 선언 구문” 외부 바인딩 선언의 구문을 표시합니다.

예 38.4. CryostatB 외부 바인딩 선언 구문

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings [schemaLocation="schemaUri" | wsdlLocation="wsdlUri">
    <jaxb:bindings node="nodeXPath">
      binding declaration
    </jaxb:bindings>
    ...
  </jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap

schemaLocation 속성 및 wsdlLocation 속성은 수정이 적용되는 스키마 문서를 식별하는 데 사용됩니다. 스키마 문서에서 코드를 생성하는 경우 schemaLocation 특성을 사용합니다. WSDL 문서에서 코드를 생성하는 경우 wsdlLocation 속성을 사용합니다.

노드 속성은 수정할 특정 XML 스키마 구성을 식별하는 데 사용됩니다. 이는 XML 스키마 요소로 확인되는 Cryostat 문입니다.

예 38.5. “XML 스키마 파일” 에 표시된 스키마 문서 위젯Schema.xsd 를 고려할 때 예 38.6. “외부 바인딩 선언” 에 표시된 외부 바인딩 선언은 복잡한 유형 크기의 생성을 수정합니다.

예 38.5. XML 스키마 파일

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        version="1.0">
  <complexType name="size">
    <sequence>
      <element name="longSize" type="xsd:string" />
      <element name="numberSize" type="xsd:int" />
    </sequence>
  </complexType>
<schema>
Copy to Clipboard Toggle word wrap

예 38.6. 외부 바인딩 선언

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="wsdlSchema.xsd">
    <jaxb:bindings node="xsd:complexType[@name='size']">
        <jaxb:class name="widgetSize" />
    </jaxb:bindings>
  </jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap

코드 생성기가 외부 연결 선언을 사용하도록 지시하려면 다음과 같이 wsdl2java 도구의 -b 바인딩 파일 옵션을 사용합니다.

wsdl2java -b widgetBinding.xml widget.wsdl
Copy to Clipboard Toggle word wrap

38.2. XML 스키마의 Java 클래스 지정

38.2.1. 개요

기본적으로 XML 스키마 유형은 Java 기본 유형에 매핑됩니다. XML 스키마와 Java 간의 가장 논리적인 매핑이지만 애플리케이션 개발자의 요구 사항을 항상 충족하는 것은 아닙니다. XML 스키마 기본 유형을 추가 정보를 저장할 수 있는 Java 클래스에 매핑하거나 XML 기본 유형을 간단한 형식 대체를 허용하는 클래스에 매핑해야 할 수 있습니다.

CryostatB javaType 사용자 지정 요소를 사용하면 XML 스키마 기본 유형과 Java 기본 유형 간의 매핑을 사용자 지정할 수 있습니다. 글로벌 수준 및 개별 인스턴스 수준에서 매핑을 사용자 지정하는 데 사용할 수 있습니다. javaType 요소를 간단한 형식 정의의 일부로 사용하거나 복잡한 형식 정의의 일부로 사용할 수 있습니다.

javaType 사용자 지정 요소를 사용하는 경우 기본 유형의 XML 표현을 대상 Java 클래스로 변환하기 위한 메서드를 지정해야 합니다. 일부 매핑에는 기본 변환 방법이 있습니다. 기본 매핑이 없는 인스턴스의 경우 Apache CXF는 CryostatB 메서드를 제공하여 필요한 메서드를 쉽게 개발할 수 있습니다.

38.2.2. 구문

javaType 사용자 지정 요소는 표 38.1. “XML 스키마 유형에 대한 Java 클래스 생성 사용자 지정을 위한 속성” 에 설명된 대로 4개의 속성을 사용합니다.

Expand
표 38.1. XML 스키마 유형에 대한 Java 클래스 생성 사용자 지정을 위한 속성
속성필수 항목설명

name

제공됨

XML Schema 기본 유형이 매핑되는 Java 클래스의 이름을 지정합니다. 유효한 Java 클래스 이름 또는 Java 기본 유형의 이름이어야 합니다. 이 클래스가 존재하고 애플리케이션에서 액세스할 수 있는지 확인해야 합니다. 코드 생성기는 이 클래스를 확인하지 않습니다.

xmlType

없음

사용자 지정되는 XML Schema 기본 유형을 지정합니다. 이 속성은 javaType 요소가 globalBindings 요소의 자식으로 사용되는 경우에만 사용됩니다.

parseMethod

없음

데이터의 문자열 기반 XML 표현을 Java 클래스의 인스턴스로 구문 분석하는 방법을 지정합니다. 자세한 내용은 “변환기 지정” 에서 참조하십시오.

printMethod

없음

Java 개체를 데이터의 문자열 기반 XML 표현으로 변환하는 방법을 지정합니다. 자세한 내용은 “변환기 지정” 에서 참조하십시오.

javaType 사용자 지정 요소는 다음 세 가지 방법으로 사용할 수 있습니다.

  • XML 스키마 기본 유형의 모든 인스턴스를 수정하려면 javaType 요소는 globalBindings 사용자 지정 요소의 자식으로 사용할 때 스키마 문서의 XML Schema 유형의 모든 인스턴스를 수정합니다. 이러한 방식으로 사용될 때는 수정되는 XML 스키마 기본 형식을 식별하는 xmlType 속성 값을 지정해야 합니다.

    예 38.7. “글로벌 우선순위 유형 사용자 정의” 는 스키마의 모든 xsd:short 인스턴스에 java.lang.Integer 를 사용하도록 코드 생성기를 지시하는 인라인 글로벌 사용자 지정을 보여줍니다.

    예 38.7. 글로벌 우선순위 유형 사용자 정의

    <schema targetNamespace="http://widget.com/types/widgetTypes"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
            jaxb:version="2.0">
      <annotation>
        <appinfo>
          <jaxb:globalBindings ...>
            <jaxb:javaType name="java.lang.Integer"
                           xmlType="xsd:short" />
          </globalBindings
        </appinfo>
      </annotation>
      ...
    </schema>
    Copy to Clipboard Toggle word wrap
  • 간단한 유형 정의를 수정하려면 javaType 요소는 명명된 단순 형식 정의에 적용할 때 XML simple 형식의 모든 인스턴스에 대해 생성된 클래스를 수정합니다. javaType 요소를 사용하여 간단한 유형 정의를 수정하는 경우 xmlType 특성을 사용하지 마십시오.

    예 38.8. “단순 유형 사용자 지정을 위한 바인딩 파일” zipCode 라는 간단한 유형의 생성을 수정하는 외부 바인딩 파일을 표시합니다.

    예 38.8. 단순 유형 사용자 지정을 위한 바인딩 파일

    <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   jaxb:version="2.0">
      <jaxb:bindings wsdlLocation="widgets.wsdl">
        <jaxb:bindings node="xsd:simpleType[@name='zipCode']">
            <jaxb:javaType name="com.widgetVendor.widgetTypes.zipCodeType"
                           parseMethod="com.widgetVendor.widgetTypes.support.parseZipCode"
                           printMethod="com.widgetVendor.widgetTypes.support.printZipCode" />
        </jaxb:bindings>
      </jaxb:bindings>
    <jaxb:bindings>
    Copy to Clipboard Toggle word wrap
  • 복잡한 유형 정의의 요소 또는 특성을 수정하기 위해 javaType 은 CryostatB 속성 사용자 지정의 일부로 포함하여 복잡한 유형 정의의 개별 부분에 적용할 수 있습니다. javaType 요소는 속성의 baseType 요소에 자식으로 배치됩니다. javaType 요소를 사용하여 복잡한 유형 정의의 특정 부분을 수정하는 경우 xmlType 특성을 사용하지 마십시오.

    예 38.9. “복잡한 유형의 요소 사용자 지정을 위한 바인딩 파일” 복합 형식의 요소를 수정하는 바인딩 파일을 표시합니다.Shows a binding file that modifies an element of a complex type.

    예 38.9. 복잡한 유형의 요소 사용자 지정을 위한 바인딩 파일

    <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   jaxb:version="2.0">
      <jaxb:bindings schemaLocation="enumMap.xsd">
        <jaxb:bindings node="xsd:ComplexType[@name='widgetOrderInfo']">
          <jaxb:bindings node="xsd:element[@name='cost']">
            <jaxb:property>
              <jaxb:baseType>
                <jaxb:javaType name="com.widgetVendor.widgetTypes.costType"
                                parseMethod="parseCost"
                                printMethod="printCost" >
              </jaxb:baseType>
            </jaxb:property>
          </jaxb:bindings>
        </jaxb:bindings>
      </jaxb:bindings>
    <jaxb:bindings>
    Copy to Clipboard Toggle word wrap

    baseType 요소 사용에 대한 자세한 내용은 38.6절. “요소 또는 속성의 기본 유형 지정” 을 참조하십시오.

38.2.3. 변환기 지정

Apache CXF는 XML 스키마 기본 유형을 임의의 Java 클래스로 변환할 수 없습니다. javaType 요소를 사용하여 XML 스키마 기본 유형의 매핑을 사용자 지정할 때 코드 생성기는 사용자 지정된 XML 스키마 기본 유형을 마샬링하고 unmarshal하는 데 사용되는 어댑터 클래스를 만듭니다. 샘플 어댑터 클래스는 예 38.10. “CryostatB 어댑터 클래스” 에 표시됩니다.

예 38.10. CryostatB 어댑터 클래스

public class Adapter1 extends XmlAdapter<String, javaType>
{
  public javaType unmarshal(String value)
  {
    return(parseMethod(value));
  }

  public String marshal(javaType value)
  {
    return(printMethod(value));
  }
}
Copy to Clipboard Toggle word wrap

parseMethodprintMethod 는 해당 parseMethod 속성 및 printMethod 속성 값으로 교체됩니다. 값은 유효한 Java 메서드를 식별해야 합니다. 다음 두 가지 방법 중 하나로 메서드의 이름을 지정할 수 있습니다.

  • 패키지 이름 .ClassName. methodName 형식의 정규화된 Java메서드 이름
  • methodName 형식의 간단한 메서드 이름

    간단한 메서드 이름만 제공하는 경우 코드 생성기는 이 메서드가 javaType 요소의 name 특성에 지정된 클래스에 있다고 가정합니다.

중요

코드 생성기는 구문 분석 또는 인쇄 메서드를 생성하지 않습니다. 이를 제공할 책임이 있습니다. 구문 분석 및 인쇄 방법 개발에 대한 자세한 내용은 “변환기 구현” 에서 참조하십시오.

parseMethod 특성에 대한 값이 제공되지 않으면 코드 생성기는 name 특성에 지정된 Java 클래스에 첫 번째 매개 변수가 Java String 개체인 생성자가 있다고 가정합니다. 생성된 어댑터의 unmarshal() 메서드는 가정된 생성자를 사용하여 Java 개체를 XML 데이터로 채웁니다.

printMethod 속성 값을 제공하지 않으면 코드 생성기는 name 특성에 지정된 Java 클래스에 toString() 메서드가 있다고 가정합니다. 생성된 어댑터의 marshal() 메서드는 가정된 toString() 메서드를 사용하여 Java 개체를 XML 데이터로 변환합니다.

javaType 요소의 name 속성이 Java 기본 유형 또는 Java 기본의 래퍼 유형 중 하나를 지정하는 경우 코드 생성기는 기본 변환기를 사용합니다. 기본 변환기에 대한 자세한 내용은 “기본 기본 유형 변환기” 을 참조하십시오.

38.2.4. 생성된 항목

“변환기 지정” 에서 언급했듯이 javaType 사용자 지정 요소를 사용하면 XML 스키마 기본 유형의 각 사용자 지정에 대해 하나의 어댑터 클래스 생성이 트리거됩니다. 어댑터는 패턴 AdapterN 을 사용하여 순서대로 지정됩니다. 두 개의 기본 유형 사용자 지정을 지정하면 코드 생성기는 Adapter1Adapter2 의 두 가지 어댑터 클래스를 만듭니다.

XML 스키마 구성에 대해 생성된 코드는 영향을 받는 XML 스키마 구성이 전역적으로 정의된 요소인지 아니면 복잡한 유형의 일부로 정의되었는지에 따라 달라집니다.

XML 스키마 구성이 전역적으로 정의된 요소인 경우 유형에 대해 생성된 개체 팩토리 메서드는 다음과 같이 기본 메서드에서 수정됩니다.

  • 메서드는 @ CryostatJavaTypeAdapter 주석과 함께 데코레이터됩니다.

    주석은 이 요소의 인스턴스를 처리할 때 사용할 어댑터 클래스를 런타임에 지시합니다. adapter 클래스는 클래스 오브젝트로 지정됩니다.

  • 기본 유형은 javaType 요소의 name 속성으로 지정된 클래스로 교체됩니다.

예 38.11. “글로벌 요소를 위한 사용자 지정 오브젝트 Cryostat 방법” 예 38.7. “글로벌 우선순위 유형 사용자 정의” 에 표시된 사용자 지정의 영향을 받는 요소의 오브젝트 팩토리 메서드를 표시합니다.

예 38.11. 글로벌 요소를 위한 사용자 지정 오브젝트 Cryostat 방법

 @XmlElementDecl(namespace = "http://widgetVendor.com/types/widgetTypes", name = "shorty")
 @XmlJavaTypeAdapter(org.w3._2001.xmlschema.Adapter1.class)
 public JAXBElement<Integer> createShorty(Integer value) {
     return new JAXBElement<Integer>(_Shorty_QNAME, Integer.class, null, value);
 }
Copy to Clipboard Toggle word wrap

XML 스키마 구성이 복잡한 유형의 일부로 정의되면 생성된 Java 속성은 다음과 같이 수정됩니다.

  • 속성은 @ CryostatJavaTypeAdapter 주석과 함께 데코레이터됩니다.

    주석은 이 요소의 인스턴스를 처리할 때 사용할 어댑터 클래스를 런타임에 지시합니다. adapter 클래스는 클래스 오브젝트로 지정됩니다.

  • 속성의 @ Cryostat에는 type 속성이 포함되어 있습니다.

    type 속성의 값은 생성된 오브젝트의 기본 유형을 나타내는 클래스 오브젝트입니다. XML 스키마 기본 유형의 경우 클래스는 String 입니다.

  • 속성은 @ CryostatSchemaType 주석으로 데코레이팅됩니다.

    이 주석은 구문의 XML 스키마 기본 유형을 식별합니다.

  • 기본 유형은 javaType 요소의 name 속성으로 지정된 클래스로 교체됩니다.

예 38.12. “사용자 정의 복잡한 유형” 예 38.7. “글로벌 우선순위 유형 사용자 정의” 에 표시된 사용자 지정의 영향을 받는 요소의 오브젝트 팩토리 메서드를 표시합니다.

예 38.12. 사용자 정의 복잡한 유형

public class NumInventory {

    @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(Adapter1.class) @XmlSchemaType(name = "short") protected Integer numLeft;
    @XmlElement(required = true)
    protected String size;

    public Integer getNumLeft() {
        return numLeft;
    }

    public void setNumLeft(Integer value) {
        this.numLeft = value;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String value) {
        this.size = value;
    }

}
Copy to Clipboard Toggle word wrap

38.2.5. 변환기 구현

Apache CXF 런타임은 parseMethod 속성 및 printMethod 특성에 지정된 메서드를 호출해야 한다는 점을 제외하고 javaType 요소에서 지정한 Java 클래스로 XML 기본 유형을 변환하는 방법을 알 수 없습니다. 런타임 호출을 수행하는 메서드의 구현을 제공해야 합니다. 구현된 메서드는 XML 기본 유형의 사전 구조로 작업할 수 있어야 합니다.

데이터 변환 방법 구현을 단순화하기 위해 Apache CXF는 javax.xml.bind.DatatypeConverter 클래스를 제공합니다. 이 클래스는 모든 XML 스키마 기본 유형을 구문 분석하고 출력하기 위한 메서드를 제공합니다. 구문 분석 메서드는 XML 데이터의 문자열 표현을 사용하고 표 34.1. “XML Schema Primitive Type to Java Native Type Mapping” 에 정의된 기본 유형의 인스턴스를 반환합니다. 출력 메서드는 기본 유형의 인스턴스를 사용하고 XML 데이터의 문자열 표현을 반환합니다.

DatatypeConverter 클래스에 대한 Java 문서는 https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/DatatypeConverter.html 에서 확인할 수 있습니다.

38.2.6. 기본 기본 유형 변환기

Java 기본 유형 또는 Java 기본 유형 Wrapper 클래스 중 하나를 지정할 때 javaType 요소의 name 속성에서 parseMethod 속성 또는 printMethod 특성에 대한 값을 지정할 필요가 없습니다. Apache CXF 런타임은 값이 제공되지 않는 경우 기본 변환기를 대체합니다.

기본 데이터 변환기는 CryostatB DatatypeConverter 클래스를 사용하여 XML 데이터를 구문 분석합니다. 기본 변환기는 변환 작업을 수행하는 데 필요한 모든 유형을 캐스팅합니다.

38.3. 간단한 유형에 대한 Java 클래스 생성

38.3.1. 개요

기본적으로 단순 형식은 열거자인 경우를 제외하고 생성된 형식을 생성하지 않습니다. 간단한 유형을 사용하여 정의된 요소는 Java 기본 유형의 속성에 매핑됩니다.

유형 대체를 사용하려는 경우와 같이 Java 클래스에 간단한 유형을 생성해야 하는 경우가 있습니다.

전역적으로 정의된 모든 간단한 형식에 대한 클래스를 생성하도록 코드 생성기에 지시하려면 globalBindings 사용자 지정 요소의 mapSimpleTypeDeftrue 로 설정합니다.

38.3.2. 사용자 정의 추가

코드 생성기가 이름이 지정된 단순 형식에 대한 Java 클래스를 생성하도록 지시하려면 globalBinding 요소의 mapSimpleTypeDef 속성을 추가하고 해당 값을 true 로 설정합니다.

예 38.13. “In-Line Customization to Force Generation of Java Classes for SimpleTypes” 코드 생성기가 간단한 유형에 대한 Java 클래스를 생성하도록 하는 인라인 사용자 지정을 표시합니다.

예 38.13. In-Line Customization to Force Generation of Java Classes for SimpleTypes

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <annotation>
    <appinfo>
      <jaxb:globalBindings mapSimpleTypeDef="true" />
    </appinfo>
  </annotation>
  ...
</schema>
Copy to Clipboard Toggle word wrap

예 38.14. “강제 발생을 위한 파일 바인딩” 간단한 유형의 생성을 사용자 지정하는 외부 바인딩 파일을 표시합니다.

예 38.14. 강제 발생을 위한 파일 바인딩

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="types.xsd">
    <jaxb:globalBindings mapSimpleTypeDef="true" />
  <jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap
중요

이 사용자 지정은 전역 범위에 정의된 간단한 유형에만 영향을 미칩니다.

38.3.3. 생성된 클래스

간단한 형식에 대해 생성된 클래스에는 value 라는 하나의 속성이 있습니다. value 속성은 34.1절. “기본 유형” 의 매핑에 의해 정의된 Java 유형입니다. 생성된 클래스에는 getter 및 value 속성에 대한 setter가 있습니다.

예 38.16. “간단한 유형의 사용자 정의 매핑” 예 38.15. “사용자 지정된 매핑을 위한 간단한 유형” 에 정의된 간단한 유형에 대해 생성된 Java 클래스를 표시합니다.

예 38.15. 사용자 지정된 매핑을 위한 간단한 유형

<simpleType name="simpleton">
  <restriction base="xsd:string">
    <maxLength value="10"/>
  </restriction>
</simpleType>
Copy to Clipboard Toggle word wrap

예 38.16. 간단한 유형의 사용자 정의 매핑

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "simpleton", propOrder = {"value"})
public class Simpleton {

    @XmlValue
    protected String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}
Copy to Clipboard Toggle word wrap

38.4. 열거 매핑 사용자 정의

38.4.1. 개요

xsd:string 이외의 스키마 유형을 기반으로 하는 열거 형식을 사용하려면 코드 생성기가 매핑하도록 지시해야 합니다.If you want enumerated types that are based on a schema type other than xsd:string, you must instruct the code generator to map it. 생성된 열거 상수의 이름을 제어할 수도 있습니다.

사용자 지정은 jaxb:typesafeEnumClass 요소와 하나 이상의 jaxb:typesafeEnumMember 요소를 사용하여 수행됩니다.

또한 코드 생성기의 기본 설정으로 인해 열거된 모든 멤버에 대해 유효한 Java 식별자를 만들 수 없는 인스턴스가 있을 수 있습니다. globalBindings 사용자 지정 특성을 사용하여 코드 생성기가 이를 처리하는 방법을 사용자 지정할 수 있습니다.

38.4.2. 멤버 이름 사용자 정의

열거 멤버를 생성할 때 코드 생성기가 이름 지정 충돌을 발견하거나 열거 멤버에 대해 유효한 Java 식별자를 만들 수 없는 경우 코드 생성기는 기본적으로 경고를 생성하고 열거에 대한 Java enum 유형을 생성하지 않습니다.

globalBinding 요소의 typesafeEnumMemberName 특성을 추가하여 이 동작을 변경할 수 있습니다. typesafeEnumMemberName 속성의 값은 표 38.2. “열거 멤버 이름 생성 사용자 지정 값” 에 설명되어 있습니다.

Expand
표 38.2. 열거 멤버 이름 생성 사용자 지정 값
현재의설명

skipGeneration(기본값)

Java enum 형식이 생성되지 않고 경고를 생성하도록 지정합니다.

generateName

VALUE_N 패턴에 따라 멤버 이름이 생성되도록 지정합니다. N 은 1에서 시작하여 각 열거 멤버에 대해 증가됩니다.N starts at one, and is incremented for each member of the enumeration.

generateError

열거를 Java 열거 형식에 매핑할 수 없을 때 코드 생성기가 오류를 생성하도록 지정합니다.

예 38.17. “Force Type Safe Member Names에 대한 사용자 정의” 코드 생성기가 type safe 멤버 이름을 생성하도록 하는 인라인 사용자 지정을 표시합니다.

예 38.17. Force Type Safe Member Names에 대한 사용자 정의

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <annotation>
    <appinfo>
      <jaxb:globalBindings typesafeEnumMemberName="generateName" />
    </appinfo>
  </annotation>
  ...
</schema>
Copy to Clipboard Toggle word wrap

38.4.3. 클래스 사용자 정의기

jaxb:typesafeEnumClass 요소는 XML 스키마 열거를 Java enum 유형에 매핑하도록 지정합니다. 표 38.3. “생성된 열거 클래스 사용자 지정에 대한 특성” 에 설명된 두 가지 속성이 있습니다. jaxb:typesafeEnumClass 요소가 인라인으로 지정되면 수정 중인 간단한 유형의 xsd:annotation 요소 내에 배치해야 합니다.

Expand
표 38.3. 생성된 열거 클래스 사용자 지정에 대한 특성
속성설명

name

생성된 Java enum 유형의 이름을 지정합니다. 이 값은 유효한 Java 식별자여야 합니다.

map

열거를 Java 열거 형식에 매핑해야 하는지 여부를 지정합니다. 기본값은 true입니다.

38.4.4. 멤버 사용자 정의기

jaxb:typesafeEnumMember 요소는 XML 스키마 열거 facet와 Java enum 형식 상수 간의 매핑을 지정합니다. 열거자에서 각 열거면에 대해 하나의 jaxb:typesafeEnumMember 요소를 사용해야 합니다.You must use one jaxb:typesafeEnumMember element for each enumeration facet in the enumeration being customized.

인라인 사용자 지정을 사용하는 경우 다음 두 가지 방법 중 하나로 이 요소를 사용할 수 있습니다.

  • 이는 수정 중인 열거 facet의 xsd:annotation 요소 내에 배치할 수 있습니다.
  • 모두 열거를 사용자 지정하는 데 사용되는 jaxb:typesafeEnumClass 요소의 하위 항목으로 배치할 수 있습니다.

jaxb:typesafeEnumMember 요소에는 필요한 name 특성이 있습니다. name 속성은 생성된 Java enum 유형 상수의 이름을 지정합니다. 값은 유효한 Java 식별자여야 합니다.

jaxb:typesafeEnumMember 요소에 특성도 있습니다. 이 값은 열거 면을 적절한 jaxb:typesafeEnumMember 요소와 연결하는 데 사용됩니다. value 특성 값은 enum facets' value 특성의 값 중 하나와 일치해야 합니다. 이 속성은 유형 생성을 위해 외부 바인딩 사양을 사용하거나 jaxb:typesafeEnumMember 요소를 jaxb:typesafeEnumClass 요소의 하위 항목으로 그룹화할 때 필요합니다.

38.4.5. 예

예 38.18. “열거된 형식의 인라인 사용자 지정In-line Customization of an Enumerated Type” 인라인 사용자 지정을 사용하고 열거된 멤버가 별도로 사용자 지정된 열거된 형식을 표시합니다.Shows an enumerated type that uses in-line customization and has the enumeration's members customized separately.

예 38.18. 열거된 형식의 인라인 사용자 지정In-line Customization of an Enumerated Type

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <simpleType name="widgetInteger">
    <annotation>
      <appinfo>
        <jaxb:typesafeEnumClass />
      </appinfo>
    </annotation>
    <restriction base="xsd:int">
      <enumeration value="1">
        <annotation>
          <appinfo>
            <jaxb:typesafeEnumMember name="one" />
          </appinfo>
        </annotation>
      </enumeration>
      <enumeration value="2">
        <annotation>
          <appinfo>
            <jaxb:typesafeEnumMember name="two" />
          </appinfo>
        </annotation>
      </enumeration>
      <enumeration value="3">
        <annotation>
          <appinfo>
            <jaxb:typesafeEnumMember name="three" />
          </appinfo>
        </annotation>
      </enumeration>
      <enumeration value="4">
        <annotation>
          <appinfo>
            <jaxb:typesafeEnumMember name="four" />
          </appinfo>
        </annotation>
      </enumeration>
    </restriction>
  </simpleType>
<schema>
Copy to Clipboard Toggle word wrap

예 38.19. “Combined Mapping을 사용하여 열거된 형식의 인라인 사용자 지정In-line Customization of an Enumerated Type Using a Combined Mapping” 인라인 사용자 지정을 사용하고 클래스 사용자 지정에 멤버의 사용자 지정을 결합하는 열거 형식을 표시합니다.

예 38.19. Combined Mapping을 사용하여 열거된 형식의 인라인 사용자 지정In-line Customization of an Enumerated Type Using a Combined Mapping

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <simpleType name="widgetInteger">
    <annotation>
      <appinfo>
        <jaxb:typesafeEnumClass>
            <jaxb:typesafeEnumMember value="1" name="one" />
            <jaxb:typesafeEnumMember value="2" name="two" />
            <jaxb:typesafeEnumMember value="3" name="three" />
            <jaxb:typesafeEnumMember value="4" name="four" />
        </jaxb:typesafeEnumClass>
      </appinfo>
    </annotation>
    <restriction base="xsd:int">
      <enumeration value="1" />
      <enumeration value="2" />
      <enumeration value="3" />
      <enumeration value="4" >
    </restriction>
  </simpleType>
<schema>
Copy to Clipboard Toggle word wrap

예 38.20. “열거 사용자 지정을 위한 바인딩 파일” 열거된 유형을 사용자 지정하는 외부 바인딩 파일을 표시합니다.Shows an external binding file that customizes an enumerated type.

예 38.20. 열거 사용자 지정을 위한 바인딩 파일

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="enumMap.xsd">
    <jaxb:bindings node="xsd:simpleType[@name='widgetInteger']">
        <jaxb:typesafeEnumClass>
            <jaxb:typesafeEnumMember value="1" name="one" />
            <jaxb:typesafeEnumMember value="2" name="two" />
            <jaxb:typesafeEnumMember value="3" name="three" />
            <jaxb:typesafeEnumMember value="4" name="four" />
        </jaxb:typesafeEnumClass>
    </jaxb:bindings>
  </jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap

38.5. 고정 값 속성 매핑 사용자 정의

38.5.1. 개요

기본적으로 코드 생성기는 고정 값을 일반 속성에 갖는 것으로 정의된 속성을 매핑합니다. 스키마 검증을 사용하는 경우 Apache CXF는 스키마 정의를 적용할 수 있습니다( 24.3.4.7절. “스키마 유효성 검사 유형 값”참조). 그러나 스키마 유효성 검사를 사용하면 메시지 처리 시간이 증가합니다.

고정 값이 있는 속성을 Java에 매핑하는 또 다른 방법은 Java 상수에 매핑하는 것입니다. 전역Bindings 사용자 지정 요소를 사용하여 코드 생성기에 고정 값 특성을 Java 상수에 매핑하도록 지시할 수 있습니다. 속성 요소를 사용하여 보다 지역화된 수준에서 Java 상수에 고정 값 특성의 매핑을 사용자 지정할 수도 있습니다.

38.5.2. 글로벌 사용자 정의

globalBinding 요소의 fixedAttributeAsConstantProperty 특성을 추가하여 이 동작을 변경할 수 있습니다. 이 속성을 true 로 설정하면 고정 특성을 사용하여 정의된 모든 속성을 Java 상수에 매핑하도록 코드 생성기가 지시합니다.

예 38.21. “Constants 강제 생성을 위한 인라인 사용자 지정” 코드 생성기가 고정된 값이 있는 속성에 대한 상수를 생성하도록 하는 인라인 사용자 지정이 표시됩니다.

예 38.21. Constants 강제 생성을 위한 인라인 사용자 지정

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <annotation>
    <appinfo>
      <jaxb:globalBindings fixedAttributeAsConstantProperty="true" />
    </appinfo>
  </annotation>
  ...
</schema>
Copy to Clipboard Toggle word wrap

예 38.22. “강제 발생을 위한 파일 바인딩” 고정 속성 생성을 사용자 지정하는 외부 바인딩 파일을 표시합니다.

예 38.22. 강제 발생을 위한 파일 바인딩

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="types.xsd">
    <jaxb:globalBindings fixedAttributeAsConstantProperty="true" />
  <jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap

38.5.3. 로컬 매핑

속성 요소의 fixedAttributeAsConstantProperty 특성을 사용하여 속성 별로 특성 매핑을 사용자 지정할 수 있습니다. 이 속성을 true 로 설정하면 고정 특성을 사용하여 정의된 모든 속성을 Java 상수에 매핑하도록 코드 생성기가 지시합니다.

예 38.23. “Constants 강제 생성을 위한 인라인 사용자 지정” 코드 생성기가 고정된 값을 사용하여 단일 속성에 대한 상수를 생성하도록 하는 인라인 사용자 지정이 표시됩니다.

예 38.23. Constants 강제 생성을 위한 인라인 사용자 지정

<schema targetNamespace="http://widget.com/types/widgetTypes"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        jaxb:version="2.0">
  <complexType name="widgetAttr">
    <sequence>
      ...
    </sequence>
    <attribute name="fixer" type="xsd:int" fixed="7">
      <annotation> <appinfo> <jaxb:property fixedAttributeAsConstantProperty="true" /> </appinfo> </annotation>
     </attribute>
  </complexType>
  ...
</schema>
Copy to Clipboard Toggle word wrap

예 38.24. “강제 발생을 위한 파일 바인딩” 고정 특성 생성을 사용자 지정하는 외부 바인딩 파일을 표시합니다.

예 38.24. 강제 발생을 위한 파일 바인딩

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="types.xsd">
    <jaxb:bindings node="xsd:complexType[@name='widgetAttr']">
      <jaxb:bindings node="xsd:attribute[@name='fixer']">
            <jaxb:property fixedAttributeAsConstantProperty="true" />
        </jaxb:bindings>
    </jaxb:bindings>
  </jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap

38.5.4. Java 매핑

기본 매핑에서 모든 속성은 getter 및 setter 메서드를 사용하여 표준 Java 속성에 매핑됩니다. 이 사용자 지정이 고정 특성을 사용하여 정의된 속성에 적용되면 예 38.25. “고정 값 특성을 Java Constant에 매핑” 에 표시된 대로 속성이 Java 상수에 매핑됩니다.

예 38.25. 고정 값 특성을 Java Constant에 매핑

@XmlAttribute
public final static type NAME = value;
Copy to Clipboard Toggle word wrap

유형은 34.1절. “기본 유형” 에 설명된 매핑을 사용하여 특성의 기본 유형을 Java 유형에 매핑하여 결정됩니다.

NAME특성 요소의 name 특성 값을 모든 대문자로 변환하여 결정됩니다.

값은 특성 요소의 고정 특성 값에 따라 결정됩니다.

예를 들어 예 38.23. “Constants 강제 생성을 위한 인라인 사용자 지정” 에 정의된 속성은 예 38.26. “Java Constant에 매핑되는 고정 값 속성” 에 표시된 대로 매핑됩니다.

예 38.26. Java Constant에 매핑되는 고정 값 속성

@XmlRootElement(name = "widgetAttr")
public class WidgetAttr {

    ...

  @XmlAttribute
  public final static int FIXER = 7;

  ...

}
Copy to Clipboard Toggle word wrap

38.6. 요소 또는 속성의 기본 유형 지정

38.6.1. 개요

경우에 따라 요소에 대해 생성된 개체의 클래스를 사용자 지정하거나 XML 스키마 복잡한 유형의 일부로 정의된 특성을 사용자 지정해야 합니다. 예를 들어 간단한 형식 대체를 허용하기 위해 보다 일반화된 오브젝트 클래스를 사용할 수 있습니다.

이 작업을 수행하는 한 가지 방법은 CryostatB 기본 유형 사용자 지정을 사용하는 것입니다. 이를 통해 개발자는 사례별로 요소 또는 특성을 나타내기 위해 생성된 오브젝트의 클래스를 지정할 수 있습니다. 기본 유형 사용자 지정을 사용하면 XML 스키마 구성과 생성된 Java 오브젝트 간에 대체 매핑을 지정할 수 있습니다. 이러한 대체 매핑은 간단한 선택 사항이거나 기본 기본 클래스의 일반화일 수 있습니다. 또한 XML 스키마 기본 유형을 Java 클래스에 매핑할 수도 있습니다.

38.6.2. 사용자 정의 사용

XML Schema 구성에 CryostatB 기본 유형 속성을 적용하려면 CryostatB baseType 사용자 지정 요소를 사용합니다. baseType 사용자 지정 요소는 CryostatB 속성 요소의 자식이므로 올바르게 중첩되어야 합니다.

XML 스키마 구성의 매핑을 Java 오브젝트에 사용자 지정하는 방법에 따라 baseType 사용자 지정 요소의 name 속성 또는 javaType 자식 요소를 추가합니다. name 속성은 생성된 오브젝트의 기본 클래스를 동일한 클래스 계층 구조 내의 다른 클래스에 매핑하는 데 사용됩니다. javaType 요소는 XML 스키마 기본 유형을 Java 클래스에 매핑하려는 경우 사용됩니다.

중요

동일한 baseType 사용자 지정 요소에서 name 속성과 javaType 자식 요소를 모두 사용할 수 없습니다.

38.6.3. 기본 매핑 특수화 또는 일반화

baseType 사용자 지정 요소의 name 속성은 생성된 오브젝트의 클래스를 동일한 Java 클래스 계층 구조 내의 클래스에 적용하는 데 사용됩니다. 속성은 XML 스키마 구성이 매핑되는 Java 클래스의 정규화된 이름을 지정합니다. 지정된 Java 클래스는 코드 생성기가 일반적으로 XML 스키마 구성에 대해 생성하는 Java 클래스의 슈퍼 클래스 또는 하위 클래스 여야 합니다. Java 기본 유형에 매핑되는 XML Schema 기본 유형의 경우 래퍼 클래스는 사용자 지정을 위해 기본 기본 클래스로 사용됩니다.

예를 들어 xsd:int 로 정의된 요소는 java.lang.Integer 를 기본 기본 클래스로 사용합니다. name 속성 값은 Number 또는 Object 와 같은 Integer 의 슈퍼 클래스를 지정할 수 있습니다.

간단한 유형 대체의 경우 가장 일반적인 사용자 지정은 기본 유형을 Object 오브젝트에 매핑하는 것입니다.

예 38.27. “기본 유형의 인라인 사용자 지정” 복잡한 유형의 하나의 요소를 Java Object 오브젝트에 매핑하는 인라인 사용자 지정을 보여줍니다.

예 38.27. 기본 유형의 인라인 사용자 지정

<complexType name="widgetOrderInfo">
  <all>
    <element name="amount" type="xsd:int" />
     <element name="shippingAdress" type="Address">
      <annotation> <appinfo> <jaxb:property> <jaxb:baseType name="java.lang.Object" /> </jaxb:property> </appinfo> </annotation>
    </element>
    <element name="type" type="xsd:string"/>
  </all>
</complexType>
Copy to Clipboard Toggle word wrap

예 38.28. “기본 유형을 사용자 정의할 외부 바인딩 파일” 예 38.27. “기본 유형의 인라인 사용자 지정” 에 표시된 사용자 지정의 외부 바인딩 파일을 표시합니다.

예 38.28. 기본 유형을 사용자 정의할 외부 바인딩 파일

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="enumMap.xsd">
    <jaxb:bindings node="xsd:ComplexType[@name='widgetOrderInfo']">
      <jaxb:bindings node="xsd:element[@name='shippingAddress']">
        <jaxb:property>
          <jaxb:baseType name="java.lang.Object" />
        </jaxb:property>
      </jaxb:bindings>
    </jaxb:bindings>
  </jaxb:bindings>
<jaxb:bindings>
Copy to Clipboard Toggle word wrap

생성된 Java 오브젝트의 @ Cryostat 주석에type 속성이 포함되어 있습니다. type 속성의 값은 생성된 오브젝트의 기본 유형을 나타내는 클래스 오브젝트입니다. XML Schema 기본 유형의 경우 클래스는 해당 Java 기본 유형의 래퍼 클래스입니다.

예 38.29. “기본 클래스가 있는 Java 클래스”예 38.28. “기본 유형을 사용자 정의할 외부 바인딩 파일” 의 스키마 정의를 기반으로 생성된 클래스를 표시합니다.

예 38.29. 기본 클래스가 있는 Java 클래스

public class WidgetOrderInfo {

    protected int amount;
    @XmlElement(required = true)
    protected String type;
    @XmlElement(required = true, type = Address.class) protected Object shippingAddress;

    ...
    public Object getShippingAddress() {
        return shippingAddress;
    }

    public void setShippingAddress(Object value) {
        this.shippingAddress = value;
    }

}
Copy to Clipboard Toggle word wrap

38.6.4. javaType과 사용

javaType 요소는 XML Schema 기본 유형을 사용하여 정의된 요소 및 특성을 Java 오브젝트에 매핑하는 방법을 사용자 지정하는 데 사용할 수 있습니다. javaType 요소를 사용하면 baseType 요소의 name 특성을 사용하는 것보다 훨씬 더 많은 유연성을 제공합니다. javaType 요소를 사용하면 기본 유형을 모든 클래스의 오브젝트에 매핑할 수 있습니다.

javaType 요소 사용에 대한 자세한 설명은 38.2절. “XML 스키마의 Java 클래스 지정” 을 참조하십시오.

39장. A Cryo statBContext 오브젝트 사용

초록

Cryo statBContext 개체를 사용하면 Apache CXF의 런타임에서 XML 요소와 Java 개체 간에 데이터를 변환할 수 있습니다. 애플리케이션 개발자는 메시지 처리기에서 Cryostat B 오브젝트를 사용하고 원시 XML 메시지로 작업하는 소비자를 구현할 때 원하는 CryostatBContext 오브젝트를 인스턴스화해야 합니다.

39.1. 개요

Cryo statBContext 오브젝트는 런타임에서 사용하는 하위 수준 오브젝트입니다. 런타임에서 XML 요소와 해당 Java 표현 간에 변환할 수 있습니다. 일반적으로 애플리케이션 개발자는 Cryostat BContext 개체를 사용할 필요가 없습니다. XML 데이터의 마샬링 및 축소 해제는 일반적으로 Cryostat-WS 애플리케이션의 전송 및 바인딩 계층에 의해 처리됩니다.

그러나 애플리케이션이 XML 메시지 콘텐츠를 직접 조작해야 하는 인스턴스가 있습니다. 다음 두 가지 경우에서 다음을 수행합니다.

사용 가능한 두 가지 Cryo statBContext .newInstance() 메서드 중 하나를 사용하여 CryostatBContext 오브젝트를 인스턴스화해야 합니다.

39.2. 모범 사례

jaxbContext 오브젝트는 인스턴스화하는 데 리소스 집약적입니다. 가능한 적은 수의 인스턴스를 생성하는 것이 좋습니다. 이 작업을 수행하는 한 가지 방법은 애플리케이션에서 사용하는 모든 개체를 관리하고 애플리케이션의 여러 부분 간에 공유할 수 있는 단일 Cryostat BContext 오브젝트를 생성하는 것입니다.

jaxbContext 개체는 스레드로부터 안전합니다.

39.3. 오브젝트 팩토리를 사용하여 CryostatBContext 오브젝트 가져오기

Cryo statBContext 클래스는 예 39.1. “클래스를 사용하여 context 가져오기” 에 표시된 newInstance() 메서드를 제공하여 CryostatB 오브젝트를 구현하는 클래스 목록을 가져옵니다.

예 39.1. 클래스를 사용하여 context 가져오기

정적CryostatBContextnewInstanceClass…​classesToBeBoundCryostatBException

반환된 Cryo statBObject 오브젝트는 메서드에 전달된 클래스에 의해 구현된 CryostatB 오브젝트에 대한 데이터를 마샬링하고 비마이클할 수 있습니다. 또한 메서드에 전달된 클래스에서 정적으로 참조되는 모든 클래스를 사용할 수 있습니다.

애플리케이션에서 사용하는 모든 CryostatB 클래스의 이름을 newInstance() 메서드에 전달할 수는 있지만 효율적이지 않습니다. 동일한 목표를 달성하는 더 효율적인 방법은 애플리케이션을 위해 생성된 오브젝트 팩토리 또는 오브젝트 팩토리를 전달하는 것입니다. 결과 Cryo statBContext 오브젝트는 지정된 오브젝트 팩토리에서 인스턴스화할 수 있는 모든 CryostatB 클래스를 관리할 수 있습니다.

39.4. 패키지 이름을 사용하여 CryostatBContext 오브젝트 가져오기

Cryo statBContext 클래스는 예 39.2. “클래스를 사용하여 context 가져오기” 에 표시된 newInstance() 메서드를 제공합니다. 이 메서드는 콜론(:) 패키지 이름 목록을 가져옵니다. 지정된 패키지에는 XML 스키마에서 파생된 CryostatB 오브젝트가 포함되어야 합니다.

예 39.2. 클래스를 사용하여 context 가져오기

정적CryostatBContext새Instance문자열컨텍스트PathPath#178BException

반환된 Cryo statBContext 오브젝트는 지정된 패키지의 클래스에 의해 구현되는 모든 CryostatB 오브젝트에 대해 마샬링 및 비마일 데이터를 마샬링할 수 있습니다.

40장. 비동기 애플리케이션 개발

초록

Cryostat-WS는 서비스에 비동기적으로 액세스하기 위한 간편한 메커니즘을 제공합니다. SEI는 서비스에 비동기적으로 액세스하는 데 사용할 수 있는 추가 메서드를 지정할 수 있습니다. Apache CXF 코드 생성기는 추가 메서드를 생성합니다. 간단히 비즈니스 논리를 추가합니다.

40.1. 비동기 Invocation 유형

일반적인 동기 호출 모드 외에도 Apache CXF는 두 가지 형태의 비동기 호출을 지원합니다.

  • 폴링 접근 방식 - 폴링 접근 방식을 사용하여 원격 작업을 호출하려면 출력 매개 변수가 없는 메서드를 호출하지만 javax.xml.ws.Response 오브젝트를 반환합니다. Response 오브젝트( javax.util.concurrency.Future 인터페이스에서 상속됨)를 폴링하여 응답 메시지가 도착했는지 여부를 확인할 수 있습니다.
  • 콜백 접근 방식 - 콜백 접근 방식을 사용하여 원격 작업을 호출하려면 콜백 오브젝트( javax.xml.ws.AsyncHandler 유형)에 대한 참조를 해당 매개변수 중 하나로 사용하는 메서드를 호출합니다. 응답 메시지가 클라이언트에 도착하면 런타임은 AsyncHandler 오브젝트에서 다시 호출하고 응답 메시지의 내용을 제공합니다.

40.2. 비동기 예제를 위한 WSDL 예

예 40.1. “비동기 계약에 대한 WSDL 계약 예” 비동기 예제에 사용되는 WSDL 계약을 표시합니다. 계약에는 단일 작업이 포함된 단일 인터페이스 GreeterAsync가 정의됩니다.

예 40.1. 비동기 계약에 대한 WSDL 계약 예

<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:tns="http://apache.org/hello_world_async_soap_http"
                  xmlns:x1="http://apache.org/hello_world_async_soap_http/types"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  targetNamespace="http://apache.org/hello_world_async_soap_http"
                  name="HelloWorld">
  <wsdl:types>
    <schema targetNamespace="http://apache.org/hello_world_async_soap_http/types"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:x1="http://apache.org/hello_world_async_soap_http/types"
            elementFormDefault="qualified">
      <element name="greetMeSometime">
        <complexType>
          <sequence>
            <element name="requestType" type="xsd:string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMeSometimeResponse">
        <complexType>
          <sequence>
            <element name="responseType"
                     type="xsd:string"/>
          </sequence>
        </complexType>
      </element>
    </schema>
  </wsdl:types>

  <wsdl:message name="greetMeSometimeRequest">
    <wsdl:part name="in" element="x1:greetMeSometime"/>
  </wsdl:message>
  <wsdl:message name="greetMeSometimeResponse">
    <wsdl:part name="out"
               element="x1:greetMeSometimeResponse"/>
  </wsdl:message>

  <wsdl:portType name="GreeterAsync">
    <wsdl:operation name="greetMeSometime">
      <wsdl:input name="greetMeSometimeRequest"
                  message="tns:greetMeSometimeRequest"/>
      <wsdl:output name="greetMeSometimeResponse"
                   message="tns:greetMeSometimeResponse"/>
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="GreeterAsync_SOAPBinding"
                type="tns:GreeterAsync">
    ...
  </wsdl:binding>

  <wsdl:service name="SOAPService">
    <wsdl:port name="SoapPort"
               binding="tns:GreeterAsync_SOAPBinding">
      <soap:address location="http://localhost:9000/SoapContext/SoapPort"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
Copy to Clipboard Toggle word wrap

40.3. Stub 코드 생성

40.3.1. 개요

비동기 호출 스타일에는 SEI에 정의된 전용 비동기 메서드에 대한 추가 스텁 코드가 필요합니다. 이 특수 스텁 코드는 기본적으로 생성되지 않습니다. 비동기 기능으로 전환하고 필수 스텁 코드를 생성하려면 WSDL 2.0 사양의 매핑 사용자 지정 기능을 사용해야 합니다.

사용자 지정을 사용하면 Maven 코드 생성 플러그인에서 스텁 코드를 생성하는 방법을 수정할 수 있습니다. 특히 WSDL-to-Java 매핑을 수정하고 특정 기능을 전환할 수 있습니다. 여기에서 사용자 지정은 비동기 호출 기능을 전환하는 데 사용됩니다. 사용자 지정은 jaxws:bindings 태그를 사용하여 정의하는 바인딩 선언을 사용하여 지정됩니다( jaxws 접두사가 http://java.sun.com/xml/ns/jaxws 네임스페이스와 연결되어 있음). 바인딩 선언을 지정하는 방법은 다음 두 가지가 있습니다.

외부 바인딩 선언
외부 바인딩 선언을 사용하는 경우 jaxws:bindings 요소는 WSDL 계약과 별도의 파일에 정의됩니다. 스텁 코드를 생성할 때 코드 생성기에 바인딩 선언 파일의 위치를 지정합니다.
임베디드 바인딩 선언
포함된 바인딩 선언을 사용하는 경우 jaxws:bindings 요소를 WSDL 계약에 직접 포함시켜 WSDL 확장으로 처리합니다. 이 경우 jaxws:bindings 의 설정은 즉시 부모 요소에만 적용됩니다.

40.3.2. 외부 바인딩 선언 사용

비동기 호출에서 전환하는 바인딩 선언 파일의 템플릿은 예 40.2. “비동기 바인딩 선언 템플릿” 에 표시됩니다.

예 40.2. 비동기 바인딩 선언 템플릿

<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          wsdlLocation="AffectedWSDL"
          xmlns="http://java.sun.com/xml/ns/jaxws">
  <bindings node="AffectedNode">
    <enableAsyncMapping>true</enableAsyncMapping>
  </bindings>
</bindings>
Copy to Clipboard Toggle word wrap

여기서 AffectedWSDL 은 이 바인딩 선언의 영향을 받는 WSDL 계약의 URL을 지정합니다. AffectedNode 는 WSDL 계약에서 어떤 노드(또는 노드)가 이 바인딩 선언의 영향을 받는지 지정하는 값입니다. 전체 WSDL 계약이 영향을 받으려면 AffectedNodewsdl:definitions 로 설정할 수 있습니다. 비동기 호출 기능을 활성화하려면 jaxws:enableAsyncMapping 요소가 true 로 설정됩니다.

예를 들어 GreeterAsync 인터페이스에 대해서만 비동기 메서드를 생성하려면 이전 바인딩 선언에서 <bindings node="wsdl:definitions/wsdl:portType[@name='GreeterAsync']">을 지정할 수 있습니다.

바인딩 선언이 파일에 저장되어 있다고 가정하면 예 40.3. “소비자 코드 생성” 에 표시된 대로 POM을 설정합니다.

예 40.3. 소비자 코드 생성

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
        <sourceRoot>outputDir</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>hello_world.wsdl</wsdl>
            <extraargs>
              <extraarg>-client</extraarg>
              <extraarg>-b async_binding.xml</extraarg>
            </extraargs>
          </wsdlOption>
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Copy to Clipboard Toggle word wrap

-b 옵션은 코드 생성기에 외부 바인딩 파일을 찾을 위치를 알려줍니다.

코드 생성기에 대한 자세한 내용은 44.2절. “cxf-codegen-plugin” 을 참조하십시오.

40.3.3. 포함된 바인딩 선언 사용

jaxws:bindings 요소 및 연결된 jaxws:enableAsynchMapping 자식을 WSDL에 직접 배치하여 서비스를 정의하는 WSDL 문서에 바인딩 사용자 지정을 직접 포함할 수도 있습니다. jaxws 접두사에 대한 네임스페이스 선언도 추가해야 합니다.

예 40.4. “비동기 매핑에 대한 WSDL 바인딩 선언” 작업에 대한 비동기 매핑을 활성화하는 내장 바인딩 선언이 포함된 WSDL 파일을 표시합니다.

예 40.4. 비동기 매핑에 대한 WSDL 바인딩 선언

<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
                  ...
                  xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
                  ...>
  ...
  <wsdl:portType name="GreeterAsync">
    <wsdl:operation name="greetMeSometime">
      <jaxws:bindings> <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping> </jaxws:bindings>
      <wsdl:input name="greetMeSometimeRequest"
                  message="tns:greetMeSometimeRequest"/>
      <wsdl:output name="greetMeSometimeResponse"
                   message="tns:greetMeSometimeResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>
Copy to Clipboard Toggle word wrap

WSDL 문서에 바인딩 선언을 포함할 때 선언 위치를 변경하여 선언의 영향을 받는 범위를 제어할 수 있습니다. 선언이 wsdl:definitions 요소의 자식으로 배치되면 코드 생성기는 WSDL 문서에 정의된 모든 작업에 대한 비동기 메서드를 생성합니다. wsdl:portType 요소의 자식으로 배치되면 코드 생성기는 인터페이스에 정의된 모든 작업에 대한 비동기 메서드를 생성합니다. wsdl:operation 요소의 자식으로 배치되면 코드 생성기는 해당 작업에 대해서만 비동기 메서드를 생성합니다.

포함된 선언을 사용할 때 코드 생성기에 특수 옵션을 전달할 필요가 없습니다. 코드 생성기는 이를 인식하고 그에 따라 작동합니다.

40.3.4. 생성된 인터페이스

이러한 방식으로 스텁 코드를 생성한 후 GreeterAsync SEI 파일( GreeterAsync.java)은 예 40.5. “비동기 Invocation을 사용하는 서비스 끝점 인터페이스” 에 표시된 대로 정의됩니다.

예 40.5. 비동기 Invocation을 사용하는 서비스 끝점 인터페이스

package org.apache.hello_world_async_soap_http;

import org.apache.hello_world_async_soap_http.types.GreetMeSometimeResponse;
...

public interface GreeterAsync
{
  public Future<?> greetMeSometimeAsync(
        java.lang.String requestType,
        AsyncHandler<GreetMeSometimeResponse> asyncHandler
    );

    public Response<GreetMeSometimeResponse> greetMeSometimeAsync(
        java.lang.String requestType
    );

    public java.lang.String greetMeSometime(
        java.lang.String requestType
    );
}
Copy to Clipboard Toggle word wrap

일반적인 동기 메서드 외에도 Cryo statMeSometime() 작업을 위해 두 개의 비동기 메서드도 생성됩니다.

  • 콜백 접근 publicFuture<?&gt; CryostatMeSomtimeAsyncjava.lang.StringrequestTypeAsyncHandler<GreetMeSomtimeResponse&gt;asyncHandler
  • 폴링 접근 방식 공용Response<GreetMeSomeTimeResponse> CryostatMeSometimeAsyncjava.lang.StringrequestType

40.4. Polling Approach를 사용하여 비동기 클라이언트 구현

40.4.1. 개요

폴링 접근 방식은 두 가지 접근 방식을 통해 비동기 애플리케이션을 개발하는 데 더 간단합니다. 클라이언트는 OperationNameAsync() 라는 비동기 메서드를 호출하고 응답을 폴링하는 Response<T > 개체를 반환합니다. 응답을 기다리는 동안 클라이언트가 수행하는 작업은 애플리케이션의 요구 사항에 따라 다릅니다. 폴링을 처리하는 데는 다음 두 가지 기본 패턴이 있습니다.

  • 비차단 폴링- 주기적으로 비차단 응답<T>.isDone() 메서드를 호출하여 결과가 준비되었는지 확인합니다. 결과가 준비되면 클라이언트가 처리합니다. 그렇지 않은 경우 클라이언트는 다른 작업을 계속합니다.
  • 폴링 차단- 즉시 Response<T>.get() 를 호출하고 응답이 도달할 때까지 차단합니다(선택적으로 시간 초과 지정).

40.4.2. 비차단 패턴 사용

예 40.6. “비동기 작업 호출에 대한 Polling Polling Approach를 차단하지 않음”예 40.1. “비동기 계약에 대한 WSDL 계약 예” 에 정의된 CryostatMeSometime 작업에 대한 비동기 호출을 수행하기 위해 차단이 아닌 폴링을 사용하는 방법을 보여줍니다. 클라이언트는 비동기 작업을 호출하고 주기적으로 결과가 반환되는지 확인합니다.

예 40.6. 비동기 작업 호출에 대한 Polling Polling Approach를 차단하지 않음

package demo.hw.client;

import java.io.File;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.*;

public final class Client {
  private static final QName SERVICE_NAME
    = new QName("http://apache.org/hello_world_async_soap_http",
                "SOAPService");

  private Client() {}

  public static void main(String args[]) throws Exception {

    // set up the proxy for the client

    Response<GreetMeSometimeResponse> greetMeSomeTimeResp =
      port.greetMeSometimeAsync(System.getProperty("user.name"));

      while (!greetMeSomeTimeResp.isDone()) {
      // client does some work
      }
      GreetMeSometimeResponse reply = greetMeSomeTimeResp.get();
      // process the response

      System.exit(0);
  }
}
Copy to Clipboard Toggle word wrap

예 40.6. “비동기 작업 호출에 대한 Polling Polling Approach를 차단하지 않음” 의 코드는 다음을 수행합니다.

프록시에서 MeSometimeAsync() 를 호출합니다.

메서드 호출은 Response<GreetMeSometimeResponse& gt; 오브젝트를 클라이언트에 즉시 반환합니다. Apache CXF 런타임은 원격 끝점에서 응답을 수신하고 Response< GreetMeSometimeResponse > 오브젝트를 채우는 방법에 대한 세부 정보를 처리합니다.

참고

런타임은 요청을 원격 끝점의 Cryostat MeSometime() 메서드로 전송하고 호출의 비동기 특성에 대한 세부 정보를 투명하게 처리합니다. 끝점 및 서비스 구현에서는 클라이언트가 응답을 기다리는 방법에 대한 세부 정보에 대해서는 절대 고려하지 않습니다.

반환된 Response 오브젝트의 isDone() 을 확인하여 응답이 도착했는지 확인합니다.

응답이 도착하지 않으면 다시 확인하기 전에 클라이언트가 계속 작동합니다.

응답이 도착하면 클라이언트는 get() 메서드를 사용하여 Response 오브젝트에서 검색합니다.

40.4.3. 차단 패턴 사용

블록 폴링 패턴을 사용하는 경우 Response 오브젝트의 isDone() 은 호출되지 않습니다. 대신 Response 개체의 get() 메서드는 원격 작업을 호출한 직후 호출합니다. get() 는 응답이 제공될 때까지 차단됩니다.

또한 get() 메서드에 시간 초과 제한을 전달할 수도 있습니다.

예 40.7. “비동기 작업 호출에 대한 Polling Approach 차단” 차단 폴링을 사용하는 클라이언트를 표시합니다.

예 40.7. 비동기 작업 호출에 대한 Polling Approach 차단

package demo.hw.client;

import java.io.File;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.*;

public final class Client {
  private static final QName SERVICE_NAME
    = new QName("http://apache.org/hello_world_async_soap_http",
                "SOAPService");

  private Client() {}

  public static void main(String args[]) throws Exception {

    // set up the proxy for the client

    Response<GreetMeSometimeResponse> greetMeSomeTimeResp =
      port.greetMeSometimeAsync(System.getProperty("user.name"));
    GreetMeSometimeResponse reply = greetMeSomeTimeResp.get();
      // process the response
      System.exit(0);
  }
}
Copy to Clipboard Toggle word wrap

40.5. 콜백 접근 방식을 사용하여 비동기 클라이언트 구현

40.5.1. 개요

비동기 작업 호출을 수행하는 다른 방법은 콜백 클래스를 구현하는 것입니다. 그런 다음 콜백 오브젝트를 매개 변수로 사용하는 비동기 원격 메서드를 호출합니다. 런타임은 콜백 오브젝트에 대한 응답을 반환합니다.

콜백을 사용하는 애플리케이션을 구현하려면 다음을 수행합니다.

  1. AsyncHandler 인터페이스를 구현하는 콜백 클래스를 생성합니다.

    참고

    콜백 오브젝트는 애플리케이션에 필요한 모든 양의 응답 처리를 수행할 수 있습니다.

  2. 콜백 오브젝트를 매개 변수로 사용하고 Future<?> 오브젝트를 반환하는 operationNameAsync() 를 사용하여 원격 호출을 수행합니다.
  3. 클라이언트가 응답 데이터에 액세스해야 하는 경우 반환된 Future <?> 개체의 isDone() 메서드를 폴링하여 원격 엔드포인트에서 응답을 전송했는지 확인할 수 있습니다.

    콜백 오브젝트가 모든 응답 처리를 수행하는 경우 응답이 도착했는지 확인할 필요가 없습니다.

40.5.2. 콜백 구현

콜백 클래스는 javax.xml.ws.AsyncHandler 인터페이스를 구현해야 합니다. 인터페이스는 단일 메서드를 정의합니다. handleResponseResponse<T> 다시 Apache CXF 런타임은 handleResponse() 메서드를 호출하여 응답이 도착했음을 클라이언트에 알립니다. 예 40.8. “javax.xml.ws.AsyncHandler 인터페이스” 구현해야 하는 AsyncHandler 인터페이스의 개요를 보여줍니다.

예 40.8. javax.xml.ws.AsyncHandler 인터페이스

public interface javax.xml.ws.AsyncHandler
{
  void handleResponse(Response<T> res)
}
Copy to Clipboard Toggle word wrap

예 40.9. “콜백 구현 클래스” 예 40.1. “비동기 계약에 대한 WSDL 계약 예” 에 정의된 MeSometime 작업의 콜백 클래스를 표시합니다.

예 40.9. 콜백 구현 클래스

package demo.hw.client;

import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.types.*;

public class GreeterAsyncHandler implements AsyncHandler<GreetMeSometimeResponse>
{
  private GreetMeSometimeResponse reply;

  public void handleResponse(Response<GreetMeSometimeResponse>
                             response)
  {
    try
    {
      reply = response.get();
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }

  public String getResponse()
  {
    return reply.getResponseType();
  }
}
Copy to Clipboard Toggle word wrap

예 40.9. “콜백 구현 클래스” 에 표시된 콜백 구현은 다음을 수행합니다.

원격 끝점에서 반환된 응답을 보유하는 멤버 변수 응답 을 정의합니다.

handleResponse() 를 구현합니다.

이 구현에서는 응답을 추출하고 멤버 변수 회신 에 할당할 수 있습니다.

getResponse() 라는 추가된 메서드를 구현합니다.

이 방법은 회신 에서 데이터를 추출하여 반환하는 편리한 방법입니다.

40.5.3. 소비자 구현

예 40.10. “비동기 작업 호출에 대한 콜백 접근 방식” 콜백 방법을 사용하여 예 40.1. “비동기 계약에 대한 WSDL 계약 예” 에 정의된 GreetMeSometime 작업에 대한 비동기 호출을 수행하는 클라이언트를 보여줍니다.

예 40.10. 비동기 작업 호출에 대한 콜백 접근 방식

package demo.hw.client;

import java.io.File;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.*;

public final class Client {
  ...

  public static void main(String args[]) throws Exception
  {
    ...
    // Callback approach
    GreeterAsyncHandler callback = new GreeterAsyncHandler();

    Future<?> response =
      port.greetMeSometimeAsync(System.getProperty("user.name"),
                                callback);
    while (!response.isDone())
    {
      // Do some work
    }
    resp = callback.getResponse();
    ...
    System.exit(0);
  }
}
Copy to Clipboard Toggle word wrap

예 40.10. “비동기 작업 호출에 대한 콜백 접근 방식” 의 코드는 다음을 수행합니다.

콜백 오브젝트를 인스턴스화합니다.

프록시에서 콜백 오브젝트를 사용하는 MeSometimeAsync() 를 호출합니다.

메서드 호출은 Future<?> 개체를 클라이언트에 즉시 반환합니다. Apache CXF 런타임은 원격 끝점에서 응답을 수신하고, 콜백 오브젝트의 handleResponse() 메서드를 호출하고, Response< GreetMeSometimeResponse > 오브젝트를 채우는 방법에 대한 세부 정보를 처리합니다.

참고

런타임은 원격 끝점의 Cryostat MeSometime() 메서드로 요청을 전송하고 원격 끝점의 지식 없이 호출의 비동기 특성에 대한 세부 정보를 처리합니다. 끝점 및 서비스 구현에서는 클라이언트가 응답을 기다리는 방법에 대한 세부 정보에 대해 우려할 필요가 없습니다.

반환된 Future<?& gt; 개체의 isDone() 메서드를 사용하여 원격 끝점에서 응답이 도착했는지 확인합니다.

콜백 오브젝트의 getResponse() 메서드를 호출하여 응답 데이터를 가져옵니다.

40.6. 원격 서비스에서 반환된 예외 캡처

40.6.1. 개요

비동기 요청을 수행하는 소비자는 동기 요청을 수행할 때 반환된 것과 동일한 예외를 받지 않습니다. 소비자에게 비동기적으로 반환되는 모든 예외는 ExecutionException 예외로 래핑됩니다. 서비스에서 발생한 실제 예외는 ExecutionException 예외의 원인 필드에 저장됩니다.

40.6.2. 예외 검색

원격 서비스에서 생성된 예외는 소비자의 비즈니스 논리에 응답을 전달하는 방법으로 로컬로 throw됩니다. 소비자가 동기 요청을 하면 원격 호출을 통해 예외가 발생합니다. 소비자가 비동기 요청을 수행할 때 Response<T> 개체의 get() 메서드가 예외를 throw합니다. 소비자는 응답 메시지를 검색하려고 시도할 때까지 요청을 처리하는 동안 오류가 발생했음을 검색하지 않습니다.

Cryostat-WS 프레임워크에서 생성된 메서드와 달리 Response<T> 오브젝트의 get() 메서드는 사용자 모델링 예외나 일반 Cryostat-WS 예외도 발생하지 않습니다. 대신 java.util.concurrent.ExecutionException 예외가 발생합니다.

40.6.3. 예외 세부 정보 가져오기

프레임워크는 원격 서비스에서 반환된 예외를 ExecutionException 예외 필드의 cause 필드에 저장합니다. 원격 예외에 대한 세부 정보는 cause 필드의 값을 가져오고 저장된 예외를 검사하여 추출됩니다. 저장된 예외는 모든 사용자 정의 예외 또는 일반 Cryostat-WS 예외 중 하나일 수 있습니다.

40.6.4. 예제

예 40.11. “Polling Approach를 사용하여 예외 catch” 폴링 방법을 사용하여 예외를 catch하는 예를 보여줍니다.

예 40.11. Polling Approach를 사용하여 예외 catch

package demo.hw.client;

import java.io.File;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.*;

public final class Client
{
  private static final QName SERVICE_NAME
    = new QName("http://apache.org/hello_world_async_soap_http",
                "SOAPService");

  private Client() {}

  public static void main(String args[]) throws Exception
  {
    ...
    // port is a previously established proxy object.
    Response<GreetMeSometimeResponse> resp =
       port.greetMeSometimeAsync(System.getProperty("user.name"));

    while (!resp.isDone())
    {
      // client does some work
    }

    try
    {
      GreetMeSometimeResponse reply = greetMeSomeTimeResp.get();
      // process the response
    }
    catch (ExecutionException ee)
    {
       Throwable cause = ee.getCause();
       System.out.println("Exception "+cause.getClass().getName()+" thrown by the remote service.");
    }
  }
}
Copy to Clipboard Toggle word wrap

예 40.11. “Polling Approach를 사용하여 예외 catch” 의 코드는 다음을 수행합니다.

호출을 try/catch 블록에서 Response<T> 오브젝트의 get() 메서드로 래핑합니다.

ExecutionException 예외를 가져옵니다.

예외에서 cause 필드를 추출합니다.

소비자가 콜백 접근 방식을 사용하는 경우 예외를 catch하는 데 사용되는 코드는 서비스의 응답이 추출된 콜백 오브젝트에 배치됩니다.

41장. 원시 XML 메시지 사용

초록

고급 Cryostat-WS API는 데이터를 CryostatB 객체로 마샬링하여 개발자가 네이티브 XML 메시지를 사용하지 못하도록 보호합니다. 그러나 전선에 전달되는 원시 XML 메시지 데이터에 직접 액세스하는 것이 더 나은 경우가 있습니다. Cryostat-WS API는 원시 XML에 대한 액세스를 제공하는 두 개의 인터페이스를 제공합니다. Dispatch 인터페이스는 클라이언트 측 인터페이스이고 공급자 인터페이스는 서버 측 인터페이스입니다.

41.1. 소비자에서 XML 사용

초록

Dispatch 인터페이스는 원시 메시지와 직접 작업할 수 있는 낮은 수준의 Cryostat-WS API입니다. 192.0.2. 개체, Cryostat 메시지 및 CryostatB 오브젝트를 포함한 다양한 유형의 메시지 또는 페이로드를 수락하고 반환합니다. 하위 수준 API이므로 Dispatch 인터페이스는 상위 수준의 Cryostat-WS API가 수행하는 메시지 준비 작업을 수행하지 않습니다. 메시지 또는 페이로드가 Dispatch 개체로 전달되는 것이 적절하고 호출되는 원격 작업에 적합한지 확인해야 합니다.

41.1.1. 사용 모드

41.1.1.1. 개요

디스패치 오브젝트에는 두 가지 사용 모드가 있습니다.

Dispatch 오브젝트에 지정하는 사용 모드는 사용자 수준 코드로 전달되는 세부 정보의 양을 결정합니다.

41.1.1.2. 메시지 모드

메시지 모드에서 Dispatch 오브젝트는 완전한 메시지와 함께 작동합니다. 전체 메시지에는 바인딩 특정 헤더 및 래퍼가 포함됩니다. 예를 들어 Cryostat 메시지가 필요한 서비스와 상호 작용하는 소비자는 Dispatch 개체의 invoke() 메서드를 완전히 지정된 Cryostat 메시지를 제공해야 합니다. invoke() 메서드도 완전히 지정된 Cryostat 메시지를 반환합니다. 소비자 코드는 Cryostat 메시지의 헤더와 message's message's information을 작성하고 읽습니다.

CryostatB 오브젝트로 작업할 때는 메시지 모드가 적합하지 않습니다.

Dispatch 개체가 메시지 모드를 사용하도록 지정하려면 Dispatch 오브젝트를 생성할 때 java.xml.ws.Service.Mode.MESSAGE 값을 제공합니다. Dispatch 오브젝트 생성에 대한 자세한 내용은 “Dispatch 오브젝트 생성” 에서 참조하십시오.

41.1.1.3. 페이로드 모드

페이로드 모드에서 는 메시지 페이로드 모드라고도 하며 Dispatch 오브젝트는 메시지의 페이로드에서만 작동합니다. 예를 들어 페이로드 모드에서 작동하는 Dispatch 오브젝트는 Cryostat 메시지의 본문에서만 작동합니다. 바인딩 계층은 바인딩 수준 래퍼 및 헤더를 처리합니다. 결과가 invoke() 메서드에서 반환되면 바인딩 수준 래퍼 및 헤더가 이미 제거되고 메시지의 본문만 남습니다.

Apache CXF XML 바인딩, 페이로드 모드 및 메시지 모드와 같이 특수 래퍼를 사용하지 않는 바인딩으로 작업하는 경우 동일한 결과를 제공합니다.

Dispatch 개체가 페이로드 모드를 사용하도록 지정하려면 Dispatch 오브젝트를 생성할 때 java.xml.ws.Service.Mode.PAYLOAD 값을 제공합니다. Dispatch 오브젝트 생성에 대한 자세한 내용은 “Dispatch 오브젝트 생성” 에서 참조하십시오.

41.1.2. 데이터 유형

41.1.2.1. 개요

Dispatch 오브젝트는 하위 수준 오브젝트이므로 상위 소비자 API와 동일한 CryostatB 생성 유형을 사용하기에 최적화되지 않습니다. 디스패치 오브젝트는 다음 유형의 오브젝트에서 작동합니다.

41.1.2.2. 소스 오브젝트 사용

Dispatch 오브젝트는 javax.xml.transform.Source 인터페이스에서 파생된 오브젝트를 수락하고 반환합니다. 소스 오브젝트는 모든 바인딩과 메시지 모드 또는 페이로드 모드에서 지원됩니다.

소스 오브젝트는 XML 문서를 보유하는 하위 수준 오브젝트입니다. 각 소스 구현은 저장된 XML 문서에 액세스한 다음 해당 내용을 조작하는 메서드를 제공합니다. 다음 오브젝트는 소스 인터페이스를 구현합니다.

CryostatSource
XML 메시지를 Document Object Model(DOM) 트리로 보관합니다. XML 메시지는 get Node () 메서드를 사용하여 액세스하는 노드 오브젝트 세트로 저장됩니다. 노드는 setNode() 메서드를 사용하여 Cryostat 트리에 업데이트하거나 추가할 수 있습니다.
SAXSource
XML 메시지를 SX(Simple API for XML) 개체로 보관합니다. SAX 개체에는 원시 데이터 및 원시 데이터를 구문 분석하는 XML Cryostat 개체를 보유하는 InputSource 오브젝트가 포함되어 있습니다.
StreamSource
XML 메시지를 데이터 스트림으로 보관합니다. 데이터 스트림은 다른 데이터 스트림과 동일하게 조작될 수 있습니다.

Dispatch 개체를 생성하여 일반 Source 오브젝트를 사용하도록 하는 경우 Apache CXF는 메시지를 SAXSource 개체로 반환합니다.

이 동작은 끝점의 source-preferred-format 속성을 사용하여 변경할 수 있습니다. Apache CXF 런타임 구성에 대한 자세한 내용은 IV 부. 웹 서비스 엔드 포인트 구성 을 참조하십시오.

41.1.2.3. CryostatMessage 오브젝트 사용

다음 조건이 true인 경우 디스패치 오브젝트는 javax.xml.soap.SOAPMessage 오브젝트를 사용할 수 있습니다.

  • Dispatch 개체가 Cryostat 바인딩을 사용하고 있습니다.
  • Dispatch 오브젝트에서 메시지 모드를 사용 중

Cryo statMessage 오브젝트에는 Cryostat 메시지가 있습니다. 이 개체에는 하나의 CryostatPart 개체와 0개 이상의 AttachmentPart 개체가 포함되어 있습니다. Cryo statPart 개체에는 Cryostat, any Cryostat 헤더 및 Cryostat 메시지 본문을 포함하여 Cryostat 메시지의 Cryostat 특정 부분이 포함되어 있습니다. AttachmentPart 오브젝트에는 첨부 파일로 전달되는 바이너리 데이터가 포함되어 있습니다.

41.1.2.4. DataSource 개체 사용

디스패치 개체는 다음 조건이 true인 경우 javax.activation.DataSource 인터페이스를 구현하는 개체를 사용할 수 있습니다.

  • Dispatch 오브젝트에서 HTTP 바인딩을 사용하고 있습니다.
  • Dispatch 오브젝트에서 메시지 모드를 사용 중

데이터 소스 오브젝트는 URL, 파일, 바이트 배열을 포함하여 다양한 소스에서 MIME 형식 데이터를 사용하기 위한 메커니즘을 제공합니다.

41.1.2.5. CryostatB 오브젝트 사용

Dispatch 오브젝트는 원시 메시지로 작업할 수 있는 낮은 수준 API로 의도된 반면, 이를 통해 CryostatB 오브젝트를 사용할 수도 있습니다. CryostatB 개체를 사용하려면 Dispatch 오브젝트를 전달해야 합니다. 이 오브젝트는 마샬링 및 사용 중인 개체를 위임 해제할 수 있습니다. Cryo statBContextDispatch 오브젝트가 생성될 때 전달됩니다.

CryostatB Context 오브젝트에서 이해하는 모든 CryostatB 오브젝트를 invoke() 메서드에 매개 변수로 전달할 수 있습니다. 반환된 메시지를 Cryostat BContext 개체에서 인식하는 모든 object로 캐스팅할 수도 있습니다.

Cryostat BContext 오브젝트 생성에 대한 자세한 내용은 39장. A Cryo statBContext 오브젝트 사용 을 참조하십시오.

41.1.3. Dispatch Objects 작업

41.1.3.1. 절차

Dispatch 오브젝트를 사용하여 원격 서비스를 호출하려면 다음 시퀀스를 따라야 합니다.

  1. Dispatch 오브젝트를 생성합니다.
  2. 요청 메시지를 구성합니다.
  3. 적절한 invoke() 메서드를 호출합니다.
  4. 응답 메시지를 구문 분석합니다.
41.1.3.2. Dispatch 오브젝트 생성

Dispatch 오브젝트를 생성하려면 다음을 수행합니다.

  1. Dispatch 개체가 호출할 서비스를 정의하는 wsdl:service 요소를 나타내는 Service 오브젝트를 생성합니다. 25.2절. “서비스 오브젝트 생성”을 참조하십시오.
  2. 예 41.1. “createDispatch() 메서드” 에 표시된 Service 오브젝트의 createDispatch() 메서드를 사용하여 Dispatch 오브젝트를 생성합니다.

    예 41.1. createDispatch() 메서드

    publicDispatch<T>createDispatchQNameportNamejava.lang.Class<T>typeService.ModemodeWebServiceException

    참고

    CryostatB 개체를 사용하는 경우 createDispatch() 에 대한 메서드 서명은 publicDispatch<T>createDispatchQNameportNamejavax.xml.bind.JAXBContextcontextService.ModemodeWebServiceException

    표 41.1. “createDispatch()매개변수” createDispatch() 메서드의 매개변수를 설명합니다.

    Expand
    표 41.1. createDispatch()매개변수
    매개변수설명

    portName

    Dispatch 개체가 호출할 서비스 공급자를 나타내는 wsdl:port 요소의 QName을 지정합니다.

    type

    Dispatch 개체에서 사용하는 오브젝트의 데이터 형식을 지정합니다. 41.1.2절. “데이터 유형”을 참조하십시오. CryostatB 오브젝트로 작업할 때 이 매개변수는 개체를 마샬링하고 unmarshal하는 데 사용되는 Cryostat BContext 오브젝트를 지정합니다.

    mode

    Dispatch 오브젝트의 사용 모드를 지정합니다. 41.1.1절. “사용 모드”을 참조하십시오.

예 41.2. “Dispatch 오브젝트 생성” 페이로드 모드에서 192.0.2. Source 개체와 함께 작동하는 Dispatch 개체를 만드는 코드를 보여줍니다.

예 41.2. Dispatch 오브젝트 생성

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    QName serviceName = new QName("http://org.apache.cxf", "stockQuoteReporter");
    Service s = Service.create(serviceName);

    QName portName = new QName("http://org.apache.cxf", "stockQuoteReporterPort");
    Dispatch<DOMSource> dispatch = s.createDispatch(portName,
                                                  DOMSource.class,
                                                  Service.Mode.PAYLOAD);
    ...
Copy to Clipboard Toggle word wrap
41.1.3.3. 요청 메시지 구성

Dispatch 오브젝트로 작업할 때 요청을 처음부터 빌드해야 합니다. 개발자는 Dispatch 오브젝트에 전달된 메시지가 대상 서비스 공급자가 처리할 수 있는 요청과 일치하는지 확인해야 합니다. 이를 위해서는 서비스 공급자가 사용하는 메시지와 필요한 헤더 정보가 무엇인지에 대한 정확한 지식이 필요합니다.

이 정보는 WSDL 문서 또는 메시지를 정의하는 XML 스키마 문서에서 제공할 수 있습니다. 서비스 공급자는 크게 다르지만 몇 가지 지침을 따라야합니다.

  • 요청의 root 요소는 호출되는 작업에 해당하는 wsdl:operation 요소의 name 특성 값을 기반으로 합니다.

    주의

    호출 중인 서비스에서 doc/literal 베어 메시지를 사용하는 경우 요청의 root 요소는 wsdl:operation 요소가 참조하는 wsdl:part 요소의 name 속성 값을 기반으로 합니다.

  • 요청의 root 요소는 namespace qualified 입니다.
  • 호출 중인 서비스에서 rpc/literal 메시지를 사용하는 경우 요청의 최상위 요소는 네임스페이스가 정규화되지 않습니다.

    중요

    최상위 요소의 하위 항목은 네임스페이스가 한정될 수 있습니다. 이를 위해서는 해당 스키마 정의를 확인해야 합니다.

  • 호출 중인 서비스에서 rpc/literal 메시지를 사용하는 경우 최상위 요소 중 어느 것도 null일 수 없습니다.
  • 호출 중인 서비스에서 doc/literal 메시지를 사용하는 경우 메시지의 스키마 정의에서 네임스페이스가 유효한지 여부를 결정합니다.

서비스에서 XML 메시지를 사용하는 방법에 대한 자세한 내용은 WS-I Basic Profile 을 참조하십시오.

41.1.3.4. 동기 호출

응답을 생성하는 동기 호출을 수행하는 소비자의 경우 예 41.3. “Dispatch.invoke() 메서드” 에 표시된 Dispatch 오브젝트의 invoke() 메서드를 사용합니다.

예 41.3. Dispatch.invoke() 메서드

TmsgWebServiceException호출

Dispatch 개체가 생성될 때 invoke() 메서드에 전달된 응답 및 요청의 유형이 결정됩니다. 예를 들어 createDispatch(portName, CryostatMessage.class, Service.Mode.MESSAGE) 를 사용하여 Dispatch 오브젝트를 생성하는 경우 응답과 요청은 모두 Cryostat Message 오브젝트입니다.

참고

CryostatB 개체를 사용하는 경우 응답과 요청은 제공된 모든 유형 중 하나일 수 있으며, 제공된 Cryostat BContext 개체는 마샬링 및 unmarshal을 마샬링할 수 있습니다. 또한 응답과 요청은 다른 CryostatB 오브젝트일 수 있습니다.

예 41.4. “Dispatch 오브젝트를 사용하여 Synchronous Invocation 만들기” 192.0.2. Source 개체를 사용하여 원격 서비스에 대해 동기적으로 호출하기 위한 코드를 표시합니다.

예 41.4. Dispatch 오브젝트를 사용하여 Synchronous Invocation 만들기

// Creating a DOMSource Object for the request
DocumentBuilder db = DocumentBuilderFactory.newDocumentBuilder();
Document requestDoc = db.newDocument();
Element root = requestDoc.createElementNS("http://org.apache.cxf/stockExample",
                                          "getStockPrice");
root.setNodeValue("DOW");
DOMSource request = new DOMSource(requestDoc);

// Dispatch disp created previously
DOMSource response = disp.invoke(request);
Copy to Clipboard Toggle word wrap
41.1.3.5. 비동기 호출

디스패치 개체는 비동기 호출도 지원합니다. 40장. 비동기 애플리케이션 개발 에서 논의된 상위 수준의 비동기 API와 마찬가지로 Dispatch 오브젝트는 폴링 접근 방식과 콜백 접근 방식을 모두 사용할 수 있습니다.

폴링 방식을 사용할 때 invokeAsync() 메서드는 응답이 도착했는지 확인하기 위해 폴링할 수 있는 Response<t > 오브젝트를 반환합니다. 예 41.5. “Dispatch.invokeAsync() Polling 방법” 폴링 방식을 사용하여 비동기 호출을 수행하는 데 사용되는 메서드의 서명을 표시합니다.

예 41.5. Dispatch.invokeAsync() Polling 방법

응답 <T&gt;invokeAsyncTmsgWebServiceException

비동기 호출에 폴링 접근 방식을 사용하는 방법에 대한 자세한 내용은 40.4절. “Polling Approach를 사용하여 비동기 클라이언트 구현” 을 참조하십시오.

콜백 접근 방식을 사용할 때 invokeAsync() 메서드는 응답을 반환할 때 응답을 처리하는 AsyncHandler 구현을 사용합니다. 예 41.6. “콜백을 사용한 Dispatch.invokeAsync() 메서드” 콜백 접근 방식을 사용하여 비동기 호출을 수행하는 데 사용되는 메서드의 서명을 표시합니다.

예 41.6. 콜백을 사용한 Dispatch.invokeAsync() 메서드

future<?&gt;invokeAsyncTmsgAsyncHandler<T>처리기WebServiceException

비동기 호출에 콜백 접근 방식을 사용하는 방법에 대한 자세한 내용은 40.5절. “콜백 접근 방식을 사용하여 비동기 클라이언트 구현” 을 참조하십시오.

참고

동기 invoke() 메서드와 마찬가지로 응답 유형과 요청 유형이 Dispatch 개체를 생성할 때 결정됩니다.

41.1.3.6. OneWay 호출

요청이 응답을 생성하지 않으면 Dispatch 오브젝트의 invokeOneWay() 를 사용하여 원격 호출을 수행합니다. 예 41.7. “Dispatch.invokeOneWay() 방법” 이 메서드의 서명을 표시합니다.

예 41.7. Dispatch.invokeOneWay() 방법

invokeOneWayTmsgWebServiceException

요청을 패키징하는 데 사용되는 오브젝트 유형은 Dispatch 오브젝트가 생성될 때 결정됩니다. 예를 들어 Dispatch 개체가 createDispatch(portName, CryostatSource.class, Service.Mode.PAYLOAD) 를 사용하여 생성된 경우 요청은GROUP Source 개체로 패키징됩니다.

참고

CryostatB 개체를 사용하는 경우 응답과 요청은 제공된 Cryostat BContext 개체가 마샬링 및 unmarshal을 마샬링할 수 있는 모든 유형일 수 있습니다.

예 41.8. “Dispatch 오브젝트를 사용하여 One way Invocation 만들기” shows code for making a oneway invocation on a remote service using a CryostatB 오브젝트를 사용하여 원격 서비스에서 단방향 호출을 수행하는 코드를 표시합니다.

예 41.8. Dispatch 오브젝트를 사용하여 One way Invocation 만들기

// Creating a JAXBContext and an Unmarshaller for the request
JAXBContext jbc = JAXBContext.newInstance("org.apache.cxf.StockExample");
Unmarshaller u = jbc.createUnmarshaller();

// Read the request from disk
File rf = new File("request.xml");
GetStockPrice request = (GetStockPrice)u.unmarshal(rf);

// Dispatch disp created previously
disp.invokeOneWay(request);
Copy to Clipboard Toggle word wrap

41.2. 서비스 공급자에서 XML 사용

초록

공급자 인터페이스는 원시 XML로 메시지에서 직접 작동하는 서비스 공급자를 구현할 수 있는 낮은 수준의 Cryostat-WS API입니다. 메시지는 Provider 인터페이스를 구현하는 개체에 전달되기 전에는 패키지되지 않습니다.

41.2.1. 메시징 모드

41.2.1.1. 개요

공급자 인터페이스를 구현하는 오브젝트에는 두 가지 메시징 모드가 있습니다.

지정한 메시징 모드에 따라 구현에 전달되는 메시징 세부 정보가 결정됩니다.

41.2.1.2. 메시지 모드

메시지 모드를 사용하는 경우 공급자 구현이 완전한 메시지와 함께 작동합니다. 전체 메시지에는 바인딩 특정 헤더 및 래퍼가 포함됩니다. 예를 들어 Cryostat 바인딩을 사용하는 공급자 구현은 요청을 완전히 지정된 Cryostat 메시지로 수신합니다. 구현에서 반환된 모든 응답은 완전히 지정된 Cryostat 메시지여야 합니다.

공급자 구현에서 예 41.9. “공급자 구현에서 메시지 모드를 사용하도록 지정” 와 같이 java.xml.ws.Service.Mode.MESSAGE 값을 javax.xml.ws.ServiceMode 주석의 값으로 제공하여 메시지 모드를 사용하도록 지정하려면 다음을 수행합니다.

예 41.9. 공급자 구현에서 메시지 모드를 사용하도록 지정

@WebServiceProvider
@ServiceMode(value=Service.Mode.MESSAGE)
public class stockQuoteProvider implements Provider<SOAPMessage>
{
  ...
}
Copy to Clipboard Toggle word wrap
41.2.1.3. 페이로드 모드

페이로드 모드에서 는 공급자 구현이 메시지의 페이로드에서만 작동합니다. 예를 들어 페이로드 모드에서 작동하는 공급자 구현은 ESP 메시지의 본문에서만 작동합니다. 바인딩 계층은 바인딩 수준 래퍼 및 헤더를 처리합니다.

Apache CXF XML 바인딩, 페이로드 모드 및 메시지 모드와 같이 특수 래퍼를 사용하지 않는 바인딩으로 작업하는 경우 동일한 결과를 제공합니다.

공급자 구현에서 예 41.10. “공급자 구현에서 페이로드 모드를 사용하도록 지정” 와 같이 java.xml.ws.Service.Mode.PAYLOAD 값을 javax.xml.ws.ServiceMode 주석의 값으로 제공하여 페이로드 모드를 사용하도록 지정하려면 다음을 수행합니다.

예 41.10. 공급자 구현에서 페이로드 모드를 사용하도록 지정

@WebServiceProvider
@ServiceMode(value=Service.Mode.PAYLOAD)
public class stockQuoteProvider implements Provider<DOMSource>
{
  ...
}
Copy to Clipboard Toggle word wrap

@ServiceMode 주석의 값을 지정하지 않으면 공급자 구현에서 페이로드 모드를 사용합니다.

41.2.2. 데이터 유형

41.2.2.1. 개요

공급자 구현은 하위 수준 개체이므로 공급자 구현에서 더 높은 수준의 소비자 API와 동일한 CryostatB 생성 유형을 사용할 수 없습니다. 공급자 구현은 다음 유형의 오브젝트에서 작동합니다.

41.2.2.2. 소스 오브젝트 사용

공급자 구현은 javax.xml.transform.Source 인터페이스에서 파생된 오브젝트를 수락하고 반환할 수 있습니다. 소스 오브젝트는 XML 문서를 보유하는 하위 수준 오브젝트입니다. 각 소스 구현은 저장된 XML 문서에 액세스하고 해당 내용을 조작하는 메서드를 제공합니다. 다음 오브젝트는 소스 인터페이스를 구현합니다.

CryostatSource
XML 메시지를 Document Object Model(DOM) 트리로 보관합니다. XML 메시지는 get Node () 메서드를 사용하여 액세스하는 노드 오브젝트 세트로 저장됩니다. 노드는 setNode() 메서드를 사용하여 Cryostat 트리에 업데이트하거나 추가할 수 있습니다.
SAXSource
XML 메시지를 SX(Simple API for XML) 개체로 보관합니다. SAX 개체에는 원시 데이터 및 원시 데이터를 구문 분석하는 XML Cryostat 개체를 보유하는 InputSource 오브젝트가 포함되어 있습니다.
StreamSource
XML 메시지를 데이터 스트림으로 보관합니다. 데이터 스트림은 다른 데이터 스트림과 동일하게 조작될 수 있습니다.

일반 소스 오브젝트를 사용하도록 Provider 오브젝트를 생성하면 Apache CXF에서 메시지를 SAXSource 개체로 반환합니다.

이 동작은 끝점의 source-preferred-format 속성을 사용하여 변경할 수 있습니다. Apache CXF 런타임 구성에 대한 자세한 내용은 IV 부. 웹 서비스 엔드 포인트 구성 을 참조하십시오.

중요

Source 오브젝트를 사용할 때 개발자는 필요한 모든 바인딩 특정 래퍼가 메시지에 추가되도록 합니다. 예를 들어, Cryostat 메시지를 예상하는 서비스와 상호 작용할 때 개발자는 필요한 Cryostat가 발신 요청에 추가되고 Cryostat의 콘텐츠가 올바른지 확인해야 합니다.

41.2.2.3. CryostatMessage 오브젝트 사용

다음 조건이 true인 경우 공급자 구현에서는 javax.xml.soap.SOAPMessage 오브젝트를 사용할 수 있습니다.

  • Provider 구현에서 source binding을 사용하고 있습니다.
  • 공급자 구현에서 메시지 모드를 사용 중

Cryo statMessage 오브젝트에는 Cryostat 메시지가 있습니다. 이 개체에는 하나의 CryostatPart 개체와 0개 이상의 AttachmentPart 개체가 포함되어 있습니다. Cryo statPart 개체에는 Cryostat, any Cryostat 헤더 및 Cryostat 메시지 본문을 포함하여 Cryostat 메시지의 Cryostat 특정 부분이 포함되어 있습니다. AttachmentPart 오브젝트에는 첨부 파일로 전달되는 바이너리 데이터가 포함되어 있습니다.

41.2.2.4. DataSource 개체 사용

다음 조건이 true인 경우 공급자 구현에서는 javax.activation.DataSource 인터페이스를 구현하는 오브젝트를 사용할 수 있습니다.

  • 구현에서 HTTP 바인딩을 사용하고 있습니다.
  • 구현에서 메시지 모드를 사용 중입니다.

데이터 소스 오브젝트는 URL, 파일, 바이트 배열을 포함하여 다양한 소스에서 MIME 형식 데이터를 사용하기 위한 메커니즘을 제공합니다.

41.2.3. 공급자 오브젝트 구현

41.2.3.1. 개요

공급자 인터페이스는 구현하기가 비교적 쉽습니다. 구현되어야 하는 하나의 메서드인 invoke() 만 있습니다. 또한 세 가지 간단한 요구 사항이 있습니다.

  • 구현에 @WebServiceProvider 주석이 있어야 합니다.
  • 구현에는 기본 공용 생성자가 있어야 합니다.
  • 구현에서는 입력된 버전의 공급자 인터페이스를 구현해야 합니다.

    즉, Provider<T> 인터페이스를 구현할 수 없습니다. 41.2.2절. “데이터 유형” 에 나열된 대로 구체적인 데이터 유형을 사용하는 인터페이스 버전을 구현해야 합니다. 예를 들어 Provider<SAXSource>의 인스턴스를 구현할 수 있습니다.

공급자 인터페이스 구현의 복잡성은 요청 메시지를 처리하고 적절한 응답을 구축하는 논리에 있습니다.

41.2.3.2. 메시지 작업

상위 수준 SEI 기반 서비스 구현과 달리 공급자 구현은 요청을 원시 XML 데이터로 수신하며 응답을 원시 XML 데이터로 보내야 합니다. 이를 위해서는 개발자가 구현 중인 서비스에서 사용하는 메시지에 대한 지식이 있어야 합니다. 이러한 세부 사항은 일반적으로 서비스를 설명하는 WSDL 문서에서 확인할 수 있습니다.

WS-I Basic Profile 은 다음을 포함하여 서비스에서 사용하는 메시지에 대한 지침을 제공합니다.

  • 요청의 루트 요소는 호출되는 작업에 해당하는 wsdl:operation 요소의 name 속성 값을 기반으로 합니다.

    주의

    서비스에서 doc/literal 베어 메시지를 사용하는 경우 요청의 루트 요소는 wsdl:operation 요소에서 참조하는 wsdl:part 요소의 name 속성 값을 기반으로 합니다.

  • 모든 메시지의 root 요소는 namespace qualified입니다.
  • 서비스에서 rpc/literal 메시지를 사용하는 경우 메시지의 최상위 요소는 네임스페이스가 정규화되지 않습니다.

    중요

    최상위 요소의 자식은 네임스페이스를 정규화할 수 있지만 스키마 정의를 확인해야 합니다.

  • 서비스에서 rpc/literal 메시지를 사용하는 경우 최상위 요소 중 어느 것도 null일 수 없습니다.
  • 서비스에서 doc/literal 메시지를 사용하는 경우 메시지의 스키마 정의에서 네임스페이스가 유효한지 여부를 결정합니다.
41.2.3.3. @WebServiceProvider 주석

Cryostat-WS에서 서비스 구현으로 인식하려면 공급자 구현을 @WebServiceProvider 주석으로 데코레이팅해야 합니다.

표 41.2. “@WebServiceProvider 속성” @WebServiceProvider 주석에 대해 설정할 수 있는 속성에 대해 설명합니다.

Expand
표 41.2. @WebServiceProvider 속성
속성설명

portName

서비스의 엔드포인트를 정의하는 wsdl:port 요소의 name 속성 값을 지정합니다.

serviceName

서비스의 엔드포인트가 포함된 wsdl:service 요소의 name 속성 값을 지정합니다.

targetNamespace

서비스의 WSDL 정의의 targetname 공간을 지정합니다.

wsdlLocation

서비스를 정의하는 WSDL 문서의 URI를 지정합니다.

이러한 속성은 모두 선택 사항이며 기본적으로 비어 있습니다. 해당 항목을 비워 두면 Apache CXF는 구현 클래스에서 정보를 사용하여 값을 생성합니다.

41.2.3.4. invoke() 메서드 구현

공급자 인터페이스에는 구현해야 하는 하나의 메서드인 invoke() 만 있습니다. invoke() 메서드는 구현 중인 공급자 인터페이스 유형에서 선언한 오브젝트 유형으로 패키지된 들어오는 요청을 수신하고 동일한 유형의 오브젝트로 패키지된 응답 메시지를 반환합니다. 예를 들어 Provider< SOAPMessage > 인터페이스의 구현은 request를 CryostatMessage 오브젝트로 수신하고 response를 Cryostat Message 오브젝트로 반환합니다.

공급자 구현에서 사용하는 메시징 모드에 따라 요청 및 응답 메시지에 포함된 바인딩 특정 정보의 양이 결정됩니다. 메시지 모드를 사용하는 구현은 요청과 함께 특정 래퍼 및 헤더를 모두 수신합니다. 또한 응답 메시지에 특정 래퍼 및 헤더를 모두 추가해야 합니다. 페이로드 모드를 사용하는 구현은 요청 본문만 수신합니다. 페이로드 모드를 사용하여 구현에 의해 반환된 XML 문서는 요청 메시지의 본문에 배치됩니다.

41.2.3.5. 예

예 41.11. “provider<SOAPMessage> 구현” 메시지 모드에서 Cryostat Message 개체와 함께 작동하는 Provider 구현을 표시합니다.

예 41.11. provider<SOAPMessage> 구현

import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;

@WebServiceProvider(portName="stockQuoteReporterPort"
                    serviceName="stockQuoteReporter")
@ServiceMode(value="Service.Mode.MESSAGE")
public class  stockQuoteReporterProvider implements Provider<SOAPMessage>
{
public stockQuoteReporterProvider()
  {
  }

public SOAPMessage invoke(SOAPMessage request)
  {
  SOAPBody requestBody = request.getSOAPBody();
  if(requestBody.getElementName.getLocalName.equals("getStockPrice"))
    {
    MessageFactory mf = MessageFactory.newInstance();
      SOAPFactory sf = SOAPFactory.newInstance();

    SOAPMessage response = mf.createMessage();
      SOAPBody respBody = response.getSOAPBody();
      Name bodyName = sf.createName("getStockPriceResponse");
      respBody.addBodyElement(bodyName);
      SOAPElement respContent = respBody.addChildElement("price");
      respContent.setValue("123.00");
      response.saveChanges();
    return response;
    }
    ...
  }
}
Copy to Clipboard Toggle word wrap

예 41.11. “provider<SOAPMessage> 구현” 의 코드는 다음을 수행합니다.

다음 클래스는 wsdl:service 요소라는 서비스를 구현하는 Provider 오브젝트를 구현하도록 합니다. 이 개체의 이름은 score QuoteReporter 이고, 해당 wsdl:port 요소 이름이 price QuoteReporterPort 입니다.

이 공급자 구현에서 메시지 모드를 사용하도록 지정합니다.

필요한 기본 공용 생성자를 제공합니다.

ESPMessage 개체를 사용하고 Cryostat Message 개체를 반환하는 invoke() 메서드의 구현을 제공합니다.

들어오는 Cryostat 메시지의 본문에서 요청 메시지를 추출합니다.

요청 메시지의 root 요소를 확인하여 요청을 처리하는 방법을 결정합니다.

응답을 구축하는 데 필요한 공장을 만듭니다.

응답에 대한 Cryostat 메시지를 빌드합니다.

response를 Cryostat Message 오브젝트로 반환합니다.

예 41.12. “공급자<DOMSource> 구현” 페이로드 모드에서 192.0.2. Source 개체를 사용하는 공급자 구현 예를 보여줍니다.

예 41.12. 공급자<DOMSource> 구현

import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;

@WebServiceProvider(portName="stockQuoteReporterPort" serviceName="stockQuoteReporter")
@ServiceMode(value="Service.Mode.PAYLOAD")
public class  stockQuoteReporterProvider implements Provider<DOMSource>
public stockQuoteReporterProvider()
  {
  }

public DOMSource invoke(DOMSource request)
  {
    DOMSource response = new DOMSource();
    ...
    return response;
  }
}
Copy to Clipboard Toggle word wrap

예 41.12. “공급자<DOMSource> 구현” 의 코드는 다음을 수행합니다.

클래스가 wsdl:service 요소의 이름이 scoreQuoteReporter 이고 해당 wsdl:port 요소 이름이 equivalent QuoteReporter Port 인 서비스를 구현하는 Provider 오브젝트를 지정합니다.

이 공급자 구현에서 페이로드 모드를 사용하도록 지정합니다.

필요한 기본 공용 생성자를 제공합니다.

CryostatSource 개체를 사용하고 192.0.2. Source 개체를 반환하는 invoke() 메서드의 구현을 제공합니다.

42장. 컨텍스트 작업

초록

Cryostat-WS는 컨텍스트를 사용하여 메시징 체인을 통해 메타데이터를 전달합니다. 이 메타데이터는 해당 범위에 따라 구현 수준 코드에서 액세스할 수 있습니다. 구현 수준 아래의 메시지에서 작동하는 Cryostat-WS 핸들러에도 액세스할 수 있습니다.

42.1. 컨텍스트 이해

42.1.1. 개요

대부분의 경우 메시지에 대한 정보를 애플리케이션의 다른 부분에 전달해야 합니다. Apache CXF는 컨텍스트 메커니즘을 사용하여 이 작업을 수행합니다. 컨텍스트는 발신 또는 들어오는 메시지와 관련된 속성을 보유하는 맵입니다. 컨텍스트에 저장된 속성은 일반적으로 메시지에 대한 메타데이터이며 메시지를 전달하는 데 사용되는 기본 전송입니다. 예를 들어 HTTP 응답 코드 또는 JMS 상관 ID와 같은 메시지를 전송하는 데 사용되는 전송 특정 헤더는 Cryostat-WS 컨텍스트에 저장됩니다.

컨텍스트는 모든 수준의 Cryostat-WS 애플리케이션에서 사용할 수 있습니다. 그러나 메시지 처리 스택에서 컨텍스트에 액세스하는 위치에 따라 미묘한 방식이 다릅니다. Cryostat-WS Handler 구현은 컨텍스트에 직접 액세스할 수 있으며 설정된 모든 속성에 액세스할 수 있습니다. 서비스 구현에서는 컨텍스트를 삽입하여 액세스 권한을 적용하고 APPLICATION 범위에서 설정된 속성에만 액세스할 수 있습니다. 소비자 구현은 APPLICATION 범위에 설정된 속성에만 액세스할 수 있습니다.

그림 42.1. “메시지 컨텍스트 및 메시지 처리 경로” 컨텍스트 속성이 Apache CXF를 통과하는 방법을 보여줍니다. 메시지가 메시징 체인을 통과하면 연결된 메시지 컨텍스트가 함께 전달됩니다.

그림 42.1. 메시지 컨텍스트 및 메시지 처리 경로

메시지 컨텍스트는 클라이언트 및 서버 메시지 처리 체인을 통해 사용할 수 있습니다.

42.1.2. 컨텍스트에 속성을 저장하는 방법

메시지 컨텍스트는 javax.xml.ws.handler.MessageContext 인터페이스의 모든 구현입니다. MessageContext 인터페이스는 java.util.Map<String 키, Object value> 인터페이스를 확장합니다. map 오브젝트는 정보를 키 값 쌍으로 저장합니다.

메시지 컨텍스트에서 속성은 이름/값 쌍으로 저장됩니다. 속성의 키는 속성을 식별하는 문자열입니다. 속성 값은 Java 개체에 저장된 모든 값일 수 있습니다. 메시지 컨텍스트에서 값이 반환되면 애플리케이션은 예상 유형을 알고 적절하게 캐스팅해야 합니다. 예를 들어 속성의 값이 UserInfo 개체에 저장된 경우 메시지 컨텍스트에서 여전히 UserInfo 개체로 캐스팅해야 하는 Object 개체로 반환됩니다.For example, if a property's value is stored in a UserInfo object it is still returned from a message context as an Object object that must be cast back into a UserInfo object.

메시지 컨텍스트의 속성에도 범위가 있습니다. 범위는 메시지 처리 체인에서 속성에 액세스할 수 있는 위치를 결정합니다.

42.1.3. 속성 범위

메시지 컨텍스트의 속성은 범위가 지정됩니다. 속성은 다음 범위 중 하나에 있을 수 있습니다.

애플리케이션
APPLICATION 으로 범위가 지정된 속성은 Cryostat-WS Handler 구현, 소비자 구현 코드 및 서비스 공급자 구현 코드에서 사용할 수 있습니다. 처리기가 서비스 공급자 구현에 속성을 전달해야 하는 경우 속성의 범위를 APPLICATION 으로 설정합니다. 소비자 구현 또는 서비스 공급자 구현 컨텍스트에서 설정된 모든 속성은 자동으로 APPLICATION 으로 범위가 지정됩니다.
HANDLER
HANDLER 로 범위가 지정된 속성은 Cryostat-WS Handler 구현에서만 사용할 수 있습니다. Handler 구현에서 메시지 컨텍스트에 저장된 속성은 기본적으로 HANDLER 로 범위가 지정됩니다.

메시지 컨텍스트의 setScope() 메서드를 사용하여 속성 범위를 변경할 수 있습니다. 예 42.1. “MessageContext.setScope() 메서드” 메서드의 서명을 표시합니다.

예 42.1. MessageContext.setScope() 메서드

SetScopeStringMessageContext.Scope범위java.lang.IllegalArgumentException

첫 번째 매개 변수는 속성의 키를 지정합니다. 두 번째 매개 변수는 속성의 새 범위를 지정합니다. 범위는 다음 중 하나일 수 있습니다.

  • MessageContext.Scope.APPLICATION
  • MessageContext.Scope.HANDLER

42.1.4. 처리기의 컨텍스트 개요

Cryostat-WS Handler 인터페이스를 구현하는 클래스는 메시지의 컨텍스트 정보에 직접 액세스할 수 있습니다. 메시지의 컨텍스트 정보는 Handler 구현의 handleMessage(), handleFault()close() 메서드에 전달됩니다.

처리기 구현은 범위에 관계없이 메시지 컨텍스트에 저장된 모든 속성에 액세스할 수 있습니다. 또한 논리 처리기는 LogicalMessageContext 라는 특수 메시지 컨텍스트를 사용합니다. LogicalMessageContext 오브젝트에는 메시지 본문의 콘텐츠에 액세스하는 메서드가 있습니다.

42.1.5. 서비스 구현의 컨텍스트 개요

서비스 구현은 메시지 컨텍스트에서 APPLICATION 으로 범위가 지정된 속성에 액세스할 수 있습니다. 서비스 공급자의 구현 오브젝트는 WebServiceContext 오브젝트를 통해 메시지 컨텍스트에 액세스합니다.

자세한 내용은 42.2절. “서비스 구현에서 컨텍스트 작업” 에서 참조하십시오.

42.1.6. 소비자 구현의 컨텍스트 개요

소비자 구현은 메시지 컨텍스트의 콘텐츠에 대한 간접 액세스 권한을 갖습니다. 소비자 구현에는 두 가지 별도의 메시지 컨텍스트가 있습니다.

  • 요청 컨텍스트 - 발신 요청에 사용되는 속성의 사본을 보유하고 있습니다.
  • 응답 컨텍스트 - 들어오는 응답에서 속성의 사본을 보유하고 있습니다.

디스패치 계층은 소비자 구현의 메시지 컨텍스트와 Handler 구현에서 사용하는 메시지 컨텍스트 간에 속성을 전송합니다.

요청이 소비자 구현에서 디스패치 계층에 전달되면 요청 컨텍스트의 콘텐츠가 디스패치 계층에서 사용되는 메시지 컨텍스트로 복사됩니다. 서비스에서 응답이 반환되면 디스패치 계층에서 메시지를 처리하고 적절한 속성을 메시지 컨텍스트로 설정합니다. 디스패치 계층에서 응답을 처리하면 메시지 컨텍스트에서 APPLICATION 범위 모든 속성을 소비자 구현의 응답 컨텍스트에 복사합니다.

자세한 내용은 42.3절. “소비자 구현에서 컨텍스트 작업” 에서 참조하십시오.

42.2. 서비스 구현에서 컨텍스트 작업

42.2.1. 개요

컨텍스트 정보는 WebServiceContext 인터페이스를 사용하여 서비스 구현에 제공됩니다. WebServiceContext 개체에서 애플리케이션 범위에서 현재 요청의 컨텍스트 속성으로 채워진 MessageContext 개체를 가져올 수 있습니다. 속성 값을 조작할 수 있으며 응답 체인을 통해 다시 전파됩니다.

참고

MessageContext 인터페이스는 java.util.Map 인터페이스에서 상속됩니다. 해당 내용은 Map 인터페이스의 방법을 사용하여 조작할 수 있습니다.

42.2.2. 컨텍스트 가져오기

서비스 구현에서 메시지 컨텍스트를 가져오려면 다음을 수행합니다.

  1. WebServiceContext 유형의 변수를 선언합니다.
  2. javax.annotation.Resource 주석으로 변수를 분리하여 컨텍스트 정보가 변수에 삽입되고 있음을 나타냅니다.
  3. get MessageContext () 메서드를 사용하여 WebServiceContext 오브젝트에서 MessageContext 오브젝트를 가져옵니다.

    중요

    getMessageContext()@WebMethod 주석으로 데코레이팅되는 메서드에서만 사용할 수 있습니다.

예 42.2. “서비스 구현에서 컨텍스트 오브젝트 가져오기” 컨텍스트 오브젝트를 가져오기 위한 코드를 표시합니다.

예 42.2. 서비스 구현에서 컨텍스트 오브젝트 가져오기

import javax.xml.ws.*;
import javax.xml.ws.handler.*;
import javax.annotation.*;

@WebServiceProvider
public class WidgetServiceImpl
{
  @Resource
  WebServiceContext wsc;

  @WebMethod
  public String getColor(String itemNum)
  {
    MessageContext context = wsc.getMessageContext();
  }

  ...
}
Copy to Clipboard Toggle word wrap

42.2.3. 컨텍스트에서 속성 읽기

구현에 대한 MessageContext 오브젝트를 가져온 후에는 예 42.3. “MessageContext.get() 메서드” 에 표시된 get() 메서드를 사용하여 여기에 저장된 속성에 액세스할 수 있습니다.

예 42.3. MessageContext.get() 메서드

v오브젝트가져오기

참고

get() 는 Map 인터페이스에서 상속됩니다.

key 매개변수는 컨텍스트에서 검색할 속성을 나타내는 문자열입니다. get() 는 속성의 적절한 유형으로 캐스팅되어야 하는 오브젝트를 반환합니다. 표 42.1. “서비스 구현 컨텍스트에서 사용 가능한 속성” 서비스 구현의 컨텍스트에서 사용할 수 있는 여러 속성을 나열합니다.Lists a number of the properties that are available in a service implementation's context.

중요

컨텍스트에서 반환된 개체의 값을 변경하면 컨텍스트의 속성 값도 변경됩니다.

예 42.4. “서비스의 메시지 컨텍스트에서 속성 가져오기” 호출된 작업을 나타내는 WSDL 작업 요소의 이름을 가져오기 위한 코드를 표시합니다.

예 42.4. 서비스의 메시지 컨텍스트에서 속성 가져오기

import javax.xml.ws.handler.MessageContext;
import org.apache.cxf.message.Message;

  ...
  // MessageContext context retrieved in a previous example
  QName wsdl_operation = (QName)context.get(Message.WSDL_OPERATION);
Copy to Clipboard Toggle word wrap

42.2.4. 컨텍스트에서 속성 설정

구현에 대한 MessageContext 오브젝트를 가져온 후에는 예 42.5. “MessageContext.put() 메서드” 에 표시된 put() 메서드를 사용하여 속성을 설정하고 기존 속성을 변경할 수 있습니다.

예 42.5. MessageContext.put() 메서드

V키 VVClassCastExceptionIllegalArgumentExceptionNullPointerException

설정 중인 속성이 이미 메시지 컨텍스트에 존재하는 경우 put() 메서드는 기존 값을 새 값으로 교체하고 이전 값을 반환합니다. 속성이 메시지 컨텍스트에 존재하지 않는 경우 put() 메서드는 속성을 설정하고 null 을 반환합니다.

예 42.6. “서비스의 메시지 컨텍스트에서 속성 설정” HTTP 요청에 대한 응답 코드를 설정하는 코드를 표시합니다.

예 42.6. 서비스의 메시지 컨텍스트에서 속성 설정

import javax.xml.ws.handler.MessageContext;
import org.apache.cxf.message.Message;

  ...
  // MessageContext context retrieved in a previous example
  context.put(Message.RESPONSE_CODE, new Integer(404));
Copy to Clipboard Toggle word wrap

42.2.5. 지원되는 컨텍스트

표 42.1. “서비스 구현 컨텍스트에서 사용 가능한 속성” 서비스 구현 개체의 컨텍스트를 통해 액세스할 수 있는 속성을 나열합니다.Lists the properties accessible through the context in a service implementation object.

Expand
표 42.1. 서비스 구현 컨텍스트에서 사용 가능한 속성
속성 이름설명

org.apache.cxf.message.Message

PROTOCOL_HEADERS[a]

전송 특정 헤더 정보를 지정합니다. 값은 java.util.Map<String, List<String>> 로 저장됩니다.

RESPONSE_CODE

소비자에게 반환되는 응답 코드를 지정합니다. 값은 Integer 오브젝트로 저장됩니다.

ENDPOINT_ADDRESS

서비스 공급자의 주소를 지정합니다. 값은 문자열로 저장됩니다.

HTTP_REQUEST_METHOD

요청과 함께 전송된 HTTP 동사를 지정합니다. 값은 문자열로 저장됩니다.

PATH_INFO

요청된 리소스의 경로를 지정합니다. 값은 문자열로 저장됩니다.

경로는 호스트 이름 뒤와 쿼리 문자열 앞에 있는 URI의 일부입니다. 예를 들어 끝점의 URI가 http://cxf.apache.org/demo/widgets 인 경우 경로는 /demo/widgets 입니다.

QUERY_STRING

요청을 호출하는 데 사용되는 URI에 연결된 경우 쿼리를 지정합니다. 값은 문자열로 저장됩니다.

쿼리는 URI 끝에 표시됩니다. ?. 예를 들어 http://cxf.apache.org/demo/widgets?color 에 대한 요청이 있는 경우 쿼리는 색상 입니다.

MTOM_ENABLED

서비스 공급자가 MTOM을음음 첨부 파일에 사용할 수 있는지 여부를 지정합니다. 값은 부울 로 저장됩니다.

SCHEMA_VALIDATION_ENABLED

서비스 공급자가 스키마에 대한 메시지의 유효성을 검증할지 여부를 지정합니다. 값은 부울 로 저장됩니다.

FAULT_STACKTRACE_ENABLED

런타임에서 오류 메시지와 함께 스택 추적을 제공하는지 여부를 지정합니다. 값은 부울 로 저장됩니다.

CONTENT_TYPE

메시지의 MIME 형식을 지정합니다. 값은 문자열로 저장됩니다.

BASE_PATH

요청된 리소스의 경로를 지정합니다. 이 값은 java.net.URL 로 저장됩니다.

경로는 호스트 이름 뒤와 쿼리 문자열 앞에 있는 URI의 일부입니다. 예를 들어 끝점의 URL이 http://cxf.apache.org/demo/widgets 인 경우 기본 경로는 /demo/widgets 입니다.

인코딩

메시지의 인코딩을 지정합니다. 값은 문자열로 저장됩니다.

FIXED_PARAMETER_ORDER

매개 변수가 특정 순서로 메시지에 표시되어야 하는지 여부를 지정합니다. 값은 부울 로 저장됩니다.

MAINTAIN_SESSION

소비자가 향후 요청에 대해 현재 세션을 유지 관리하려는지 여부를 지정합니다. 값은 부울 로 저장됩니다.

WSDL_DESCRIPTION

구현 중인 서비스를 정의하는 WSDL 문서를 지정합니다. 이 값은 org.xml.sax.InputSource 오브젝트로 저장됩니다.

WSDL_SERVICE

구현 중인 서비스를 정의하는 wsdl:service 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

WSDL_PORT

서비스에 액세스하는 데 사용되는 엔드포인트를 정의하는 wsdl:port 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

WSDL_INTERFACE

구현 중인 서비스를 정의하는 wsdl:portType 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

WSDL_OPERATION

소비자가 호출한 작업에 해당하는 wsdl:operation 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

javax.xml.ws.handler.MessageContext

MESSAGE_OUTBOUND_PROPERTY

메시지가 아웃바운드인지 여부를 지정합니다. 값은 부울 로 저장됩니다. true 는 메시지가 아웃바운드임을 나타냅니다.

INBOUND_MESSAGE_ATTACHMENTS

요청 메시지에 포함된 첨부 파일을 포함합니다. 값은 java.util.Map<String, DataHandler>로 저장됩니다.

맵의 키 값은 헤더의 MIME Content-ID입니다.

OUTBOUND_MESSAGE_ATTACHMENTS

응답 메시지에 대한 첨부 파일을 포함합니다. 값은 java.util.Map<String, DataHandler>로 저장됩니다.

맵의 키 값은 헤더의 MIME Content-ID입니다.

WSDL_DESCRIPTION

구현 중인 서비스를 정의하는 WSDL 문서를 지정합니다. 이 값은 org.xml.sax.InputSource 오브젝트로 저장됩니다.

WSDL_SERVICE

구현 중인 서비스를 정의하는 wsdl:service 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

WSDL_PORT

서비스에 액세스하는 데 사용되는 엔드포인트를 정의하는 wsdl:port 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

WSDL_INTERFACE

구현 중인 서비스를 정의하는 wsdl:portType 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

WSDL_OPERATION

소비자가 호출한 작업에 해당하는 wsdl:operation 요소의 정규화된 이름을 지정합니다. 값은 QName 으로 저장됩니다.

HTTP_RESPONSE_CODE

소비자에게 반환되는 응답 코드를 지정합니다. 값은 Integer 오브젝트로 저장됩니다.

HTTP_REQUEST_HEADERS

요청의 HTTP 헤더를 지정합니다. 값은 java.util.Map<String, List<String>> 로 저장됩니다.

HTTP_RESPONSE_HEADERS

응답의 HTTP 헤더를 지정합니다. 값은 java.util.Map<String, List<String>> 로 저장됩니다.

HTTP_REQUEST_METHOD

요청과 함께 전송된 HTTP 동사를 지정합니다. 값은 문자열로 저장됩니다.

SERVLET_REQUEST

서블릿의 request 오브젝트를 포함합니다. 값은 javax.servlet.http.HttpServletRequest 로 저장됩니다.

SERVLET_RESPONSE

서블릿의 응답 오브젝트를 포함합니다. 값은 javax.servlet.http.HttpResponse 로 저장됩니다.

SERVLET_CONTEXT

서블릿의 컨텍스트 오브젝트를 포함합니다. 값은 javax.servlet.ServletContext 로 저장됩니다.

PATH_INFO

요청된 리소스의 경로를 지정합니다. 값은 문자열로 저장됩니다.

경로는 호스트 이름 뒤와 쿼리 문자열 앞에 있는 URI의 일부입니다. 예를 들어 끝점의 URL이 http://cxf.apache.org/demo/widgets 인 경우 경로는 /demo/widgets 입니다.

QUERY_STRING

요청을 호출하는 데 사용되는 URI에 연결된 경우 쿼리를 지정합니다. 값은 문자열로 저장됩니다.

쿼리는 URI 끝에 표시됩니다. ?. 예를 들어 http://cxf.apache.org/demo/widgets?color 에 대한 요청이 있는 경우 쿼리 문자열은 색상 입니다.

REFERENCE_PARAMETERS

WS-Addressing 참조 매개변수를 지정합니다. 여기에는 wsa:IsReferenceParameter 속성이 true 로 설정된 모든 Cryostat 헤더가 포함됩니다. 값은 java.util.List 로 저장됩니다.

org.apache.cxf.transport.jms.JMSConstants

JMS_SERVER_HEADERS

JMS 메시지 헤더를 포함합니다. 자세한 내용은 42.4절. “JMS 메시지 속성 작업” 에서 참조하십시오.

[a] HTTP를 사용하는 경우 이 속성은 표준 Cryostat-WS 정의 속성과 동일합니다.

42.3. 소비자 구현에서 컨텍스트 작업

42.3.1. 개요

소비자 구현은 BindingProvider 인터페이스를 통해 컨텍스트 정보에 액세스할 수 있습니다. BindingProvider 인스턴스는 두 개의 개별 컨텍스트에 컨텍스트 정보를 보유합니다.

  • 요청 컨텍스트 요청 컨텍스트 를 사용하면 아웃바운드 메시지에 영향을 주는 속성을 설정할 수 있습니다. 요청 컨텍스트 속성은 특정 포트 인스턴스에 적용되며, 설정된 경우 속성과 같은 시간이 명시적으로 지워질 때까지 포트에서 수행된 모든 후속 작업 호출에 영향을 미칩니다. 예를 들어 요청 컨텍스트 속성을 사용하여 연결 시간 초과를 설정하거나 헤더에서 전송할 데이터를 초기화할 수 있습니다.
  • 응답 컨텍스트 응답 컨텍스트 를 사용하면 현재 스레드에서 수행된 마지막 작업 호출에 대한 응답으로 설정된 속성 값을 읽을 수 있습니다. 응답 컨텍스트 속성은 모든 작업 호출 후 재설정됩니다. 예를 들어 응답 컨텍스트 속성에 액세스하여 마지막 인바운드 메시지에서 수신된 헤더 정보를 읽을 수 있습니다.
중요

메시지 컨텍스트의 애플리케이션 범위에 배치된 정보만 소비자 구현에서 액세스할 수 있습니다.

42.3.2. 컨텍스트 가져오기

컨텍스트는 javax.xml.ws.BindingProvider 인터페이스를 사용하여 가져옵니다. BindingProvider 인터페이스에는 컨텍스트를 가져오기 위한 두 가지 메서드가 있습니다.

  • getRequestContext() 예 42.7. “getRequestContext() 메서드” 에 표시된 getRequestContext() 메서드는 요청 컨텍스트를 Map 오브젝트로 반환합니다. 반환된 Map 오브젝트를 사용하여 컨텍스트의 콘텐츠를 직접 조작할 수 있습니다.

    예 42.7. getRequestContext() 메서드

    Map<String, Object>getRequestContext

  • getResponseContext() 예 42.8. “getResponseContext() 메서드” 에 표시된 getResponseContext() 는 응답 컨텍스트를 Map 오브젝트로 반환합니다. 반환된 Map 오브젝트의 콘텐츠는 현재 스레드에서 만든 원격 서비스에 대한 가장 최근의 요청에 대한 응답 컨텍스트 내용의 상태를 반영합니다.

    예 42.8. getResponseContext() 메서드

    Map<String, Object>getResponseContext

프록시 개체는 BindingProvider 인터페이스를 구현하므로 프록시 개체를 캐스팅하여 BindingProvider 개체를 가져올 수 있습니다.Because proxy objects implement the BindingProvider interface, a BindingProvider object can be obtained by casting a proxy object. BindingProvider 개체에서 가져온 컨텍스트는 이를 생성하는 데 사용되는 프록시 오브젝트에서 호출된 작업에만 유효합니다.

예 42.9. “소비자의 요청 컨텍스트 가져오기” 프록시에 대한 요청 컨텍스트를 가져오는 코드를 표시합니다.

예 42.9. 소비자의 요청 컨텍스트 가져오기

// Proxy widgetProxy obtained previously
BindingProvider bp = (BindingProvider)widgetProxy;
Map<String, Object> requestContext = bp.getRequestContext();
Copy to Clipboard Toggle word wrap

42.3.3. 컨텍스트에서 속성 읽기

소비자 컨텍스트는 java.util.Map<String, Object> 오브젝트에 저장됩니다. 맵에는 임의의 개체가 포함된 String 개체 및 값인 키가 있습니다. java.util.Map.get() 을 사용하여 응답 컨텍스트 속성 맵의 항목에 액세스합니다.

특정 컨텍스트 속성인 ContextPropertyName 을 검색하려면 예 42.10. “응답 컨텍스트 속성 읽기” 에 표시된 코드를 사용합니다.

예 42.10. 응답 컨텍스트 속성 읽기

// Invoke an operation.
port.SomeOperation();

// Read response context property.
java.util.Map<String, Object> responseContext =
  ((javax.xml.ws.BindingProvider)port).getResponseContext();
PropertyType propValue = (PropertyType) responseContext.get(ContextPropertyName);
Copy to Clipboard Toggle word wrap

42.3.4. 컨텍스트에서 속성 설정

소비자 컨텍스트는 java.util.Map<String, Object> 개체에 저장된 해시 맵 입니다. 맵에는 임의의 오브젝트인 String 개체 및 값인 키가 있습니다. 컨텍스트에서 속성을 설정하려면 java.util.Map.put() 메서드를 사용합니다.

요청 컨텍스트와 응답 컨텍스트에서 속성을 설정할 수 있지만 요청 컨텍스트에 대한 변경 사항만 메시지 처리에 영향을 미칩니다. 응답 컨텍스트의 속성은 현재 스레드에서 각 원격 호출이 완료되면 재설정됩니다.

예 42.11. “요청 컨텍스트 속성 설정” 에 표시된 코드는 BindingProvider.ENDPOINT_ADDRESS_PROPERTY 값을 설정하여 대상 서비스 공급자의 주소를 변경합니다.

예 42.11. 요청 컨텍스트 속성 설정

// Set request context property.
java.util.Map<String, Object> requestContext =
     ((javax.xml.ws.BindingProvider)port).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/widgets");

// Invoke an operation.
port.SomeOperation();
Copy to Clipboard Toggle word wrap
중요

속성 값이 요청 컨텍스트에서 설정되면 모든 후속 원격 호출에 사용됩니다.Once a property is set in the request context its value is used for all subsequent remote invocations. 값을 변경할 수 있으며 변경된 값이 사용됩니다.

42.3.5. 지원되는 컨텍스트

Apache CXF는 소비자 구현에서 다음과 같은 컨텍스트 속성을 지원합니다.

Expand
표 42.2. 소비자 컨텍스트 속성
속성 이름설명

javax.xml.ws.BindingProvider

ENDPOINT_ADDRESS_PROPERTY

대상 서비스의 주소를 지정합니다. 값은 문자열로 저장됩니다.

USERNAME_PROPERTY[a]

HTTP 기본 인증에 사용되는 사용자 이름을 지정합니다. 값은 문자열로 저장됩니다.

PASSWORD_PROPERTY[b]

HTTP 기본 인증에 사용되는 암호를 지정합니다. 값은 문자열로 저장됩니다.

SESSION_MAINTAIN_PROPERTY[c]

클라이언트가 세션 정보를 유지 관리하려는지 여부를 지정합니다. 값은 부울 오브젝트로 저장됩니다.

org.apache.cxf.ws.addressing.JAXWSAConstants

CLIENT_ADDRESSING_PROPERTIES

소비자가 원하는 서비스 공급자에 연결하는 데 사용하는 WS-Addressing 정보를 지정합니다. 이 값은 org.apache.cxf.ws.addressing.AddressingProperties 로 저장됩니다.

org.apache.cxf.transports.jms.context.JMSConstants

JMS_CLIENT_REQUEST_HEADERS

메시지의 JMS 헤더를 포함합니다. 자세한 내용은 42.4절. “JMS 메시지 속성 작업” 에서 참조하십시오.

[a] 이 속성은 HTTP 보안 설정에 정의된 사용자 이름으로 재정의됩니다.
[b] 이 속성은 HTTP 보안 설정에 정의된 암호로 재정의됩니다.
[c] Apache CXF는 이 속성을 무시합니다.

42.4. JMS 메시지 속성 작업

초록

Apache CXF JMS 전송에는 JMS 메시지의 속성을 검사하는 데 사용할 수 있는 컨텍스트 메커니즘이 있습니다. 컨텍스트 메커니즘을 사용하여 JMS 메시지의 속성을 설정할 수도 있습니다.

42.4.1. JMS 메시지 헤더 검사

초록

소비자 및 서비스는 다양한 컨텍스트 메커니즘을 사용하여 JMS 메시지 헤더 속성에 액세스합니다. 그러나 두 메커니즘 모두 헤더 속성을 org.apache.cxf.transports.jms.context.JMSMessageHeadersType 오브젝트로 반환합니다.

42.4.1.1. 서비스에서 JMS 메시지 헤더 가져오기

WebServiceContext 개체에서 JMS 메시지 헤더 속성을 가져오려면 다음을 수행합니다.

  1. “컨텍스트 가져오기” 에 설명된 대로 컨텍스트를 가져옵니다.
  2. org.apache.cxf.transports.jms.JMSConstants.JMS_SERVER_HEADERS와 함께 메시지 컨텍스트의 get() 메서드를 사용하여 메시지 헤더를 가져옵니다.

예 42.12. “서비스 구현에서 JMS 메시지 헤더 가져오기” 서비스의 메시지 컨텍스트에서 JMS 메시지 헤더를 가져오는 코드를 표시합니다.

예 42.12. 서비스 구현에서 JMS 메시지 헤더 가져오기

import org.apache.cxf.transport.jms.JMSConstants;
import org.apache.cxf.transports.jms.context.JMSMessageHeadersType;

@WebService(serviceName = "HelloWorldService",
                           portName = "HelloWorldPort",
                           endpointInterface = "org.apache.cxf.hello_world_jms.HelloWorldPortType",
                           targetNamespace = "http://cxf.apache.org/hello_world_jms")
  public class GreeterImplTwoWayJMS implements HelloWorldPortType
  {
    @Resource
    protected WebServiceContext wsContext;
    ...

    @WebMethod
    public String greetMe(String me)
    {
      MessageContext mc = wsContext.getMessageContext();
      JMSMessageHeadersType headers = (JMSMessageHeadersType) mc.get(JMSConstants.JMS_SERVER_HEADERS);
       ...
     }
      ...
}
Copy to Clipboard Toggle word wrap
42.4.1.2. 소비자에서 JMS 메시지 헤더 속성 가져오기

JMS 전송에서 메시지가 성공적으로 검색되면 소비자의 응답 컨텍스트를 사용하여 JMS 헤더 속성을 검사할 수 있습니다. 또한 “클라이언트 수신 시간 초과” 에 설명된 대로 클라이언트가 시간 초과 전에 응답을 기다리는 시간을 설정하거나 확인할 수 있습니다. 소비자의 응답 컨텍스트에서 JMS 메시지 헤더를 가져오려면 다음을 수행합니다.

  1. “컨텍스트 가져오기” 에 설명된 대로 응답 컨텍스트를 가져옵니다.
  2. org.apache.cxf.transports.jms.JMSConstants.JMS_CLIENT_RESPONSE_HEADERS와 함께 컨텍스트의 get() 메서드를 사용하여 응답 컨텍스트에서 JMS 메시지 헤더 속성을 가져옵니다.

예 42.13. “소비자 응답 헤더에서 JMS 헤더 가져오기” 소비자의 응답 컨텍스트에서 JMS 메시지 헤더 속성을 가져오는 코드를 표시합니다.

예 42.13. 소비자 응답 헤더에서 JMS 헤더 가져오기

import org.apache.cxf.transports.jms.context.*;
// Proxy greeter initialized previously
BindingProvider  bp = (BindingProvider)greeter;
Map<String, Object> responseContext = bp.getResponseContext();
JMSMessageHeadersType responseHdr = (JMSMessageHeadersType)
                           responseContext.get(JMSConstants.JMS_CLIENT_RESPONSE_HEADERS);
...
}
Copy to Clipboard Toggle word wrap

예 42.13. “소비자 응답 헤더에서 JMS 헤더 가져오기” 의 코드는 다음을 수행합니다.

프록시를 BindingProvider로 캐스팅합니다.

응답 컨텍스트를 가져옵니다.

응답 컨텍스트에서 JMS 메시지 헤더를 검색합니다.

42.4.2. 메시지 헤더 속성 검사

42.4.2.1. 표준 JMS 헤더 속성

표 42.3. “JMS 헤더 속성” 검사할 수 있는 JMS 헤더의 표준 속성을 나열합니다.

Expand
표 42.3. JMS 헤더 속성
속성 이름속성 유형getter Method

상관 관계 ID

string

getJMSCorralationID()

전달 모드

int

getJMSDeliveryMode()

메시지 만료

long

getJMSExpiration()

메시지 ID

string

getJMSMessageID()

우선 순위

int

getJMSPriority()

재전송됨

boolean

getJMSRedlivered()

Time Stamp

long

getJMSTimeStamp()

유형

string

getJMSType()

실시간 시간

long

getTimeToLive()

42.4.2.2. 선택적 헤더 속성

또한 JMSMessageHeadersType.getProperty() 를 사용하여 JMS 헤더에 저장된 선택적 속성을 검사할 수 있습니다. 선택적 속성은 org.apache.cxf.transports.jms.context.JMSPropertyType 목록으로 반환됩니다. 선택적 속성은 이름/값 쌍으로 저장됩니다.

42.4.2.3. 예제

예 42.14. “JMS 헤더 속성 읽기” 응답 컨텍스트를 사용하여 일부 JMS 속성을 검사하는 코드를 보여줍니다.

예 42.14. JMS 헤더 속성 읽기

// JMSMessageHeadersType messageHdr retrieved previously
System.out.println("Correlation ID: "+messageHdr.getJMSCorrelationID());
System.out.println("Message Priority: "+messageHdr.getJMSPriority());
System.out.println("Redelivered: "+messageHdr.getRedelivered());

JMSPropertyType prop = null;
List<JMSPropertyType> optProps = messageHdr.getProperty();
Iterator<JMSPropertyType> iter = optProps.iterator();
while (iter.hasNext())
{
  prop = iter.next();
   System.out.println("Property name: "+prop.getName());
   System.out.println("Property value: "+prop.getValue());
}
Copy to Clipboard Toggle word wrap

예 42.14. “JMS 헤더 속성 읽기” 의 코드는 다음을 수행합니다.

메시지의 상관관계 ID 값을 출력합니다.

메시지의 priority 속성 값을 출력합니다.

메시지 재전송된 속성 값을 출력합니다.

메시지의 선택적 헤더 속성 목록을 가져옵니다.

속성 목록을 통과하는 Iterator 를 가져옵니다.

선택적 속성 목록을 반복하고 이름과 값을 출력합니다.

42.4.3. JMS 속성 설정

초록

소비자 끝점의 요청 컨텍스트를 사용하여 여러 JMS 메시지 헤더 속성 및 소비자 끝점의 시간 초과 값을 설정할 수 있습니다. 이러한 속성은 단일 호출에 유효합니다. 서비스 프록시에서 작업을 호출할 때마다 재설정해야 합니다.

서비스에서 헤더 속성을 설정할 수 없습니다.

42.4.3.1. JMS 헤더 속성

표 42.4. “설정 가능한 JMS 헤더 속성” 소비자 엔드포인트의 요청 컨텍스트를 사용하여 설정할 수 있는 JMS 헤더의 속성을 나열합니다.

Expand
표 42.4. 설정 가능한 JMS 헤더 속성
속성 이름속성 유형Setter 방법

상관 관계 ID

string

setJMSCorralationID()

전달 모드

int

setJMSDeliveryMode()

우선 순위

int

setJMSPriority()

실시간 시간

long

setTimeToLive()

이러한 속성을 설정하려면 다음을 수행합니다.

  1. org.apache.cxf.transports.jms.context.JMSMessageHeadersType 오브젝트를 생성합니다.
  2. 표 42.4. “설정 가능한 JMS 헤더 속성” 에 설명된 적절한 setter 방법을 사용하여 설정할 값을 채웁니다.
  3. org.apache.cxf.transports.jms.JMSConstants.JMS_CLIENT_REQUEST_HEADERS를 첫 번째 인수로 사용하고 새 JMSMessageHeadersType 오브젝트를 두 번째 인수로 사용하여 요청 컨텍스트의 put() 메서드를 호출하여 값을 요청 컨텍스트로 설정합니다.
42.4.3.2. 선택적 JMS 헤더 속성

선택적 속성을 JMS 헤더에 설정할 수도 있습니다. 선택적 JMS 헤더 속성은 다른 JMS 헤더 속성을 설정하는 데 사용되는 JMSMessageHeadersType 오브젝트에 저장됩니다. org.apache.cxf.transports.jms.context.JMSPropertyType 개체를 포함하는 List 오브젝트로 저장됩니다. JMS 헤더에 선택적 속성을 추가하려면 다음을 수행합니다.

  1. JMSPropertyType 오브젝트를 생성합니다.
  2. setName() 을 사용하여 속성의 name 필드를 설정합니다.
  3. setValue() 를 사용하여 속성의 value 필드를 설정합니다.
  4. JMSMessageHeadersType.getProperty().add(JMSPropertyType) 를 사용하여 JMS 메시지 헤더에 속성을 추가합니다.
  5. 모든 속성이 메시지 헤더에 추가될 때까지 절차를 반복합니다.
42.4.3.3. 클라이언트 수신 시간 초과

JMS 헤더 속성 외에도 소비자 엔드포인트가 시간 초과되기 전에 응답을 기다리는 시간을 설정할 수 있습니다. org.apache.cxf.transports.jms.JMS_CLIENT_RECEIVE_TIMEOUT을 사용하여 요청 컨텍스트의 put() 메서드를 호출하고 첫 번째 인수로 소비자가 두 번째 인수로 대기하려는 시간(밀리초)을 나타내는 시간을 설정합니다.

42.4.3.4. 예제

예 42.15. “요청 컨텍스트를 사용하여 JMS 속성 설정” 요청 컨텍스트를 사용하여 일부 JMS 속성을 설정하는 코드를 보여줍니다.

예 42.15. 요청 컨텍스트를 사용하여 JMS 속성 설정

import org.apache.cxf.transports.jms.context.*;
 // Proxy greeter initialized previously
InvocationHandler handler = Proxy.getInvocationHandler(greeter);

BindingProvider bp= null;
if (handler instanceof BindingProvider)
{
  bp = (BindingProvider)handler;
  Map<String, Object> requestContext = bp.getRequestContext();

  JMSMessageHeadersType requestHdr = new JMSMessageHeadersType();
  requestHdr.setJMSCorrelationID("WithBob");
  requestHdr.setJMSExpiration(3600000L);


  JMSPropertyType prop = new JMSPropertyType;
  prop.setName("MyProperty");
  prop.setValue("Bluebird");
  requestHdr.getProperty().add(prop);

  requestContext.put(JMSConstants.CLIENT_REQUEST_HEADERS, requestHdr);

  requestContext.put(JMSConstants.CLIENT_RECEIVE_TIMEOUT, new Long(1000));
}
Copy to Clipboard Toggle word wrap

예 42.15. “요청 컨텍스트를 사용하여 JMS 속성 설정” 의 코드는 다음을 수행합니다.

변경하려는 JMS 속성이 있는 프록시에 대한 InvocationHandler 를 가져옵니다.

InvocationHandlerBindingProvider 인지 확인합니다.

반환된 InvocationHandler 오브젝트를 BindingProvider 오브젝트로 캐스팅하여 요청 컨텍스트를 검색합니다.

요청 컨텍스트를 가져옵니다.

새 메시지 헤더 값을 유지하기 위해 JMSMessageHeadersType 오브젝트를 생성합니다.

Correlation ID를 설정합니다.

Expiration 속성을 60분으로 설정합니다.

JMSPropertyType 오브젝트를 생성합니다.

선택적 속성의 값을 설정합니다.

메시지 헤더에 선택적 속성을 추가합니다.

JMS 메시지 헤더 값을 요청 컨텍스트로 설정합니다.

클라이언트 수신 시간 초과 속성을 1초로 설정합니다.

43장. 처리기 작성

초록

Cryostat-WS는 메시지 처리 모듈을 애플리케이션에 추가하기 위한 유연한 플러그인 프레임워크를 제공합니다. 처리기라고 하는 이러한 모듈은 애플리케이션 수준 코드와 독립적이며 낮은 수준의 메시지 처리 기능을 제공할 수 있습니다.

43.1. 처리기: 소개

43.1.1. 개요

서비스 프록시가 서비스에서 작업을 호출하면 작업의 매개 변수가 메시지로 빌드되고 유선에 배치되는 Apache CXF로 전달됩니다. 서비스에서 메시지를 수신하면 Apache CXF에서 메시지를 읽고 메시지를 재구성한 다음 작업 매개 변수를 작업 코드로 전달합니다. 애플리케이션 코드가 요청 처리를 완료하면 응답 메시지는 요청을 시작한 서비스 프록시로 이동하는 유사한 이벤트 체인을 거칩니다. 이는 그림 43.1. “메시지 교환 경로” 에 표시됩니다.

그림 43.1. 메시지 교환 경로

클라이언트와 서버 간의 메시지 교환 경로

Cryostat-WS는 애플리케이션 수준 코드와 네트워크 간에 메시지 데이터를 조작하기 위한 메커니즘을 정의합니다. 예를 들어, 오픈 네트워크를 통해 전달되는 메시지 데이터가 독점 암호화 메커니즘을 사용하여 암호화되도록 할 수 있습니다. 데이터를 암호화하고 해독하는 경우, Cryostat-WS 핸들러를 작성할 수 있습니다. 그런 다음 모든 클라이언트 및 서버의 메시지 처리 체인에 처리기를 삽입할 수 있습니다.

그림 43.2. “처리기를 사용한 메시지 교환 경로” 에 표시된 대로 처리기는 애플리케이션 수준 코드와 메시지를 네트워크에 배치하는 전송 코드 간에 통과하는 체인에 배치됩니다.

그림 43.2. 처리기를 사용한 메시지 교환 경로

처리기는 전송과 애플리케이션 계층 간의 메시지 교환 경로에 배치됩니다.

43.1.2. 처리기 유형

Cryostat-WS 사양은 다음 두 가지 기본 처리기 유형을 정의합니다.

  • 논리 처리기 논리 처리기는 메시지 페이로드와 메시지 컨텍스트에 저장된 속성을 처리할 수 있습니다. 예를 들어 애플리케이션에서 순수 XML 메시지를 사용하는 경우 논리 처리기는 전체 메시지에 액세스할 수 있습니다. 애플리케이션에서 Cryostat 메시지를 사용하는 경우 논리 처리기는 Cryostat 본문의 콘텐츠에 액세스할 수 있습니다. 메시지 컨텍스트에 배치된 경우를 제외하고 Cryostat 헤더 또는 모든 첨부 파일에 액세스할 수 없습니다.

    논리 처리기는 처리기 체인의 애플리케이션 코드에 가장 근접하게 배치됩니다. 즉, 메시지가 애플리케이션 코드에서 전송으로 전달될 때 먼저 실행됩니다. 네트워크에서 메시지를 수신하고 애플리케이션 코드로 다시 전달되면 논리 처리기가 마지막으로 실행됩니다.

  • 프로토콜 처리기 프로토콜 처리기는 네트워크에서 수신된 전체 메시지와 메시지 컨텍스트에 저장된 속성을 처리할 수 있습니다. 예를 들어 애플리케이션에서 Cryostat 메시지를 사용하는 경우 프로토콜 처리기는 Cryostat 본문, Cryostat 헤더 및 모든 첨부 파일의 콘텐츠에 액세스할 수 있습니다.

    프로토콜 처리기는 처리기 체인의 전송에 가장 근접하게 배치됩니다. 즉, 네트워크에서 메시지를 수신할 때 먼저 실행됩니다. 메시지가 애플리케이션 코드에서 네트워크로 전송되면 프로토콜 처리기가 마지막으로 실행됩니다.

    참고

    Apache CXF에서 지원하는 유일한 프로토콜 처리기는 Cryostat에 따라 다릅니다.

43.1.3. 처리기 구현

두 처리기 유형의 차이점은 매우 미묘하며 공통 기본 인터페이스를 공유합니다. 논리 처리기와 프로토콜 처리기는 일반적인 부모로 인해 다음을 포함하여 구현해야 하는 여러 메서드를 공유합니다.

  • handleMessage() handleMessage() 메서드는 모든 처리기의 중앙 메서드입니다. 정상적인 메시지를 처리하는 방법입니다.
  • handleFault() handleFault() 는 오류 메시지를 처리하는 방법입니다.
  • close() close() 는 메시지가 체인의 끝에 도달했을 때 처리기 체인의 모든 실행 처리기에서 호출됩니다. 메시지 처리 중에 사용되는 모든 리소스를 정리하는 데 사용됩니다.

논리 처리기의 구현과 프로토콜 처리기 구현의 차이점은 다음과 같습니다.

  • 구현되는 특정 인터페이스

    모든 처리기는 Handler 인터페이스에서 파생되는 인터페이스를 구현합니다. 논리 처리기는 LogicalHandler 인터페이스를 구현합니다. 프로토콜 처리기는 Handler 인터페이스의 프로토콜별 확장을 구현합니다. 예를 들어 Cryostat 처리기는 CryostatHandler 인터페이스를 구현합니다.

  • 처리기에서 사용할 수 있는 정보의 양

    프로토콜 처리기는 메시지의 내용과 메시지 콘텐츠와 함께 패키지된 모든 프로토콜 관련 정보에 액세스할 수 있습니다. 논리 처리기는 메시지의 콘텐츠에만 액세스할 수 있습니다. 논리 처리기에는 프로토콜 세부 정보가 없습니다.

43.1.4. 애플리케이션에 처리기 추가

애플리케이션에 처리기를 추가하려면 다음을 수행해야 합니다.

  1. 처리기를 서비스 공급자, 소비자 또는 둘 다에서 사용할지 여부를 확인합니다.
  2. 작업에 가장 적합한 핸들러 유형을 결정합니다.
  3. 적절한 인터페이스를 구현합니다.

    논리 처리기를 구현하려면 43.2절. “논리 처리기 구현” 을 참조하십시오.

    프로토콜 처리기를 구현하려면 43.4절. “프로토콜 처리기 구현” 에서 참조하십시오.

  4. 처리기를 사용하도록 끝점을 구성합니다. 43.10절. “Handlers를 사용하도록 끝점 구성”을 참조하십시오.

43.2. 논리 처리기 구현

43.2.1. 개요

논리 처리기는 javax.xml.ws.handler.LogicalHandler 인터페이스를 구현합니다. 예 43.1. “LogicalHandler Synopsis” 에 표시된 LogicalHandler 인터페이스는 LogicalMessageContext 오브젝트를 handleMessage() 메서드 및 handleFault() 메서드에 전달합니다. 컨텍스트 오브젝트는 메시지의 본문 과 메시지 교환의 컨텍스트로 설정된 모든 속성에 대한 액세스를 제공합니다.

예 43.1. LogicalHandler Synopsis

public interface LogicalHandler extends Handler
{
  boolean handleMessage(LogicalMessageContext context);
  boolean handleFault(LogicalMessageContext context);
  void close(LogicalMessageContext context);
}
Copy to Clipboard Toggle word wrap

43.2.2. 절차

논리 핸드백을 구현하려면 다음을 수행합니다.

  1. 처리기에 필요한 모든 43.6절. “처리기 초기화” 논리를 구현합니다.
  2. 43.3절. “논리 처리기에서 메시지 처리” 논리를 구현합니다.
  3. 43.7절. “오류 메시지 처리” 논리를 구현합니다.
  4. 완료되면 처리기에 대한 논리를 43.8절. “처리기 닫기” 에 구현합니다.
  5. 43.9절. “처리기 해제” 에 대한 모든 논리가 제거되기 전에 처리기의 리소스를 구현합니다.

43.3. 논리 처리기에서 메시지 처리

43.3.1. 개요

일반적인 메시지 처리는 handleMessage() 메서드에서 처리합니다.

handleMessage() 메서드는 메시지 본문에 대한 액세스 및 메시지 컨텍스트에 저장된 모든 속성에 대한 액세스를 제공하는 LogicalMessageContext 개체를 수신합니다.

handleMessage() 메서드는 메시지 처리를 계속 수행하는 방법에 따라 true 또는 false를 반환합니다. 또한 예외를 throw할 수도 있습니다.

43.3.2. 메시지 데이터 가져오기

논리 메시지 처리기로 전달된 LogicalMessageContext 개체를 사용하면 컨텍스트의 getMessage() 메서드를 사용하여 메시지 본문에 액세스할 수 있습니다. 예 43.2. “논리 처리기에서 메시지 페이로드를 가져오는 방법” 에 표시된 getMessage() 메서드는 메시지 페이로드를 LogicalMessage 오브젝트로 반환합니다.

예 43.2. 논리 처리기에서 메시지 페이로드를 가져오는 방법

LogicalMessagegetMessage

LogicalMessage 개체가 있으면 이를 사용하여 메시지 본문을 조작할 수 있습니다. 예 43.3. “논리 메시지 홀더” 에 표시된 논리 메시지 인터페이스에는 실제 메시지 본문으로 작업하기 위한 getECDSA 및 set zone이 있습니다.

예 43.3. 논리 메시지 홀더

LogicalMessageSourcegetPayloadObjectgetPayload>-<BContext컨텍스트setPayloadObjectpayloadCryostatBContextcontextsetPayloadSourcepayload

중요

메시지 페이로드의 내용은 사용 중인 바인딩 유형에 따라 결정됩니다. Cryostat 바인딩은 메시지의 Cryostat 본문에만 액세스할 수 있습니다. XML 바인딩을 사용하면 전체 메시지 본문에 액세스할 수 있습니다.

43.3.3. 메시지 본문을 XML 개체로 사용하여 작업

논리 메시지의 한 쌍과 setexports는 javax.xml.transform.dom.DOMSource 개체로 메시지 페이로드와 함께 작동합니다.

매개 변수가 없는 getPayload() 메서드는 message payload를 192.0.2. Source 개체로 반환합니다. 반환된 오브젝트는 실제 메시지 페이로드입니다. 반환된 오브젝트의 변경 사항은 메시지 본문을 즉시 변경합니다.

단일 Source 개체를 사용하는 setPayload() 메서드를 사용하여 message의 본문을 192.0.2.Source 개체로 교체할 수 있습니다.

43.3.4. 메시지 본문을 사용하여 오브젝트로 작업

다른 한 쌍의 getter 및 setter를 사용하면 메시지 페이로드를 a CryostatB 오브젝트로 사용할 수 있습니다. 메시지 페이로드를 CryostatB 오브젝트로 변환하는 데 CryostatBContext 오브젝트를 사용합니다.

CryostatB 오브젝트를 사용하려면 다음을 수행합니다.

  1. 메시지 본문에서 데이터 유형을 관리할 수 있는 Cryostat BContext 개체를 가져옵니다.

    Cryostat BContext 오브젝트 생성에 대한 자세한 내용은 39장. A Cryo statBContext 오브젝트 사용 을 참조하십시오.

  2. 예 43.4. “메시지 본문을 사용하여 메시지 본문 가져오기” 에 표시된 대로 메시지 본문을 가져옵니다.

    예 43.4. 메시지 본문을 사용하여 메시지 본문 가져오기

    JAXBContext jaxbc = JAXBContext(myObjectFactory.class);
    Object body = message.getPayload(jaxbc);
    Copy to Clipboard Toggle word wrap
  3. 반환된 오브젝트를 적절한 유형으로 캐스팅합니다.
  4. 필요에 따라 메시지 본문을 조작합니다.
  5. 예 43.5. “CryostatB 오브젝트를 사용하여 메시지 본문 업데이트” 에 표시된 대로 업데이트된 메시지 본문을 컨텍스트에 다시 배치합니다.

    예 43.5. CryostatB 오브젝트를 사용하여 메시지 본문 업데이트

    message.setPayload(body, jaxbc);
    Copy to Clipboard Toggle word wrap

43.3.5. 컨텍스트 속성 작업

논리 처리기에 전달된 논리 메시지 컨텍스트는 애플리케이션 메시지 컨텍스트의 인스턴스이며 저장된 모든 속성에 액세스할 수 있습니다. 처리기는 APPLICATION 범위와 HANDLER 범위 모두에서 속성에 액세스할 수 있습니다.

애플리케이션의 메시지 컨텍스트와 마찬가지로 논리 메시지 컨텍스트는 Java 맵의 하위 클래스입니다. 컨텍스트에 저장된 속성에 액세스하려면 Map 인터페이스에서 상속된 get() 메서드 및 put() 메서드를 사용합니다.

기본적으로 논리 처리기 내에서 메시지 컨텍스트에서 설정한 모든 속성에는 HANDLER의 범위가 할당됩니다.By default, any properties you set in the message context from inside a logical handler are assigned a scope of HANDLER. 애플리케이션 코드가 속성에 액세스하려면 컨텍스트의 setScope() 메서드를 사용하여 속성 범위를 명시적으로 APPLICATION으로 설정해야 합니다.

메시지 컨텍스트에서 속성 사용에 대한 자세한 내용은 42.1절. “컨텍스트 이해” 을 참조하십시오.

43.3.6. 메시지의 방향 확인Determining the direction of the message

메시지가 처리기 체인을 통과하는 방향을 아는 것이 종종 중요합니다. 예를 들어 들어오는 요청에서 보안 토큰을 검색하고 발신 응답에 보안 토큰을 연결해야 합니다.

메시지의 방향은 메시지 컨텍스트의 아웃바운드 메시지 속성에 저장됩니다. 예 43.6. “ESP 메시지 컨텍스트에서 메시지 방향 가져오기” 에 표시된 대로 MessageContext.MESSAGE_OUTBOUND_PROPERTY 키를 사용하여 메시지 컨텍스트에서 아웃바운드 메시지 속성을 검색합니다.

예 43.6. ESP 메시지 컨텍스트에서 메시지 방향 가져오기

Boolean outbound;
outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
Copy to Clipboard Toggle word wrap

속성은 부울 오브젝트로 저장됩니다. 개체의 booleanValue() 메서드를 사용하여 속성의 값을 확인할 수 있습니다. 속성이 true로 설정되면 메시지는 아웃바운드입니다. 속성이 false로 설정된 경우 메시지는 인바운드입니다.

43.3.7. 반환 값 확인

handleMessage() 메서드가 메시지 처리를 완료하는 방법은 메시지 처리가 진행되는 방식에 직접적인 영향을 미칩니다. 다음 작업 중 하나를 수행하여 완료할 수 있습니다.

  1. 메시지 처리가 정상적으로 진행되어야 하는 Apache CXF 런타임으로 true- returnsing true 신호를 반환합니다. 다음 처리기(있는 경우)에 해당 handleMessage() 가 호출됩니다.
  2. 일반 메시지 처리가 중지되어야 하는 Apache CXF 런타임으로 false- return false 신호를 반환합니다. 런타임이 진행되는 방법은 현재 메시지에 사용되는 메시지 교환 패턴에 따라 달라집니다.

    요청-응답 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    1. 메시지 처리 방향이 취소됩니다.

      예를 들어 서비스 공급자가 요청을 처리하는 경우 메시지는 서비스의 구현 오브젝트에 대한 진행을 중지합니다. 대신 요청을 시작한 소비자로의 반환에 대한 바인딩으로 다시 전송됩니다.

    2. 처리기 체인에 상주하는 모든 메시지 처리기는 체인에 상주하는 순서대로 호출되는 handleMessage() 메서드가 있습니다.
    3. 메시지가 처리기 체인의 끝에 도달하면 디스패치됩니다.

      단방향 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    4. 메시지 처리가 중지됩니다.
    5. 이전에 호출한 모든 메시지 처리기에는 Close() 메서드가 호출됩니다.
    6. 메시지가 발송됩니다.
  3. ProtocolException 예외를 throw합니다. ProtocolException 예외 또는 이 예외의 서브 클래스를 사용하면 메시지 처리가 중단되는 Apache CXF 런타임이 시작됩니다. 런타임이 진행되는 방법은 현재 메시지에 사용되는 메시지 교환 패턴에 따라 달라집니다.

    요청-응답 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    1. 처리기에서 fault 메시지를 아직 생성하지 않은 경우 런타임은 메시지를 fault 메시지로 래핑합니다.
    2. 메시지 처리 방향이 취소됩니다.

      예를 들어 서비스 공급자가 요청을 처리하는 경우 메시지는 서비스의 구현 오브젝트에 대한 진행을 중지합니다. 대신 요청을 시작한 소비자로의 반환에 대한 바인딩으로 다시 전송됩니다.

    3. 처리기 체인에 새 처리 방향에 상주하는 모든 메시지 처리기는 체인에 상주하는 순서대로 호출되는 handleFault() 메서드가 있습니다.
    4. 오류 메시지가 처리기 체인의 끝에 도달하면 디스패치됩니다.

      단방향 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    5. 처리기에서 fault 메시지를 아직 생성하지 않은 경우 런타임은 메시지를 fault 메시지로 래핑합니다.
    6. 메시지 처리가 중지됩니다.
    7. 이전에 호출한 모든 메시지 처리기에는 Close() 메서드가 호출됩니다.
    8. 오류 메시지가 발송됩니다.
  4. 다른 런타임 예외를 발생 - ProtocolException 예외 이외의 런타임 예외를 검색하면 메시지 처리가 중지되는 Apache CXF 런타임이 신호를 보냅니다. 이전에 호출한 모든 메시지 처리기에는 Close() 메서드가 호출되고 예외가 디스패치됩니다. 메시지가 요청-응답 메시지 교환의 일부인 경우 예외가 처리되어 요청을 시작한 소비자에게 반환됩니다.

43.3.8. 예제

예 43.7. “논리 메시지 처리기 메시지 처리” 서비스 소비자가 사용하는 논리 메시지 처리기에 대한 handleMessage() 메시지의 구현을 보여줍니다. 요청을 서비스 공급자로 보내기 전에 처리합니다.

예 43.7. 논리 메시지 처리기 메시지 처리

public class SmallNumberHandler implements LogicalHandler<LogicalMessageContext>
{
    public final boolean handleMessage(LogicalMessageContext messageContext)
    {
        try
        {
            boolean outbound = (Boolean)messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

            if (outbound)
            {
                LogicalMessage msg = messageContext.getMessage();

                JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
                Object payload = msg.getPayload(jaxbContext);
                if (payload instanceof JAXBElement)
                {
                    payload = ((JAXBElement)payload).getValue();
                }

                if (payload instanceof AddNumbers)
                {
                    AddNumbers req = (AddNumbers)payload;

                    int a = req.getArg0();
                    int b = req.getArg1();
                    int answer = a + b;

                    if (answer < 20)
                    {
                      AddNumbersResponse resp = new AddNumbersResponse();
                      resp.setReturn(answer);
                      msg.setPayload(new ObjectFactory().createAddNumbersResponse(resp),
                                                      jaxbContext);

                      return false;
                    }
                }
                else
                {
                   throw new WebServiceException("Bad Request");
                }
            }
            return true;
        }
        catch (JAXBException ex)
        {
            throw new ProtocolException(ex);
        }
    }
...
}
Copy to Clipboard Toggle word wrap

예 43.7. “논리 메시지 처리기 메시지 처리” 의 코드는 다음을 수행합니다.

메시지가 아웃바운드 요청인지 확인합니다.

메시지가 아웃바운드 요청인 경우 처리기는 추가 메시지 처리를 수행합니다.

메시지 컨텍스트에서 메시지 페이로드의 LogicalMessage 표현을 가져옵니다.

실제 메시지 페이로드를 가져옵니다.

요청이 올바른 유형인지 확인합니다.

이 경우 처리기는 메시지를 계속 처리합니다.

합계 값을 확인합니다.

임계값이 20 미만이면 응답을 작성하고 클라이언트에 반환합니다.

응답을 빌드합니다.

false를 반환하여 메시지 처리를 중지하고 클라이언트에 대한 응답을 반환합니다.

메시지가 올바른 유형이 아닌 경우 런타임 예외를 throw합니다.

이 예외는 클라이언트에 반환됩니다.

메시지가 인바운드 응답이거나 합계가 임계값을 충족하지 않는 경우 true를 반환합니다.

메시지 처리가 정상적으로 계속됩니다.

CryostatB marshalling 오류가 발생하는 경우 ProtocolException이 발생합니다.

예외는 현재 처리기와 클라이언트 간의 처리기에서 처리한 후 클라이언트에 다시 전달됩니다.

43.4. 프로토콜 처리기 구현

43.4.1. 개요

프로토콜 처리기는 사용 중인 프로토콜에 따라 다릅니다. Apache CXF는 Cryostat-WS에서 지정한 대로 Cryostat 프로토콜 처리기를 제공합니다. Cryostat 프로토콜 처리기는 javax.xml.ws.handler.soap.SOAPHandler 인터페이스를 구현합니다.

예 43.8. “CryostatHandler Synopsis” 에 표시된 CryostatHandler 인터페이스는 message에 대한 액세스를 Cryostat Message 오브젝트로 제공하는 Cryostat 특정 메시지 컨텍스트를 사용합니다. 또한 Cryostat 헤더에 액세스할 수 있습니다.

예 43.8. CryostatHandler Synopsis

public interface SOAPHandler extends Handler
{
  boolean handleMessage(SOAPMessageContext context);
  boolean handleFault(SOAPMessageContext context);
  void close(SOAPMessageContext context);
  Set<QName> getHeaders()
}
Copy to Clipboard Toggle word wrap

Cryostat 특정 메시지 컨텍스트를 사용하는 것 외에도 Cryostat 프로토콜 처리기에서는 getHeaders() 라는 추가 메서드를 구현해야 합니다. 이 추가 메서드는 처리기에서 처리할 수 있는 헤더 블록의 QNames를 반환합니다.

43.4.2. 절차

논리 핸드퍼를 구현하려면 다음을 수행합니다.

  1. 처리기에 필요한 모든 43.6절. “처리기 초기화” 논리를 구현합니다.
  2. 43.5절. “Cryostat 처리기에서 메시지 처리” 논리를 구현합니다.
  3. 43.7절. “오류 메시지 처리” 논리를 구현합니다.
  4. getHeaders() 메서드를 구현합니다.
  5. 완료되면 처리기에 대한 논리를 43.8절. “처리기 닫기” 에 구현합니다.
  6. 43.9절. “처리기 해제” 에 대한 모든 논리가 제거되기 전에 처리기의 리소스를 구현합니다.

43.4.3. getHeaders() 메서드 구현

예 43.9. “Cryo statHander.getHeaders() 메서드” 에 표시된 getHeaders() 는 Apache CXF 런타임에서 처리기가 처리하는 Loki 헤더를 알립니다. 처리기에서 이해할 수 있는 각 Cryostat 헤더의 외부 요소의 QNames를 반환합니다.

예 43.9. Cryo statHander.getHeaders() 메서드

set<QName&gt;getHeaders

대부분의 경우 null을 반환하는 것으로 충분합니다. 그러나 애플리케이션에서 ESP 헤더의 mustUnderstand 특성을 사용하는 경우 애플리케이션의 Cryostat 처리기에서 이해하는 헤더를 지정하는 것이 중요합니다. 런타임은 등록된 모든 핸들러가 mustUnderstand 특성이 true 로 설정된 헤더 목록에 대해 이해하는 Cryostat 헤더 집합을 확인합니다. 플래그가 지정된 헤더 중 하나라도 이해된 헤더 목록에 없는 경우 런타임은 메시지를 거부하고 CloudEvent가 예외를 이해해야 합니다.

43.5. Cryostat 처리기에서 메시지 처리

43.5.1. 개요

일반적인 메시지 처리는 handleMessage() 메서드에서 처리합니다.

handleMessage() 메서드는 메시지 본문에 대한 액세스를 제공하고 message와 연결된 Cryostat 헤더로 message 본문에 대한 액세스를 제공하는 Cryostat Message Context 오브젝트를 수신합니다. 또한 컨텍스트는 메시지 컨텍스트에 저장된 속성에 대한 액세스를 제공합니다.In addition, the context provides access to any properties stored in the message context.

handleMessage() 메서드는 메시지 처리를 계속 수행하는 방법에 따라 true 또는 false를 반환합니다. 또한 예외를 throw할 수도 있습니다.

43.5.2. 메시지 본문으로 작업

Cryostat 메시지 컨텍스트의 getMessage() 메서드를 사용하여 Cryostat 메시지를 가져올 수 있습니다. 메시지를 라이브 Cryostat Message 오브젝트로 반환합니다. 처리기의 메시지에 대한 모든 변경 사항은 컨텍스트에 저장된 메시지에 자동으로 반영됩니다.

기존 메시지를 새 메시지로 교체하려면 컨텍스트의 setMessage() 메서드를 사용할 수 있습니다. setMessage() 메서드는 Cryostat Message 오브젝트 를 사용합니다.

43.5.3. Cryostat 헤더 가져오기

Cryostat Message 개체의 getHeader() 메서드를 사용하여 Cryostat 메시지 의 헤더에 액세스할 수 있습니다. 이렇게 하면 처리하려는 헤더 요소를 찾기 위해 검사해야 하는 Cryostat Header 개체로 header 헤더가 반환됩니다.

Cryostat 메시지 컨텍스트는 예 43.10. “Cryo statMessageContext.getHeaders() 메서드” 에 표시된 getHeaders() 메서드를 제공하여 지정된 Cryostat 헤더에 대해 CryostatB 개체가 포함된 배열을 반환합니다.

예 43.10. Cryo statMessageContext.getHeaders() 메서드

Ojbect[]getHeadersQName헤더>.<BContext컨텍스트부울allRoles

해당 요소의 QName을 사용하여 헤더를 지정합니다. allRoles 매개변수를 false로 설정하여 반환된 헤더를 추가로 제한할 수 있습니다. 이는 활성 Cryostat 역할에 적용할 수 있는 Cryostat 헤더만 반환하도록 런타임에 지시합니다.

헤더가 없는 경우 메서드는 빈 배열을 반환합니다.

Cryostat BContext 오브젝트 인스턴스화에 대한 자세한 내용은 39장. A Cryo statBContext 오브젝트 사용 에서 참조하십시오.

43.5.4. 컨텍스트 속성 작업

논리 처리기에 전달된 Cryostat 메시지 컨텍스트는 애플리케이션 메시지 컨텍스트의 인스턴스이며 이 컨텍스트에 저장된 모든 속성에 액세스할 수 있습니다. 처리기는 APPLICATION 범위와 Handler 범위 모두에서 속성에 액세스할 수 있습니다.

애플리케이션의 메시지 컨텍스트와 마찬가지로 Cryostat 메시지 컨텍스트는 Java 맵의 하위 클래스입니다. 컨텍스트에 저장된 속성에 액세스하려면 Map 인터페이스에서 상속된 get() 메서드 및 put() 메서드를 사용합니다.

기본적으로 논리 처리기 내에서 컨텍스트에서 설정한 모든 속성에는 HANDLER의 범위가 할당됩니다.By default, any properties you set in the context from inside a logical handler will be assigned a scope of HANDLER. 애플리케이션 코드가 속성에 액세스하려면 컨텍스트의 setScope() 메서드를 사용하여 속성 범위를 명시적으로 APPLICATION으로 설정해야 합니다.

메시지 컨텍스트에서 속성 사용에 대한 자세한 내용은 42.1절. “컨텍스트 이해” 을 참조하십시오.

43.5.5. 메시지의 방향 확인Determining the direction of the message

메시지가 처리기 체인을 통과하는 방향을 아는 것이 종종 중요합니다. 예를 들어 발신 메시지에 헤더를 추가하고 들어오는 메시지에서 헤더를 제거하려고 합니다.

메시지의 방향은 메시지 컨텍스트의 아웃바운드 메시지 속성에 저장됩니다. 예 43.11. “ESP 메시지 컨텍스트에서 메시지 방향 가져오기” 에 표시된 대로 MessageContext.MESSAGE_OUTBOUND_PROPERTY 키를 사용하여 메시지 컨텍스트에서 아웃바운드 메시지 속성을 검색합니다.

예 43.11. ESP 메시지 컨텍스트에서 메시지 방향 가져오기

Boolean outbound;
outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
Copy to Clipboard Toggle word wrap

속성은 부울 오브젝트로 저장됩니다. 개체의 booleanValue() 메서드를 사용하여 속성의 값을 확인할 수 있습니다. 속성이 true로 설정되면 메시지는 아웃바운드입니다. 속성이 false로 설정된 경우 메시지는 인바운드입니다.

43.5.6. 반환 값 확인

handleMessage() 메서드가 메시지 처리를 완료하는 방법은 메시지 처리가 진행되는 방식에 직접적인 영향을 미칩니다. 다음 작업 중 하나를 수행하여 완료할 수 있습니다.

  1. 메시지 처리가 정상적으로 진행되어야 하는 Apache CXF 런타임으로 true- returnsing true 신호를 반환합니다. 다음 처리기(있는 경우)에 해당 handleMessage() 가 호출됩니다.
  2. 일반적인 메시지 처리가 중지되는 Apache CXF 런타임으로 false-반복 신호를 반환합니다. 런타임이 진행되는 방법은 현재 메시지에 사용되는 메시지 교환 패턴에 따라 달라집니다.

    요청-응답 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    1. 메시지 처리 방향이 취소됩니다.

      예를 들어 서비스 공급자가 요청을 처리하는 경우 메시지는 서비스의 구현 오브젝트에 대한 진행을 중지합니다. 대신 요청을 시작한 소비자로의 반환을 위해 바인딩으로 다시 전송됩니다.

    2. 처리기 체인에 상주하는 모든 메시지 처리기는 체인에 상주하는 순서대로 호출되는 handleMessage() 메서드가 있습니다.
    3. 메시지가 처리기 체인의 끝에 도달하면 디스패치됩니다.

      단방향 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    4. 메시지 처리가 중지됩니다.
    5. 이전에 호출한 모든 메시지 처리기에는 Close() 메서드가 호출됩니다.
    6. 메시지가 발송됩니다.
  3. ProtocolException 예외를 throw - ProtocolException 예외 또는 이 예외의 하위 클래스를 발생시켜 메시지 처리를 중단하는 Apache CXF 런타임을 시작하라는 신호를 보냅니다. 런타임이 진행되는 방법은 현재 메시지에 사용되는 메시지 교환 패턴에 따라 달라집니다.

    요청-응답 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    1. 처리기에서 fault 메시지를 아직 생성하지 않은 경우 런타임은 메시지를 fault 메시지로 래핑합니다.
    2. 메시지 처리 방향이 취소됩니다.

      예를 들어 서비스 공급자가 요청을 처리하는 경우 메시지는 서비스의 구현 오브젝트에 대한 진행을 중지합니다. 요청을 시작한 소비자로의 반환에 대한 바인딩으로 다시 전송됩니다.

    3. 처리기 체인에 새 처리 방향에 상주하는 모든 메시지 처리기는 체인에 상주하는 순서대로 호출되는 handleFault() 메서드가 있습니다.
    4. 오류 메시지가 처리기 체인의 끝에 도달하면 디스패치됩니다.

      단방향 메시지 교환의 경우 다음과 같은 일이 발생합니다.

    5. 처리기에서 fault 메시지를 아직 생성하지 않은 경우 런타임은 메시지를 fault 메시지로 래핑합니다.
    6. 메시지 처리가 중지됩니다.
    7. 이전에 호출한 모든 메시지 처리기에는 Close() 메서드가 호출됩니다.
    8. 오류 메시지가 발송됩니다.
  4. 다른 런타임 예외를 발생 - ProtocolException 예외 이외의 런타임 예외를 검색하면 메시지 처리가 중지되는 Apache CXF 런타임이 신호를 보냅니다. 이전에 호출한 모든 메시지 처리기에는 Close() 메서드가 호출되고 예외가 디스패치됩니다. 메시지가 요청-응답 메시지 교환의 일부인 경우 예외가 디스패치되어 요청을 시작한 소비자로 반환됩니다.

43.5.7. 예제

예 43.12. “Cryostat 처리기에서 메시지 처리” shows a handleMessage() implementation that print the message to the screen.

예 43.12. Cryostat 처리기에서 메시지 처리

public boolean handleMessage(SOAPMessageContext smc)
{
  PrintStream out;

  Boolean outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

  if (outbound.booleanValue())
  {
    out.println("\nOutbound message:");
  }
  else
  {
    out.println("\nInbound message:");
  }

  SOAPMessage message = smc.getMessage();

  message.writeTo(out);
  out.println();

  return true;
}
Copy to Clipboard Toggle word wrap

예 43.12. “Cryostat 처리기에서 메시지 처리” 의 코드는 다음을 수행합니다.

메시지 컨텍스트에서 아웃바운드 속성을 검색합니다.

메시지 방향을 테스트하고 적절한 메시지를 출력합니다.

컨텍스트에서 Cryostat 메시지를 검색합니다.

메시지를 콘솔에 출력합니다.

43.6. 처리기 초기화

43.6.1. 개요

런타임에서 처리기의 인스턴스를 생성할 때 핸드퍼에서 메시지를 처리하는 데 필요한 모든 리소스를 생성합니다. 처리기의 생성자에 이 작업을 수행하기 위해 모든 논리를 배치할 수 있지만 가장 적합한 위치가 아닐 수도 있습니다. 처리기 프레임워크는 처리기를 인스턴스화할 때 여러 선택적 단계를 수행합니다. 선택적 단계에서 실행할 리소스 주입 및 기타 초기화 논리를 추가할 수 있습니다.

처리기에 초기화 메서드를 제공할 필요는 없습니다.

43.6.2. 초기화 순서

Apache CXF 런타임은 다음과 같은 방식으로 처리기를 초기화합니다.

  1. 처리기의 생성자가 호출됩니다.
  2. @Resource 주석으로 지정된 리소스가 삽입됩니다.
  3. @PostConstruct 주석으로 데코레이팅된 메서드는 호출됩니다.

    참고

    @PostConstruct 주석으로 데코레이팅된 메서드에는 void 반환 유형이 있어야 하며 매개변수가 없습니다.

  4. 처리기는 Ready 상태에 있습니다.

43.7. 오류 메시지 처리

43.7.1. 개요

처리기는 메시지 처리 중에 ProtocolException 예외가 throw될 때 오류 메시지를 처리하는 데 handleFault() 메서드를 사용합니다.

handleFault() 메서드는 처리기 유형에 따라 LogicalMessageContext 개체 또는 CryostatMessageContext 개체를 수신합니다. 수신된 컨텍스트는 처리기의 메시지 페이로드에 대한 구현 액세스를 제공합니다.

handleFault() 메서드는 오류 메시지 처리를 수행하는 방법에 따라 true 또는 false를 반환합니다. 또한 예외를 throw할 수도 있습니다.

43.7.2. 메시지 페이로드 가져오기

handleFault() 메서드에서 수신한 컨텍스트 오브젝트는 handleMessage() 메서드에서 수신한 것과 유사합니다. 컨텍스트의 getMessage() 메서드를 사용하여 동일한 방식으로 메시지 페이로드에 액세스합니다. 유일한 차이점은 컨텍스트에 포함된 페이로드입니다.

LogicalMessageContext 작업에 대한 자세한 내용은 43.3절. “논리 처리기에서 메시지 처리” 을 참조하십시오.

Cryostat MessageContext 작업에 대한 자세한 내용은 43.5절. “Cryostat 처리기에서 메시지 처리” 에서 참조하십시오.

43.7.3. 반환 값 확인

handleFault() 메서드가 메시지 처리를 완료하는 방법은 메시지 처리 진행 방식에 직접적인 영향을 미칩니다. 다음 작업 중 하나를 수행하여 완료합니다.

true로 반환
오류 처리가 정상적으로 계속되어야 한다는 실제 신호를 반환합니다. 체인에서 다음 처리기의 handleFault() 메서드가 호출됩니다.
false 반환
오류 처리가 중지되는 잘못된 신호를 반환합니다. 현재 메시지를 처리할 때 호출된 처리기의 close() 메서드가 호출되고 fault 메시지가 디스패치됩니다.
예외 발생
예외를 throw하면 오류 메시지 처리가 중지됩니다. 현재 메시지를 처리할 때 호출된 처리기의 close() 메서드가 호출되고 예외가 디스패치됩니다.

43.7.4. 예제

예 43.13. “메시지 처리기의 오류 처리” 메시지 본문을 화면에 출력하는 handleFault() 구현을 보여줍니다.

예 43.13. 메시지 처리기의 오류 처리

public final boolean handleFault(LogicalMessageContext messageContext)
{
  System.out.println("handleFault() called with message:");

  LogicalMessage msg=messageContext.getMessage();
  System.out.println(msg.getPayload());

  return true;
}
Copy to Clipboard Toggle word wrap

43.8. 처리기 닫기

처리기 체인이 메시지 처리가 완료되면 런타임은 실행된 각 처리기의 close() 메서드를 호출합니다. 이 위치는 메시지 처리 중 처리기에서 사용한 리소스를 정리하거나 속성을 기본 상태로 재설정하는 데 적합합니다.

리소스를 단일 메시지 교환 이상으로 유지해야 하는 경우 처리기의 close() 메서드 중에 해당 리소스를 정리해서는 안 됩니다.

43.9. 처리기 해제

43.9.1. 개요

런타임은 처리기가 바인딩된 서비스 또는 서비스 프록시가 종료될 때 처리기를 해제합니다. 런타임은 처리기의 종료자를 호출하기 전에 선택적 릴리스 메서드를 호출합니다. 이 선택적 릴리스 방법은 처리기에서 사용하는 리소스를 해제하거나 처리기의 종료자에서 적합하지 않은 다른 작업을 수행하는 데 사용할 수 있습니다.

처리기에 대한 정리 메서드를 제공할 필요가 없습니다.

43.9.2. 릴리스 순서

처리기가 릴리스될 때 다음이 발생합니다.

  1. 처리기는 활성 메시지 처리를 완료합니다.
  2. 런타임은 @PreDestroy 주석을 사용하여 데코레이팅 메서드를 호출합니다.

    이 메서드는 처리기에서 사용하는 모든 리소스를 정리해야 합니다.

  3. 처리기의 종료자를 이라고 합니다.

43.10. Handlers를 사용하도록 끝점 구성

43.10.1. 프로그래밍 방식 구성

43.10.1.1. 소비자에 Handler 체인 추가
43.10.1.1.1. 개요

처리기 체인을 소비자에 추가하려면 처리기 체인을 명시적으로 빌드해야 합니다. 그런 다음 서비스 프록시의 Binding 오브젝트에 처리기 체인을 직접 설정합니다.

중요

Spring 구성을 사용하여 구성된 모든 처리기 체인은 프로그래밍 방식으로 구성된 처리기 체인을 재정의합니다.

43.10.1.1.2. 절차

사용자에게 처리기 체인을 추가하려면 다음을 수행합니다.

  1. 처리기 체인을 저장할 List<Handler > 오브젝트를 생성합니다.
  2. 체인에 추가할 각 처리기의 인스턴스를 생성합니다.
  3. 런타임에서 호출할 순서대로 각 인스턴스화된 처리기 오브젝트를 목록에 추가합니다.
  4. 서비스 프록시에서 Binding 오브젝트를 가져옵니다.

    Apache CXF는 org.apache.cxf.jaxws.binding.DefaultBindingImpl 이라는 바인딩 인터페이스의 구현을 제공합니다.

  5. Binding 오브젝트의 setHandler Cryostat() 메서드를 사용하여 프록시에서 처리기 체인을 설정합니다.
43.10.1.1.3. 예제

예 43.14. “소비자에 Handler 체인 추가” 사용자에게 처리기 체인을 추가하기 위한 코드를 표시합니다.

예 43.14. 소비자에 Handler 체인 추가

import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import java.util.ArrayList;
import java.util.List;

import org.apache.cxf.jaxws.binding.DefaultBindingImpl;
...
SmallNumberHandler sh = new SmallNumberHandler();
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.add(sh);

DefaultBindingImpl binding = ((BindingProvider)proxy).getBinding();
binding.getBinding().setHandlerChain(handlerChain);
Copy to Clipboard Toggle word wrap

예 43.14. “소비자에 Handler 체인 추가” 의 코드는 다음을 수행합니다.

처리기를 인스턴스화합니다.

체인을 보유할 List 오브젝트를 만듭니다.

체인에 처리기를 추가합니다.

프록시에서 DefaultBindingImpl 개체로 Binding 개체를 가져옵니다.Gets the Binding object from the proxy as a DefaultBindingImpl object.

처리기 체인을 프록시의 바인딩에 할당합니다.

43.10.1.2. 서비스 공급자에 처리기 체인 추가
43.10.1.2.1. 개요

SEI 또는 구현 클래스를 @Handler Cryostat 주석으로 데코팅하여 서비스 공급자에 처리기 체인을 추가합니다. 주석은 서비스 공급자가 사용하는 처리기 체인을 정의하는 메타 데이터 파일을 가리킵니다.

43.10.1.2.2. 절차

서비스 공급자에 처리기 체인을 추가하려면 다음을 수행합니다.

  1. @Handler Cryostat 주석을 사용하여 공급자의 구현 클래스를 분리합니다.
  2. 처리기 체인을 정의하는 처리기 구성 파일을 생성합니다.
43.10.1.2.3. @Handler Cryostat 주석

javax.jws.Handler annotations 는 서비스 공급자의 구현 클래스를 분리합니다. 런타임에서 파일 속성으로 지정된 처리기 체인 구성 파일을 로드하도록 지시합니다.

주석의 file 속성은 로드할 처리기 구성 파일을 식별하는 두 가지 방법을 지원합니다.

  • a URL
  • 상대 경로 이름

예 43.15. “처리기 체인을 로드하는 서비스 구현” 에서는 handlers.xml 이라는 파일에 정의된 처리기 체인을 사용할 서비스 공급자 구현을 표시합니다. handlers.xml 은 서비스 공급자가 실행되는 디렉터리에 있어야 합니다.

예 43.15. 처리기 체인을 로드하는 서비스 구현

import javax.jws.HandlerChain;
import javax.jws.WebService;
...

@WebService(name = "AddNumbers",
            targetNamespace = "http://apache.org/handlers",
            portName = "AddNumbersPort",
            endpointInterface = "org.apache.handlers.AddNumbers",
            serviceName = "AddNumbersService")
@HandlerChain(file = "handlers.xml")
public class AddNumbersImpl implements AddNumbers
{
...
}
Copy to Clipboard Toggle word wrap
43.10.1.2.4. 처리기 구성 파일

처리기 구성 파일은 구현되는 XML 문법을 사용하여 처리기 체인을 정의합니다(Java EE용 웹 서비스, 버전 1.2). 이 문법은 http://java.sun.com/xml/ns/javaee 에 정의되어 있습니다.

처리기 구성 파일의 root 요소는 handler-chains 요소입니다. handler-chains 요소에는 하나 이상의 handler-chain 요소가 있습니다.

handler-chain 요소는 처리기 체인을 정의합니다. 표 43.1. “Server-Side Handler Chain을 정의하는 데 사용되는 요소” handler-chain 요소의 하위 요소에 대해 설명합니다.

Expand
표 43.1. Server-Side Handler Chain을 정의하는 데 사용되는 요소
element설명

handler

처리기를 설명하는 요소를 포함합니다.

service-name-pattern

처리기 체인이 바인딩된 서비스를 정의하는 WSDL 서비스 요소의 QName을 지정합니다. QName을 정의할 때 * 를 와일드카드로 사용할 수 있습니다.

port-name-pattern

처리기 체인이 바인딩된 끝점을 정의하는 WSDL 포트 요소의 QName을 지정합니다. QName을 정의할 때 * 를 와일드카드로 사용할 수 있습니다.

protocol-binding

처리기 체인이 사용되는 메시지 바인딩을 지정합니다. 바인딩은 URI로 지정되거나 다음과 같은 별칭을 사용하여 지정됩니다. #\#SOAP11_HTTP,\#SOAP11_HTTP_MTOM, \#SOAP12_HTTP_HTTP ,\##SOAP12_HTTP _MTOM 또는 \## XML_HTTP_HTTP.

메시지 바인딩 URI에 대한 자세한 내용은 23장. Apache CXF 바인딩 ID 을 참조하십시오.

handler-chain 요소는 단일 handler 요소를 하위로 보유하는 데만 필요합니다. 그러나 전체 처리기 체인을 정의하는 데 필요한 만큼의 처리기 요소를 지원할 수 있습니다. 체인의 처리기는 처리기 체인 정의에 지정된 순서로 실행됩니다.

중요

실행 최종 순서는 지정된 처리기를 논리 처리기 및 프로토콜 처리기로 정렬하여 결정됩니다. 그룹화 내에서 구성에 지정된 순서가 사용됩니다.

protocol-binding 과 같은 다른 자식은 정의된 처리기 체인의 범위를 제한하는 데 사용됩니다. 예를 들어 service-name-pattern 요소를 사용하는 경우 처리기 체인은 WSDL 포트 요소가 지정된 WSDL 서비스 요소의 자식인 서비스 공급자에만 연결됩니다. 이러한 제한 하위 중 하나만 handler 요소에서 사용할 수 있습니다.

handler 요소는 처리기 체인에서 개별 처리기를 정의합니다. handler-class 하위 요소는 처리기를 구현하는 클래스의 정규화된 이름을 지정합니다. handler 요소에는 처리기의 고유 이름을 지정하는 선택적 handler-name 요소가 있을 수도 있습니다.

예 43.16. “처리기 구성 파일” 단일 처리기 체인을 정의하는 처리기 구성 파일을 표시합니다. 체인은 두 개의 처리기로 구성됩니다.

예 43.16. 처리기 구성 파일

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
  <handler-chain>
    <handler>
      <handler-name>LoggingHandler</handler-name>
      <handler-class>demo.handlers.common.LoggingHandler</handler-class>
    </handler>
    <handler>
      <handler-name>AddHeaderHandler</handler-name>
      <handler-class>demo.handlers.common.AddHeaderHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>
Copy to Clipboard Toggle word wrap

43.10.2. Spring 설정

43.10.2.1. 개요

처리기 체인을 사용하도록 끝점을 구성하는 가장 쉬운 방법은 끝점 구성에 체인을 정의하는 것입니다. 이 작업은 엔드포인트를 구성하는 요소에 jaxwxs:handlers 자식을 추가하여 수행됩니다.

중요

구성 파일을 통해 추가된 처리기 체인은 프로그래밍 방식으로 구성된 처리기 체인보다 우선합니다.

43.10.2.2. 절차

처리기 체인을 로드하도록 끝점을 구성하려면 다음을 수행합니다.

  1. 끝점에 구성 요소가 없는 경우 하나를 추가합니다.

    Apache CXF 끝점 구성에 대한 자세한 내용은 17장. Cryostat-WS 끝점 구성 을 참조하십시오.

  2. jaxws:handlers 하위 요소를 끝점의 구성 요소에 추가합니다.
  3. 체인의 각 처리기에 대해 처리기를 구현하는 클래스를 지정하는ans 요소를 추가합니다.

    처리기 구현이 둘 이상의 위치에서 사용되는 경우 ref 요소를 사용하여 8080 요소를 참조할 수 있습니다.

43.10.2.3. handlers 요소

jaxws:handlers 요소는 엔드포인트 구성에서 처리기 체인을 정의합니다. 모든 Cryostat-WS 엔드포인트 구성 요소에 자식으로 표시될 수 있습니다. 다음은 다음과 같습니다.

  • jaxws:endpoint 는 서비스 공급자를 구성합니다.
  • jaxws:server 도 서비스 공급자를 구성합니다.
  • jaxws:client 는 서비스 소비자를 구성합니다.

다음 두 가지 방법 중 하나로 처리기를 처리기 체인에 추가합니다.

  • 구현 클래스 정의하는 Quarkus 요소 추가
  • ref 요소를 사용하여 구성 파일의 다른 위치에서 이름이 지정된 8080 요소를 참조합니다.

핸들러가 구성에 정의된 순서는 해당 핸들러가 실행될 순서입니다. 논리 처리기와 프로토콜 처리기를 혼합하면 순서가 변경될 수 있습니다. 런타임은 구성에 지정된 기본 순서를 유지하면서 적절한 순서로 정렬합니다.

43.10.2.4. 예제

예 43.17. “Spring에서 처리기 체인을 사용하도록 끝점 구성” 처리기 체인을 로드하는 서비스 공급자에 대한 구성이 표시됩니다.

예 43.17. Spring에서 처리기 체인을 사용하도록 끝점 구성

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:endpoint id="HandlerExample"
                  implementor="org.apache.cxf.example.DemoImpl"
                  address="http://localhost:8080/demo">
    <jaxws:handlers> <bean class="demo.handlers.common.LoggingHandler" /> <bean class="demo.handlers.common.AddHeaderHandler" /> </jaxws:handlers>
  </jaws:endpoint>
</beans>
Copy to Clipboard Toggle word wrap

44장. Maven 툴링 참조

44.1. 플러그인 설정

초록

Apache CXF 플러그인을 사용하려면 먼저 POM에 적절한 종속 항목과 리포지토리를 추가해야 합니다.

44.1.1. 종속 항목

프로젝트의 POM에 다음 종속 항목을 추가해야 합니다.

  • Cryostat-WS 프런트 엔드

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>version</version>
    </dependency>
    Copy to Clipboard Toggle word wrap
  • HTTP 전송

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>version</version>
    </dependency>
    Copy to Clipboard Toggle word wrap
  • Cryostat 전송

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http-undertow</artifactId>
      <version>version</version>
    </dependency>
    Copy to Clipboard Toggle word wrap

44.2. cxf-codegen-plugin

초록

WSDL 문서에서 Cryostat-WS 호환 Java 코드 생성

44.2.1. 개요

44.2.2. 기본 예

다음 POM 추출에서는 myService.wsdl WSDL 파일을 처리하기 위해 Maven cxf-codegen-plugin 을 구성하는 방법에 대한 간단한 예를 보여줍니다.

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>3.3.6.fuse-7_12_0-00020-redhat-00001</version>
  <executions>
    <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
        <sourceRoot>target/generated/src/main/java</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>src/main/resources/wsdl/myService.wsdl</wsdl>
          </wsdlOption>
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Copy to Clipboard Toggle word wrap

44.2.3. 기본 구성 설정

이전 예제에서는 다음 구성 설정을 사용자 지정할 수 있습니다.

configuration/sourceRoot
생성된 Java 파일이 저장될 디렉터리를 지정합니다. 기본값은 target/generated-sources/cxf 입니다.
configuration/wsdlOptions/wsdlOption/wsdl
WSDL 파일의 위치를 지정합니다.

44.2.4. 설명

wsdl2java 작업은 WSDL 문서를 사용하고 서비스를 구현할 완전히 주석이 달린 Java 코드를 생성합니다. WSDL 문서에는 유효한 portType 요소가 있어야 하지만 바인딩 요소 또는 서비스 요소를 포함할 필요는 없습니다. 선택적 인수를 사용하여 생성된 코드를 사용자 지정할 수 있습니다.

44.2.5. WSDL 옵션

플러그인을 구성하려면 하나 이상의 wsdlOptions 요소가 필요합니다. wsdlOptions 요소의 wsdl child이 필요하며 플러그인에서 처리할 WSDL 문서를 지정합니다. wsdl 요소 외에도 wsdlOptions 요소는 WSDL 문서를 처리하는 방법을 사용자 지정할 수 있는 여러 자식을 사용할 수 있습니다.

둘 이상의 wsdlOptions 요소를 플러그인 구성에 나열할 수 있습니다. 각 요소는 처리를 위해 단일 WSDL 문서를 구성합니다.

44.2.6. 기본 옵션

defaultOptions 요소는 선택적 요소입니다. 지정된 모든 WSDL 문서에 사용되는 옵션을 설정하는 데 사용할 수 있습니다.

중요

wsdlOptions 요소에서 옵션이 중복되면 wsdlOptions 요소의 값이 우선합니다.

44.2.7. 코드 생성 옵션 지정

일반 코드 생성 옵션( Apache CXF wsdl2java 명령줄 도구에서 지원하는 스위치에 해당)을 지정하려면 extraargs 요소를 wsdlOption 요소의 자식으로 추가할 수 있습니다. 예를 들어 다음과 같이 -impl 옵션과 -verbose 옵션을 추가할 수 있습니다.

...
<configuration>
  <sourceRoot>target/generated/src/main/java</sourceRoot>
  <wsdlOptions>
    <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
      <!-- you can set the options of wsdl2java command by using the <extraargs> -->
      <extraargs>
        <extraarg>-impl</extraarg>
        <extraarg>-verbose</extraarg>
      </extraargs>
    </wsdlOption>
  </wsdlOptions>
</configuration>
...
Copy to Clipboard Toggle word wrap

스위치가 인수를 사용하는 경우 후속 추가 요소를 사용하여 이러한 요소를 지정할 수 있습니다. 예를 들어 jibx 데이터 바인딩을 지정하려면 다음과 같이 플러그인을 구성할 수 있습니다.

...
<configuration>
  <sourceRoot>target/generated/src/main/java</sourceRoot>
  <wsdlOptions>
    <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
      <extraargs>
        <extraarg>-databinding</extraarg>
        <extraarg>jibx</extraarg>
      </extraargs>
    </wsdlOption>
  </wsdlOptions>
</configuration>
...
Copy to Clipboard Toggle word wrap

44.2.8. 바인딩 파일 지정

하나 이상의 Cryostat-WS 바인딩 파일의 위치를 지정하려면 bindingFiles 요소를 wsdlOption의 자식으로 추가할 수 있습니다. 예를 들면 다음과 같습니다.

...
<configuration>
  <wsdlOptions>
    <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
      <bindingFiles>
        <bindingFile>${basedir}/src/main/resources/wsdl/async_binding.xml</bindingFile>
      </bindingFiles>
    </wsdlOption>
  </wsdlOptions>
</configuration>
...
Copy to Clipboard Toggle word wrap

44.2.9. 특정 WSDL 서비스에 대한 코드 생성

코드가 생성될 WSDL 서비스의 이름을 지정하려면 serviceName 요소를 wsdlOption 의 자식으로 추가할 수 있습니다(기본 동작은 WSDL 문서의 모든 서비스에 대한 코드를 생성하는 것입니다).

...
<configuration>
  <wsdlOptions>
    <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
      <serviceName>MyWSDLService</serviceName>
    </wsdlOption>
  </wsdlOptions>
</configuration>
...
Copy to Clipboard Toggle word wrap

44.2.10. 여러 WSDL 파일에 대한 코드 생성

여러 WSDL 파일에 대한 코드를 생성하려면 WSDL 파일에 대한 추가 wsdlOption 요소를 삽입하면 됩니다. 모든 WSDL 파일에 적용되는 몇 가지 일반적인 옵션을 지정하려면 다음과 같이 공통 옵션을 defaultOptions 요소에 배치합니다.

<configuration>
  <defaultOptions>
      <bindingFiles>
          <bindingFile>${basedir}/src/main/jaxb/bindings.xml</bindingFile>
      </bindingFiles>
      <noAddressBinding>true</noAddressBinding>
  </defaultOptions>
  <wsdlOptions>
      <wsdlOption>
          <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
          <serviceName>MyWSDLService</serviceName>
      </wsdlOption>
      <wsdlOption>
          <wsdl>${basedir}/src/main/resources/wsdl/myOtherService.wsdl</wsdl>
          <serviceName>MyOtherWSDLService</serviceName>
      </wsdlOption>
  </wsdlOptions>
</configuration>
Copy to Clipboard Toggle word wrap

와일드카드 일치를 사용하여 여러 WSDL 파일을 지정할 수도 있습니다. 이 경우 wsdlRoot 요소를 사용하여 WSDL 파일을 포함하는 디렉터리를 지정한 다음 * 문자로 와일드카드를 지원하는 include 요소를 사용하여 필요한 WSDL 파일을 선택합니다. 예를 들어, src/main/resources/wsdl 루트 디렉터리에서 Service.wsdl 로 끝나는 모든 WSDL 파일을 선택하려면 다음과 같이 플러그인을 구성할 수 있습니다.

<configuration>
  <defaultOptions>
      <bindingFiles>
          <bindingFile>${basedir}/src/main/jaxb/bindings.xml</bindingFile>
      </bindingFiles>
      <noAddressBinding>true</noAddressBinding>
  </defaultOptions>
  <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>
  <includes>
      <include>*Service.wsdl</include>
  </includes>
</configuration>
Copy to Clipboard Toggle word wrap

44.2.11. Maven 리포지토리에서 WSDL 다운로드

Maven 리포지토리에서 직접 WSDL 파일을 다운로드하려면 wsdlOption 요소의 자식으로 wsdlArtifact 요소를 추가하고 다음과 같이 Maven 아티팩트의 좌표를 지정합니다.

...
<configuration>
  <wsdlOptions>
    <wsdlOption>
      <wsdlArtifact>
        <groupId>org.apache.pizza</groupId>
        <artifactId>PizzaService</artifactId>
        <version>1.0.0</version>
      </wsdlArtifact>
    </wsdlOption>
  </wsdlOptions>
</configuration>
...
Copy to Clipboard Toggle word wrap

44.2.12. 인코딩

(필수) generated Java 파일에 사용되는 문자 인코딩(Charset)을 지정하려면 다음과 같이 encoding 요소를 구성 요소의 자식으로 추가합니다.

...
<configuration>
  <wsdlOptions>
    <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
    </wsdlOption>
  </wsdlOptions>
  <encoding>UTF-8</encoding>
</configuration>
...
Copy to Clipboard Toggle word wrap

44.2.13. 별도의 프로세스 생성

fork 요소를 구성 요소의 자식으로 추가하여 코드 생성을 위해 별도의 JVM을 분기하도록 codegen 플러그인을 구성할 수 있습니다. fork 요소는 다음 값 중 하나로 설정할 수 있습니다.

한 번
단일 새 JVM을 분기하여 codegen 플러그인 구성에 지정된 모든 WSDL 파일을 처리합니다.
always
새 JVM을 분기하여 codegen 플러그인 구성에 지정된 각 WSDL 파일을 처리합니다.
false
(기본값) 포크를 비활성화합니다.

codegen 플러그인이 별도의 JVM을 분기하도록 구성된 경우(즉, fork 옵션이 false가 아닌 값으로 설정됨) additionalJvmArgs 요소를 통해 분기된 JVM에 추가 JVM 인수를 지정할 수 있습니다. 예를 들어 다음 조각에서는 단일 JVM을 분기하도록 codegen 플러그인을 구성합니다. 이 플러그인은 로컬 파일 시스템에서만 XML 스키마에 액세스하도록 제한됩니다 (Java x.xml.accessExternalSchema 시스템 속성을 설정함으로써).

...
<configuration>
  <wsdlOptions>
    <wsdlOption>
      <wsdl>${basedir}/src/main/resources/wsdl/myService.wsdl</wsdl>
    </wsdlOption>
  </wsdlOptions>
  <fork>once</fork>
  <additionalJvmArgs>-Djavax.xml.accessExternalSchema=jar:file,file</additionalJvmArgs>
</configuration>
...
Copy to Clipboard Toggle word wrap

44.2.14. 옵션 참조

코드 생성 프로세스를 관리하는 데 사용되는 옵션은 다음 표에서 검토합니다.

Expand
옵션해석

-fe|-frontend frontend

코드 생성기에서 사용하는 프런트 엔드를 지정합니다. 가능한 값은 jaxws,jaxws21cxf 입니다. jaxws21 프런트 엔드는 Cryostat-WS 2.1 호환 코드를 생성하는 데 사용됩니다. jaxws 프런트 엔드 대신 선택적으로 사용할 수 있는 cxf 프런트 엔드는 서비스 클래스에 대한 추가 생성자를 제공합니다. 이 생성자를 편리하게 사용하면 서비스 구성을 위해 Bus 인스턴스를 지정할 수 있습니다. 기본값은 jaxws 입니다.

-db|-databinding databinding

코드 생성기에서 사용하는 데이터 바인딩을 지정합니다. 가능한 값은 jaxb,xmlbeans,sdo (sdo-staticsdo-dynamic) 및 jibx 입니다. 기본값은 jaxb 입니다.

-wv wsdlVersion

도구에서 예상되는 WSDL 버전을 지정합니다. 기본값은 1.1 입니다.[a]

-p wsdlNamespace=PackageName

생성된 코드에 사용할 패키지 이름을 0개 이상 지정합니다. 선택적으로 WSDL 네임스페이스를 패키지 이름 매핑으로 지정합니다.

-b bindingName

하나 이상의 CryostatWS 또는 CryostatB 바인딩 파일을 지정합니다. 각 바인딩 파일에 별도의 -b 플래그를 사용합니다.

-sn serviceName

코드를 생성할 WSDL 서비스의 이름을 지정합니다. 기본값은 WSDL 문서의 모든 서비스에 대한 코드를 생성하는 것입니다.

-reserveClass classname

-autoNameResolution 과 함께 사용되며 클래스를 생성할 때 사용하지 않는 wsdl-to-java의 클래스 이름을 정의합니다. 여러 클래스에 대해 이 옵션을 여러 번 사용합니다.

-catalog catalogUrl

가져온 스키마 및 WSDL 문서를 확인하는 데 사용할 XML 카탈로그의 URL을 지정합니다.

-d output-directory

생성된 코드 파일을 작성할 디렉터리를 지정합니다.

-compile

생성된 Java 파일을 컴파일합니다.

-classdir complile-class-dir

컴파일된 클래스 파일이 기록되는 디렉터리를 지정합니다.

-clientjar jar-file-name

모든 클라이언트 클래스와 WSDL을 포함하는 JAR 파일을 생성합니다. 이 옵션이 지정되면 지정된 wsdlLocation 이 작동하지 않습니다.

-client

클라이언트 메인라인에 대한 시작점 코드를 생성합니다.

-server

서버 메인라인에 대한 시작점 코드를 생성합니다.

-impl

구현 개체의 시작점 코드를 생성합니다.

-all

모든 시작점 코드(type, service proxy, service interface, server mainline, client mainline, implementation object, Cryostat build.xml 파일)를 생성합니다.

-ant

Cryostat build.xml 파일을 생성합니다.

-autoNameResolution

바인딩 사용자 지정을 사용할 필요 없이 이름 지정 충돌을 자동으로 해결합니다.

-defaultValues=DefaultValueProvider

생성된 클라이언트 및 생성된 구현에 대한 기본값을 생성하도록 툴에 지시합니다. 선택적으로 기본값을 생성하는 데 사용되는 클래스 이름을 제공할 수도 있습니다. 기본적으로 RandomValueProvider 클래스가 사용됩니다.

-nexclude schema-namespace=java-packagename

코드를 생성할 때 지정된 WSDL 스키마 네임스페이스를 무시합니다. 이 옵션은 여러 번 지정할 수 있습니다. 또한 선택적으로 제외된 네임스페이스에 설명된 유형에서 사용하는 Java 패키지 이름을 지정합니다.

-exsh (true/false)

확장된 soap 헤더 메시지 바인딩 처리를 활성화하거나 비활성화합니다. 기본값은 false입니다.

-noTypes

생성 유형을 끕니다.

-DNS (true/false)

기본 네임스페이스 패키지 이름 매핑 로드를 활성화하거나 비활성화합니다. 기본값은 true입니다.

-DEX (true/false)

기본 excludes 네임스페이스 매핑의 로드를 활성화하거나 비활성화합니다. 기본값은 true입니다.

-xjcargs

CryostatB 데이터 바인딩이 사용될 때 XJC에 직접 전달할 쉼표로 구분된 인수 목록을 지정합니다. 가능한 모든 XJC 인수 목록을 가져오려면 -xjc-X 를 사용합니다.

-noAddressBinding

Cryostat-WS 2.1 준수 매핑 대신 Apache CXF 독점 WS-Addressing 유형을 사용하도록 툴에 지시합니다.

-validate [=all|basic|none]

모든 코드를 생성하기 전에 WSDL 문서의 유효성을 검사하도록 툴에 지시합니다.

-keep

기존 파일을 덮어쓰지 않도록 도구에 지시합니다.

-wsdlLocation wsdlLocation

@WebService 주석의 wsdlLocation 속성 값을 지정합니다.

-v

도구의 버전 번호를 표시합니다.

-verbose|-V

코드 생성 프로세스 중에 주석을 표시합니다.

-quiet

코드 생성 프로세스 중에 주석을 비활성화합니다.

-allowElementReferences[=true], -aer[=true]

true 인 경우 래퍼 스타일 매핑을 사용할 때 Cryostat-WS 2.2 사양의 섹션 2.3.1.2(v)에 지정된 규칙을 무시하십시오. 기본값은 false 입니다.

-asyncMethods[=method1,method2,…​]

client-WS 바인딩 파일에서 enableAsyncMapping 과 유사하게 클라이언트 측 비동기 호출을 허용하는 이후에 생성된 Java 클래스 메서드 목록입니다.

-bareMethods[=method1,method2,…​]

Cryostat-WS 바인딩 파일의 enableWrapperStyle 과 유사하게 래퍼 스타일을 갖도록 이후에 생성된 Java 클래스 메서드 목록입니다.

-mimeMethods[=method1,method2,…​]

나중에 생성된 Java 클래스 메서드 목록입니다. mime:content 매핑을 활성화하는 것과 유사하게 192.0.2.-WS 바인딩 파일에서 MIMEContent를 활성화할 수 있습니다.

-faultSerialVersionUID fault-serialVersionUID

오류 예외의 suid를 생성하는 방법 가능한 값은 NONE,TIMESTAMP,FQCN 또는 특정 번호입니다. 기본값은 None입니다.

-encoding 인코딩

Java 코드를 생성할 때 사용할 Charset 인코딩을 지정합니다.

-exceptionSuper

wsdl:fault 요소에서 생성된 fault 빈에 대한 슈퍼 클래스(기본값: java.lang.Exception).

-seiSuper interfaceName

생성된 SEI 인터페이스에 대한 기본 인터페이스를 지정합니다. 예를 들어 이 옵션을 사용하여 Java 7 자동 닫기 인터페이스를 슈퍼 인터페이스로 추가할 수 있습니다.

-mark-generated

@Generated 주석을 생성된 클래스에 추가합니다.

[a] 현재 Apache CXF는 코드 생성기에 대한 WSDL 1.1 지원만 제공합니다.

44.3. java2ws

초록

Java 코드에서 WSDL 문서 생성

44.3.1. 개요

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-java2ws-plugin</artifactId>
  <version>version</version>
  <executions>
    <execution>
      <id>process-classes</id>
      <phase>process-classes</phase>
      <configuration>
        <className>className</className>
        <option>...</option>
         ...
      </configuration>
      <goals>
        <goal>java2ws</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Copy to Clipboard Toggle word wrap

44.3.2. 설명

java2ws 작업은 서비스 엔드포인트 구현(SEI)을 사용하고 웹 서비스를 구현하는 데 사용되는 지원 파일을 생성합니다. 다음을 생성할 수 있습니다.

  • WSDL 문서
  • 서비스를 Cryostat로 배포하는 데 필요한 서버 코드
  • 서비스에 액세스하기 위한 클라이언트 코드
  • 래퍼 및 오류 빈

44.3.3. 필수 구성

플러그인을 사용하려면 className 구성 요소가 있어야 합니다. 요소의 값은 처리할 SEI의 정규화된 이름입니다.

44.3.4. 선택적 구성

다음 표에 나열된 구성 요소를 사용하여 WSDL 생성을 미세 조정할 수 있습니다.

Expand
element설명

frontend

SEI를 처리하고 지원 클래스를 생성하는 데 사용할 프런트 엔드를 지정합니다. jaxws 는 기본값입니다. 단순함 도 지원됩니다.

DataBinding

SEI를 처리하고 지원 클래스를 생성하는 데 사용되는 데이터 바인딩을 지정합니다. Cryostat-WS 프런트 엔드를 사용하는 경우 기본값은 jaxb 입니다. simple frontend를 사용할 때 기본값은 aegis 입니다.

genWsdl

true 로 설정할 때 WSDL 문서를 생성하도록 도구에 지시합니다.

genWrapperbean

true 로 설정할 때 래퍼 빈과 폴트 빈을 생성하도록 툴에 지시합니다.

genClient

true 로 설정할 때 클라이언트 코드를 생성하도록 툴에 지시합니다.

genServer

true 로 설정할 때 서버 코드를 생성하도록 툴에 지시합니다.

outputFile

생성된 WSDL 파일의 이름을 지정합니다.

classpath

SEI를 처리할 때 검색되는 classpath를 지정합니다.

soap12

생성된 WSDL 문서가 true 로 설정된 경우 Cryostat 1.2 바인딩을 포함하도록 지정합니다.

targetNamespace

생성된 WSDL 파일에서 사용할 대상 네임스페이스를 지정합니다.

serviceName

생성된 서비스 요소의 name 속성 값을 지정합니다.

VI 부. RESTful 웹 서비스 개발

이 가이드에서는 Cryostat-RS API를 사용하여 웹 서비스를 구현하는 방법을 설명합니다.

45장. RESTful 웹 서비스 소개

초록

REST(Representational State Transfer)는 네 가지 기본 HTTP 동사만 사용하여 HTTP를 통해 데이터 전송을 중심으로 하는 소프트웨어 아키텍처 스타일입니다. 또한 모든 추가 래퍼를 사용하고 모든 상태 데이터를 사용할 수 있습니다.

45.1. 개요

REST( Representational State Transfer )는 Roy Fielding이라는 연구원에 의해 의사 간해에 설명된 아키텍처 스타일입니다. RESTful 시스템에서 서버는 URI를 사용하여 리소스를 노출하고 클라이언트는 4개의 HTTP 동사를 사용하여 이러한 리소스에 액세스합니다. 클라이언트가 리소스를 수신하면 상태가 됩니다. 일반적으로 링크 다음에 따라 새 리소스에 액세스하면 해당 상태가 변경되거나 전환됩니다. 작업하기 위해 REST는 리소스가 광범위한 표준 문법을 사용하여 표현될 수 있다고 가정합니다.

World Wide Web은 REST 원칙에 따라 설계된 시스템의 가장 유비쿼터스의 예입니다. 웹 브라우저는 웹 서버에서 호스팅되는 리소스에 액세스하는 클라이언트의 역할을 합니다. 리소스는 모든 웹 브라우저에서 사용할 수 있는 HTML 또는 XML 문법을 사용하여 표시됩니다. 또한 브라우저는 새 리소스에 대한 링크를 쉽게 따를 수 있습니다.

RESTful 시스템의 장점은 확장성이 높고 유연하다는 것입니다. 리소스가 4개의 HTTP 동사를 사용하여 액세스 및 조작되므로 리소스는 URI를 사용하여 노출되고 리소스는 표준 문법을 사용하여 표현되므로 클라이언트는 서버 변경의 영향을 받지 않습니다. 또한 RESTful 시스템은 캐싱 및 프록시와 같은 HTTP의 확장성 기능을 최대한 활용할 수 있습니다.

45.2. 기본 REST 원칙

RESTful 아키텍처는 다음과 같은 기본 원칙을 준수합니다.

  • 애플리케이션 상태 및 기능은 리소스로 나뉩니다.
  • 리소스는 하이퍼 미디어 링크로 사용할 수 있는 표준 URI를 사용하여 주소 지정할 수 있습니다.
  • 모든 리소스는 4개의 HTTP 동사만 사용합니다.

    • DELETE
    • GET
    • POST
    • PUT
  • 모든 리소스는 HTTP에서 지원하는 MIME 유형을 사용하여 정보를 제공합니다.
  • 프로토콜은 상태 비저장입니다.
  • 응답은 캐시할 수 있습니다.
  • 프로토콜이 계층화됩니다.

45.3. Resources

리소스는 REST의 핵심입니다. 리소스는 URI를 사용하여 처리할 수 있는 정보의 소스입니다. 웹 초기에는 리소스가 주로 정적 문서였습니다. 최신 웹에서 리소스는 모든 정보 소스가 될 수 있습니다. 예를 들어 웹 서비스는 URI를 사용하여 액세스할 수 있는 리소스일 수 있습니다.

RESTful 끝점은 주소 있는 리소스의 표현을 교환합니다. 표현은 리소스에서 제공하는 데이터를 포함하는 문서입니다. 예를 들어 고객 레코드에 대한 액세스를 제공하는 웹 서비스의 방법은 리소스와 서비스 간에 교환되는 고객 레코드의 사본은 리소스를 나타냅니다.

45.4. REST 모범 사례

RESTful 웹 서비스를 설계할 때 다음 사항을 염두에 두는 것이 좋습니다.

  • 노출하려는 각 리소스에 대해 고유한 URI를 제공합니다.

    예를 들어, 드라이브 레코드를 처리하는 시스템을 구축하는 경우 각 레코드에는 고유한 URI가 있어야 합니다. 또한 시스템이 다운로딩 위반 및 과속도에 대한 정보를 제공하는 경우 각 유형의 리소스도 고유한 기반을 보유해야 합니다. 예를 들어, 속도 운임은 /speedingfines/driverID 를 통해 접근할 수 있고, 타이핑 위반은 /parkingfines/driverID 를 통해 접근할 수 있습니다.

  • URI에 nouns를 사용합니다.

    nouns를 사용하면 리소스가 작업이 아닌 리소스가 있다는 사실을 강조합니다. /ordering 과 같은 URI는 작업을 의미하지만 /order는 작업을 의미합니다.

  • GET 에 매핑되는 메서드는 데이터를 변경하지 않아야 합니다.
  • 응답에서 링크를 사용하십시오.

    응답에 다른 리소스에 대한 링크를 배치하면 클라이언트가 데이터 체인을 더 쉽게 추적할 수 있습니다. 예를 들어 서비스에서 리소스 컬렉션을 반환하는 경우 클라이언트가 제공된 링크를 사용하여 각 개별 리소스에 더 쉽게 액세스할 수 있습니다. 링크가 포함되지 않은 경우 클라이언트는 특정 노드로 체인을 따르기 위해 추가 논리가 있어야 합니다.

  • 서비스를 상태 비저장으로 설정합니다.

    상태 정보를 유지하기 위해 클라이언트 또는 서비스를 요구하면 둘 사이의 긴밀한 결합이 강제 적용됩니다. 긴밀한 결합으로 인해 업그레이드 및 마이그레이션이 더 어려워집니다. 상태를 유지하면 통신 오류로부터 복구를 더 어렵게 만들 수 있습니다.

45.5. RESTful 웹 서비스 설계

RESTful 웹 서비스를 구현하는 데 사용하는 프레임워크에 관계없이 따라야 하는 여러 단계가 있습니다.

  1. 서비스에서 노출할 리소스를 정의합니다.

    일반적으로 서비스는 트리로 구성된 하나 이상의 리소스를 노출합니다. 예를 들어 구동 레코드 서비스는 다음 세 가지 리소스로 구성할 수 있습니다.

    • /license/driverID
    • /license/driverID/speedingfines
    • /license/driverID/parkingfines
  2. 각 리소스에서 수행할 수 있는 작업을 정의합니다.

    예를 들어, 다이버의 주소를 업데이트하거나 운전기사 기록에서 공원 티켓을 제거할 수 있어야 합니다.

  3. 작업을 적절한 HTTP 동사에 매핑합니다.

서비스를 정의하면 Apache CXF를 사용하여 구현할 수 있습니다.

45.6. Apache CXF를 사용하여 REST 구현

Apache CXF는 RESTFul Web Services(JAX-RS)를 위한 Java API구현을 제공합니다. Cryostat-RS는 주석을 사용하여 Cryostat를 리소스에 매핑하는 표준화된 방법을 제공합니다.

abstract 서비스 정의에서 Cryostat-RS를 사용하여 구현된 RESTful 웹 서비스로 이동하는 경우 다음을 수행해야 합니다.

  1. 서비스 리소스 트리의 최상위를 나타내는 리소스에 대한 루트 리소스 클래스를 생성합니다.

    46.3절. “루트 리소스 클래스”을 참조하십시오.

  2. 서비스의 기타 리소스를 하위 리소스에 매핑합니다.

    46.5절. “하위 리소스 작업”을 참조하십시오.

  3. 각 리소스에서 사용하는 각 HTTP 동사를 구현하는 방법을 생성합니다.

    46.4절. “리소스 메서드 작업”을 참조하십시오.

참고

Apache CXF는 Java 인터페이스를 RESTful 웹 서비스에 매핑하기 위해 이전 HTTP 바인딩을 계속 지원합니다. HTTP 바인딩은 기본 기능을 제공하며 여러 가지 제한이 있습니다. 개발자는 Cryostat-RS를 사용하도록 애플리케이션을 업데이트하는 것이 좋습니다.

45.7. 데이터 바인딩

기본적으로 Apache CXF는 JAXB(Java Architecture for XML Binding) 개체를 사용하여 리소스 및 해당 표현을 Java 오브젝트에 매핑합니다. Java 개체와 XML 요소 간의 깔끔하고 잘 정의된 매핑을 제공합니다.

Apache CXF Cryostat-RS 구현에서는 JSON( JavaScript Object Notation )을 사용하여 데이터 교환도 지원합니다. JSON은 Cryostat 개발자가 사용하는 일반적인 데이터 형식입니다. JSON과 CryostatB 간의 데이터 마샬링은 Apache CXF 런타임에서 처리합니다.

46장. 리소스 생성

초록

RESTful 웹 서비스에서 모든 요청은 리소스에서 처리합니다. Cryostat-RS API는 리소스를 Java 클래스로 구현합니다. 리소스 클래스는 하나 이상의 Cryostat-RS 주석이 있는 Java 클래스입니다. Cryostat-RS를 사용하여 구현된 RESTful 웹 서비스의 핵심은 루트 리소스 클래스입니다. 루트 리소스 클래스는 서비스에서 노출하는 리소스 트리의 진입점입니다. 모든 요청 자체를 처리할 수도 있고, 요청을 처리하는 하위 리소스에 대한 액세스를 제공할 수도 있습니다.

46.1. 소개

46.1.1. 개요

Cryostat-RS API를 사용하여 구현된 RESTful 웹 서비스는 Java 클래스로 구현된 리소스의 표현으로 응답을 제공합니다. 리소스 클래스는 Cryostat-RS 주석을 사용하여 리소스를 구현하는 클래스입니다. 대부분의 RESTful 웹 서비스의 경우 액세스해야 하는 리소스 컬렉션이 있습니다. 리소스 클래스의 주석은 리소스의 URI 및 각 작업에서 처리하는 HTTP 동사와 같은 정보를 제공합니다.

46.1.2. 리소스 유형

Cryostat-RS API를 사용하면 두 가지 기본 유형의 리소스를 생성할 수 있습니다.

  • 46.3절. “루트 리소스 클래스” 는 서비스의 리소스 트리에 대한 진입점입니다. @Path 주석으로 데코레이팅되어 서비스의 리소스에 대한 기본 URI를 정의합니다.
  • 46.5절. “하위 리소스 작업” 루트 리소스를 통해 액세스할 수 있습니다. @Path 주석으로 데코레이팅되는 메서드로 구현됩니다. 하위 리소스의 @Path 주석은 루트 리소스의 기본 URI를 기준으로 URI를 정의합니다.

46.1.3. 예제

예 46.1. “간단한 리소스 클래스” 간단한 리소스 클래스를 표시합니다.

예 46.1. 간단한 리소스 클래스

package demo.jaxrs.server;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

@Path("/customerservice")
public class CustomerService
{
  public CustomerService()
  {
  }

  @GET
  public Customer getCustomer(@QueryParam("id") String id)
  {
    ...
  }

  ...
}
Copy to Clipboard Toggle word wrap

다음 두 항목은 예 46.1. “간단한 리소스 클래스” 에 정의된 클래스를 리소스 클래스로 만듭니다.

@Path 주석은 리소스의 기본 URI를 지정합니다.

@GET 주석은 메서드에서 리소스에 대한 HTTP GET 메서드를 구현하도록 지정합니다.

46.2. Basic Cryostat-RS 주석

46.2.1. 개요

RESTful 웹 서비스 구현에 필요한 가장 기본적인 정보는 다음과 같습니다.

  • 서비스 리소스의 URI
  • 클래스의 메서드를 HTTP 동사에 매핑하는 방법

Cryostat-RS는 이 기본 정보를 제공하는 주석 세트를 정의합니다. 모든 리소스 클래스에는 이러한 주석 중 하나 이상이 있어야 합니다.

46.2.2. 경로 설정

@Path 주석은 리소스의 URI를 지정합니다. 주석은 javax.ws.rs.Path 인터페이스에서 정의하며 리소스 클래스 또는 리소스 메서드를 데코레이팅하는 데 사용할 수 있습니다. 문자열 값은 유일한 매개 변수로 사용합니다. string 값은 구현된 리소스의 위치를 지정하는 URI 템플릿입니다.

URI 템플릿은 리소스의 상대 위치를 지정합니다. 예 46.2. “URI 템플릿 구문” 에 표시된 대로 템플릿에는 다음이 포함될 수 있습니다.

  • 처리되지 않은 경로 구성 요소
  • { }로 묶은 매개변수 식별자

    참고

    매개변수 식별자에는 기본 경로 처리를 변경하기 위한 정규식이 포함될 수 있습니다.

예 46.2. URI 템플릿 구문

@Path("resourceName/{param1}/../{paramN}")
Copy to Clipboard Toggle word wrap

예를 들어 URI 템플릿 위젯/{color}/{number}위젯s/blue/12 에 매핑됩니다. color 매개변수의 값은 파란색 으로 할당됩니다. number 매개 변수의 값은 12 로 할당됩니다.

URI 템플릿을 전체 URI에 매핑하는 방법은 @Path 주석을 데코딩하는 항목에 따라 달라집니다. 루트 리소스 클래스에 배치되면 URI 템플릿은 트리의 모든 리소스의 루트 URI이며 서비스가 게시되는 URI에 직접 추가됩니다. 주석이 하위 리소스를 데코레이트하는 경우 루트 리소스 URI를 기준으로 합니다.

46.2.3. HTTP 동사 지정

Cryostat-RS는 메서드에 사용할 HTTP 동사를 지정하는 데 5개의 주석을 사용합니다.

  • javax.ws.rs.DELETE는 메서드가 DELETE 에 매핑되도록 지정합니다.
  • javax.ws.rs.GET은 메서드가 GET 에 매핑되도록 지정합니다.
  • javax.ws.rs.POST는 메서드가 POST 에 매핑되도록 지정합니다.
  • javax.ws.rs.PUT는 메서드가 PUT 에 매핑되도록 지정합니다.
  • javax.ws.rs.HEAD는 메서드가 HEAD 에 매핑되도록 지정합니다.

메서드를 HTTP 동사에 매핑할 때 매핑이 적합한지 확인해야 합니다. 예를 들어 구매 주문을 제출하려는 방법을 매핑하면 PUT 또는 POST 에 매핑됩니다. GET 또는 DELETE 에 매핑하면 예기치 않은 동작이 발생합니다.

46.3. 루트 리소스 클래스

46.3.1. 개요

루트 리소스 클래스는 RESTful 웹 서비스가 구현된 Cryostat-RS의 진입점입니다. 서비스에서 구현된 리소스의 루트 URI를 지정하는 @Path 로 데코레이드됩니다. 해당 메서드는 리소스에 대한 작업을 직접 구현하거나 하위 리소스에 대한 액세스를 제공합니다.

46.3.2. 요구 사항

클래스가 루트 리소스 클래스가 되려면 다음 기준을 충족해야 합니다.

  • 클래스는 @Path 주석을 사용하여 데코레이팅해야 합니다.

    지정된 경로는 서비스에서 구현한 모든 리소스에 대한 루트 URI입니다. 루트 리소스 클래스가 해당 경로가 위젯 임을 지정하고 해당 메서드 중 하나가 GET 동사를 구현하는 경우 위젯GET 에서 해당 메서드를 호출합니다. 하위 리소스가 해당 URI를 {id} 로 지정하는 경우 하위 리소스의 전체 URI 템플릿은 widgets/{id} 이며 위젯 /12 및 위젯 /42 와 같은 URI에 대한 요청을 처리합니다.

  • 클래스에는 런타임이 호출되려면 공용 생성자가 있어야 합니다.

    런타임은 모든 생성자의 매개 변수에 대한 값을 제공할 수 있어야 합니다. 생성자의 매개 변수에는 Cryostat-RS 매개변수 주석으로 데코레이팅된 매개 변수가 포함될 수 있습니다. 매개변수 주석에 대한 자세한 내용은 47장. 리소스 클래스 및 메서드에 정보 전달 을 참조하십시오.

  • 클래스 메서드 중 하나 이상을 HTTP 동사 주석 또는 @Path 주석으로 데코레이팅해야 합니다.

46.3.3. 예제

예 46.3. “루트 리소스 클래스” 하위 리소스에 대한 액세스를 제공하는 루트 리소스 클래스를 표시합니다.

예 46.3. 루트 리소스 클래스

package demo.jaxrs.server;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/customerservice/")
public class CustomerService
{
  public CustomerService()
  {
    ...
  }

  @GET
  public Customer getCustomer(@QueryParam("id") String id)
  {
    ...
  }

  @DELETE
  public Response deleteCustomer(@QueryParam("id") String id)
  {
    ...
  }

  @PUT
  public Response updateCustomer(Customer customer)
  {
    ...
  }

  @POST
  public Response addCustomer(Customer customer)
  {
    ...
  }

  @Path("/orders/{orderId}/")
  public Order getOrder(@PathParam("orderId") String orderId)
  {
    ...
  }

}
Copy to Clipboard Toggle word wrap

예 46.3. “루트 리소스 클래스” 의 클래스는 루트 리소스 클래스에 대한 모든 요구 사항을 충족합니다.

클래스는 @Path 주석으로 데코레이팅됩니다. 서비스에서 노출하는 리소스의 루트 URI는 customerservice 입니다.

클래스에는 공용 생성자가 있습니다. 이 경우 단순화를 위해 인수 생성자가 사용되지 않습니다.

클래스는 리소스에 대한 네 가지 HTTP 동사를 각각 구현합니다.

또한 클래스는 getOrder() 메서드를 통해 하위 리소스에 대한 액세스를 제공합니다. @Path 주석을 사용하여 지정된 하위 리소스의 URI는 customerservice/order/id 입니다. 하위 리소스는 Order 클래스에 의해 구현됩니다.

하위 리소스 구현에 대한 자세한 내용은 46.5절. “하위 리소스 작업” 을 참조하십시오.

46.4. 리소스 메서드 작업

46.4.1. 개요

리소스 메서드에는 Cryostat-RS 주석을 사용하여 주석이 추가됩니다. 메서드에서 처리하는 요청 유형을 지정하는 HTTP 메서드 주석 중 하나가 있습니다. Cryostat-RS는 리소스 메서드에 여러 제약 조건을 배치합니다.

46.4.2. 일반 제약 조건

모든 리소스 메서드는 다음 조건을 충족해야 합니다.

  • 공개적이어야 합니다.
  • “HTTP 동사 지정” 에 설명된 HTTP 메서드 주석 중 하나로 데코레이팅해야 합니다.
  • “매개 변수” 에 설명된 대로 둘 이상의 엔터티 매개변수가 없어야 합니다.

46.4.3. 매개 변수

리소스 메서드 매개변수는 다음 두 가지 형태를 취합니다.

  • 엔터티 매개변수-Entity 매개변수는 주석이 없습니다. 해당 값은 요청 본문에서 매핑됩니다. 엔터티 매개 변수는 애플리케이션에 엔터티 공급자가 있는 모든 유형일 수 있습니다. 일반적으로 해당 오브젝트는 CryostatB 오브젝트입니다.

    중요

    리소스 메서드에는 엔터티 매개 변수가 하나만 있을 수 있습니다.

    엔터티 공급자에 대한 자세한 내용은 51장. 엔터티 지원 을 참조하십시오.

  • 주석이 달린 매개 변수-Annotated 매개변수는 요청에서 매개변수 값이 매핑되는 방법을 지정하는 Cryostat-RS 주석 중 하나를 사용합니다. 일반적으로 매개 변수의 값은 요청 URI의 일부에서 매핑됩니다.

    요청 데이터를 메서드 매개변수에 매핑하기 위해 Cryostat-RS 주석을 사용하는 방법에 대한 자세한 내용은 47장. 리소스 클래스 및 메서드에 정보 전달 을 참조하십시오.

예 46.4. “유효한 매개변수 목록이 있는 리소스 메서드” 유효한 매개 변수 목록을 사용하여 리소스 메서드를 표시합니다.

예 46.4. 유효한 매개변수 목록이 있는 리소스 메서드

@POST
@Path("disaster/monster/giant/{id}")
public void addDaikaiju(Kaiju kaiju,
                        @PathParam("id") String id)
{
  ...
}
Copy to Clipboard Toggle word wrap

예 46.5. “잘못된 매개변수 목록이 있는 리소스 메서드” 잘못된 매개변수 목록이 있는 리소스 메서드를 표시합니다. 여기에는 주석이 지정되지 않은 두 개의 매개변수가 있습니다.

예 46.5. 잘못된 매개변수 목록이 있는 리소스 메서드

@POST
@Path("disaster/monster/giant/")
public void addDaikaiju(Kaiju kaiju,
                        String id)
{
  ...
}
Copy to Clipboard Toggle word wrap

46.4.4. 반환 값

리소스 메서드는 다음 중 하나를 반환할 수 있습니다.

모든 리소스 메서드는 HTTP 상태 코드를 요청자에게 반환합니다. 메서드의 반환 유형이 void 이거나 반환되는 값이 null 인 경우 resource 메서드는 HTTP 상태 코드를 204 로 설정합니다. resource 메서드가 null 이외의 값을 반환하면 HTTP 상태 코드를 200 으로 설정합니다.

46.5. 하위 리소스 작업

46.5.1. 개요

두 개 이상의 리소스에서 서비스를 처리해야 할 가능성이 있습니다. 예를 들어 주문 처리 서비스에서 모범 사례에서는 각 고객이 고유한 리소스로 처리되도록 제안합니다. 각 순서는 고유한 리소스로 처리됩니다.

Cryostat-RS API를 사용하여 고객 리소스 및 주문 리소스를 하위 리소스로 구현합니다. 하위 리소스는 루트 리소스 클래스를 통해 액세스하는 리소스입니다. 리소스 클래스의 메서드에 @Path 주석을 추가하여 정의합니다. 하위 리소스는 다음 두 가지 방법 중 하나로 구현할 수 있습니다.

46.5.2. 하위 리소스 지정

하위 리소스는 메서드를 @Path 주석으로 데코딩하여 지정합니다. 하위 리소스의 URI는 다음과 같이 구성됩니다.

  1. 하위 리소스의 @Path 주석 값을 하위 리소스의 상위 리소스의 @Path 주석 값에 추가합니다.

    상위 리소스의 @Path 주석은 하위 리소스가 포함된 클래스의 오브젝트를 반환하는 리소스 클래스의 메서드에 있을 수 있습니다.

  2. 루트 리소스에 도달할 때까지 이전 단계를 반복합니다.
  3. 어셈블된 URI가 서비스가 배포된 기본 URI에 추가됩니다.

예를 들어 예 46.6. “주문 하위 리소스” 에 표시된 하위 리소스의 URI는 baseURI/customerservice/order/12 일 수 있습니다.

예 46.6. 주문 하위 리소스

...
@Path("/customerservice/")
public class CustomerService
{
  ...
  @Path("/orders/{orderId}/")
  @GET
  public Order getOrder(@PathParam("orderId") String orderId)
  {
    ...
  }
}
Copy to Clipboard Toggle word wrap

46.5.3. 하위 리소스 메서드

하위 리소스 메서드는 @Path 주석과 HTTP 동사 주석 중 하나로 구분됩니다. 하위 리소스 메서드는 지정된 HTTP 동사를 사용하여 리소스에 대한 요청을 직접 처리합니다.

예 46.7. “하위 리소스 메서드” 세 가지 하위 리소스가 포함된 리소스 클래스를 표시합니다.

  • getOrder() 는 URI가 /customerservice/orders/{orderId}/ 와 일치하는 리소스에 대한 HTTP GET 요청을 처리합니다.
  • updateOrder() 는 URI가 /customerservice/orders/{orderId}/ 와 일치하는 리소스에 대한 HTTP PUT 요청을 처리합니다.
  • newOrder()/customerservice/orders/ 에 있는 리소스에 대한 HTTP POST 요청을 처리합니다.

예 46.7. 하위 리소스 메서드

...
@Path("/customerservice/")
public class CustomerService
{
  ...
  @Path("/orders/{orderId}/")
  @GET
  public Order getOrder(@PathParam("orderId") String orderId)
  {
    ...
  }

  @Path("/orders/{orderId}/")
  @PUT
  public Order updateOrder(@PathParam("orderId") String orderId,
                           Order order)
  {
    ...
  }

  @Path("/orders/")
  @POST
  public Order newOrder(Order order)
  {
    ...
  }
}
Copy to Clipboard Toggle word wrap
참고

동일한 URI 템플릿이 있는 하위 리소스 메서드는 하위 리소스에서 반환하는 리소스 클래스와 동일합니다.

46.5.4. 하위 리소스

하위 리소스는 HTTP 동사 주석 중 하나로 장식되지 않으며 직접 처리하지 않는 하위 리소스에서 요청합니다. 대신 하위 리소스는 요청을 처리할 수 있는 리소스 클래스의 인스턴스를 반환합니다.

HTTP 동사 주석이 없는 것 외에도 하위 리소스는 엔터티 매개변수도 포함할 수 없습니다. 하위 리소스에서 사용하는 모든 매개변수는 47장. 리소스 클래스 및 메서드에 정보 전달 에 설명된 주석 중 하나를 사용해야 합니다.

예 46.8. “특정 클래스를 반환하는 하위 리소스” 에 표시된 대로 하위 리소스를 사용하면 모든 메서드를 하나의 슈퍼 클래스에 배치하지 않고 재사용 가능한 클래스로 리소스를 캡슐화할 수 있습니다. processOrder() 메서드는 하위 리소스입니다. URI 템플릿 /orders/{orderId}/ 와 일치하는 URI에서 요청이 생성되면 Order 클래스의 인스턴스를 반환합니다. Order 클래스에는 HTTP 동사 주석으로 데코레이팅되는 메서드가 있습니다. PUT 요청은 updateOrder() 메서드에서 처리합니다.

예 46.8. 특정 클래스를 반환하는 하위 리소스

...
@Path("/customerservice/")
public class CustomerService
{
  ...
  @Path("/orders/{orderId}/")
  public Order processOrder(@PathParam("orderId") String orderId)
  {
    ...
  }

  ...
}

public class Order
{
  ...
  @GET
  public Order getOrder(@PathParam("orderId") String orderId)
  {
    ...
  }

  @PUT
  public Order updateOrder(@PathParam("orderId") String orderId,
                           Order order)
  {
    ...
  }

}
Copy to Clipboard Toggle word wrap

하위 리소스는 런타임 시 처리되므로 다형성을 지원할 수 있습니다. 하위 리소스의 반환 값은 일반 개체, 추상 클래스 또는 클래스 계층 구조의 최상위일 수 있습니다. 예를 들어, 귀하의 서비스가 JWT 주문 및 신용카드 주문을 처리하는 데 필요한 경우 예 46.8. “특정 클래스를 반환하는 하위 리소스” 에서 processOrder() 메서드의 서명은 변경되지 않은 상태로 유지될 수 있습니다. Order 클래스를 확장한 두 개의 클래스 ppOrderccOder 를 구현해야 합니다. processOrder() 의 구현은 필요한 논리에 따라 원하는 하위 리소스 구현을 인스턴스화합니다.

46.6. 리소스 선택 방법

46.6.1. 개요

지정된 URI가 하나 이상의 리소스 메서드에 매핑될 수 있습니다. 예를 들어 URI customerservice/12/ma@Path("customerservice/{id}") 또는 @Path("customerservice/{id}/{state}") 템플릿과 일치할 수 있습니다. Cryostat-RS는 리소스 메서드를 요청과 일치시키기 위한 자세한 알고리즘을 지정합니다. 알고리즘은 정규화된 URI, HTTP 동사, 요청 및 응답 엔터티의 미디어 유형을 리소스 클래스의 주석과 비교합니다.

46.6.2. 기본 선택 알고리즘

Cryostat-RS 선택 알고리즘은 다음 세 단계로 나뉩니다.

  1. 루트 리소스 클래스를 확인합니다.

    요청 URI는 @Path 주석으로 데코레이팅된 모든 클래스와 일치합니다. @Path 주석이 요청 URI와 일치하는 클래스가 결정됩니다.

    리소스 클래스의 @Path 주석 값이 전체 요청 URI와 일치하면 클래스의 메서드가 세 번째 단계에 대한 입력으로 사용됩니다.

  2. 오브젝트가 요청을 처리할지 확인합니다.

    요청 URI가 선택한 클래스의 @Path 주석 값보다 길면 리소스 메서드의 @Path 주석 값이 요청을 처리할 수 있는 하위 리소스를 찾는 데 사용됩니다.

    하나 이상의 하위 리소스 메서드가 요청 URI와 일치하는 경우 이러한 메서드는 세 번째 단계에 대한 입력으로 사용됩니다.

    요청 URI에 대한 유일한 항목이 하위 리소스 검색기인인 경우 요청 URI와 일치하도록 하위 리소스 검색기에서 생성한 오브젝트의 리소스 메서드입니다. 이 단계는 하위 리소스 메서드가 요청 URI와 일치할 때까지 반복됩니다.

  3. 요청을 처리할 리소스 메서드를 선택합니다.

    HTTP 동사 주석이 요청의 HTTP 동사와 일치하는 리소스 메서드입니다. 또한 선택한 리소스 메서드는 요청 엔티티 본문의 미디어 유형을 수락하고 요청에 지정된 미디어 유형을 따르는 응답을 생성할 수 있어야 합니다.

46.6.3. 여러 리소스 클래스에서 선택

선택 알고리즘의 처음 두 단계에 따라 요청을 처리할 리소스가 결정됩니다. 경우에 따라 리소스는 리소스 클래스로 구현됩니다. 다른 경우에는 동일한 URI 템플릿을 사용하는 하나 이상의 하위 리소스로 구현됩니다. 요청 URI와 일치하는 리소스가 여러 개 있는 경우 리소스 클래스가 하위 리소스보다 우선합니다.

리소스 클래스와 하위 리소스 간에 정렬한 후 두 개 이상의 리소스가 요청 URI와 일치하는 경우 다음 기준이 단일 리소스를 선택하는 데 사용됩니다.

  1. URI 템플릿에서 리터럴 문자가 가장 많은 리소스를 선호합니다.

    리터럴 문자는 템플릿 변수의 일부가 아닌 문자입니다. 예를 들어 /widgets/{id}/{color} 에는 10개의 리터럴 문자가 있으며 /widgets/1/{color} 에는 7개의 리터럴 문자가 있습니다. 따라서 요청 URI /widgets/1/red 가 URI 템플릿으로 /widgets/1/{color} 인 리소스와 일치합니다.

    참고

    후행 슬래시(/)는 리터럴 문자로 간주됩니다. 따라서 /joefred//joefred 보다 우선합니다.

  2. URI 템플릿에서 가장 많은 변수가 있는 리소스를 선호합니다.

    요청 URI /widgets/30/green/widgets/{id}/{color}/widgets/{amount}/ 와 모두 일치할 수 있습니다. 그러나 URI 템플릿 /widgets/{id}/{color} 가 있는 리소스는 두 개의 변수가 있으므로 선택됩니다.

  3. 정규식을 포함하는 가장 많은 변수가 있는 리소스를 선호합니다.

    요청 URI /widgets/30/green/widgets/{number}/{ color}/widgets/{id:.}/{ color}*와 모두 일치할 수 있습니다. 그러나 URI 템플릿 */widgets/{id:.}/{color} 가 있는 리소스는 정규식이 포함된 변수가 있기 때문에 선택됩니다.

46.6.4. 여러 리소스 방법에서 선택

대부분의 경우 요청 URI와 일치하는 리소스를 선택하면 요청을 처리할 수 있는 단일 리소스 메서드가 생성됩니다. 방법은 요청에 지정된 HTTP 동사와 리소스 메서드의 HTTP 동사 주석을 일치시켜 결정됩니다. 적절한 HTTP 동사 주석 외에도 선택한 방법은 요청에 포함된 요청 엔티티를 처리하고 요청의 메타데이터에 지정된 적절한 유형의 응답을 생성할 수 있어야 합니다.

참고

리소스 메서드가 처리할 수 있는 요청 엔티티 유형은 @Consumes 주석으로 지정됩니다. 리소스 메서드에서 생성할 수 있는 응답 유형은 @Produces 주석을 사용하여 지정합니다.

리소스를 선택할 때 요청을 처리할 수 있는 여러 메서드를 생성할 때 다음 기준이 요청을 처리할 리소스 메서드를 선택하는 데 사용됩니다.

  1. 하위 리소스에 대한 리소스 메서드를 선호합니다.
  2. 하위 리소스 검색기에 비해 하위 리소스 메서드를 선호합니다.
  3. @Consumes 주석과 @Produces 주석에서 가장 구체적인 값을 사용하는 메서드를 선호합니다.

    예를 들어 주석이 @Consumes("text/xml") 인 메서드는 @Consumes("text/*") 주석이 있는 메서드보다 우선합니다. 두 방법 모두 @Consumes 주석이나 주석 @Consumes("\*/*") 없이 메서드보다 우선합니다.

  4. 요청 본문 엔티티의 콘텐츠 유형과 가장 밀접하게 일치하는 메서드를 선호합니다.

    참고

    요청 본문 엔티티의 콘텐츠 유형은 HTTP Content-Type 속성에 지정됩니다.

  5. 응답으로 허용되는 콘텐츠 유형과 가장 근접하게 일치하는 방법을 선호합니다.

    참고

    응답으로 허용되는 콘텐츠 유형은 HTTP Accept 속성에 지정됩니다.

46.6.5. 선택 프로세스 사용자 정의

경우에 따라 개발자는 여러 리소스 클래스를 선택하는 방식에서 알고리즘이 다소 제한적인 경우가 있습니다. 예를 들어 지정된 리소스 클래스가 일치하고 이 클래스에 일치하는 리소스 메서드가 없는 경우 알고리즘의 실행이 중지됩니다. 일치하는 나머지 리소스 클래스를 확인하지 않습니다.

Apache CXF는 런타임에서 일치하는 여러 리소스 클래스를 사용자 지정하는 데 사용할 수 있는 org.apache.cxf.jaxrs.ext.ResourceComparator 인터페이스를 제공합니다. 예 46.9. “리소스 선택을 사용자 정의하는 인터페이스” 에 표시된 ResourceComparator 인터페이스는 구현해야 하는 방법이 있어야 합니다. 하나는 두 리소스 클래스를 비교하고 다른 하나는 두 리소스 메서드를 비교합니다.

예 46.9. 리소스 선택을 사용자 정의하는 인터페이스

package org.apache.cxf.jaxrs.ext;

import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.message.Message;

public interface ResourceComparator
{
  int compare(ClassResourceInfo cri1,
              ClassResourceInfo cri2,
              Message message);

  int compare(OperationResourceInfo oper1,
              OperationResourceInfo oper2,
              Message message);
}
Copy to Clipboard Toggle word wrap

사용자 지정 구현은 다음과 같이 두 리소스 간에 선택합니다.

  • 첫 번째 매개 변수가 두 번째 매개변수보다 일치하는 경우 1 을 반환합니다.
  • 두 번째 매개 변수가 첫 번째 매개변수보다 일치하는 경우 -1 을 반환합니다.

0 이 반환되면 런타임은 기본 선택 알고리즘을 진행합니다.

서비스의 jaxrs:server 요소에 resourceComparator 자식을 추가하여 사용자 지정 ResourceComparator 구현을 등록합니다.

47장. 리소스 클래스 및 메서드에 정보 전달

초록

Cryostat-RS는 개발자가 리소스에 전달되는 정보가 들어오는 위치를 제어할 수 있는 여러 주석을 지정합니다. 주석은 URI의 매트릭스 매개변수와 같은 일반적인 HTTP 개념을 준수합니다. 표준 API를 사용하면 주석을 메서드 매개변수, 빈 속성 및 리소스 클래스 필드에서 사용할 수 있습니다. Apache CXF는 여러 매개 변수를 빈에 삽입할 수 있는 확장을 제공합니다.

47.1. 데이터 삽입의 기본 사항

47.1.1. 개요

HTTP 요청 메시지의 데이터를 사용하여 초기화되는 parameters, 필드,ans 속성의 값은 런타임에서 해당 값에 삽입됩니다. 삽입된 특정 데이터는 47.2절. “Cryostat-RS API 사용” 에 설명된 주석 세트에 의해 지정됩니다.

Cryostat-RS 사양은 데이터가 삽입될 때 몇 가지 제한 사항을 배치합니다. 또한 요청 데이터를 삽입할 수 있는 오브젝트 유형에 대한 몇 가지 제한 사항을 배치합니다.

47.1.2. 데이터가 삽입되는 경우

요청 데이터는 요청으로 인해 인스턴스화될 때 오브젝트에 삽입됩니다. 즉, 리소스에 직접 해당하는 오브젝트만 인젝션 주석을 사용할 수 있습니다. 46장. 리소스 생성 에서 설명한 대로 이러한 오브젝트는 @Path 주석으로 데코레이팅된 루트 리소스 또는 하위 리소스 Cryostat 메서드에서 반환된 오브젝트입니다.

47.1.3. 지원되는 데이터 유형

데이터를 삽입할 수 있는 특정 데이터 유형 세트는 삽입된 데이터의 소스를 지정하는 데 사용되는 주석에 따라 달라집니다. 그러나 모든 삽입 주석은 최소한 다음 데이터 유형 세트를 지원합니다.

  • int,char 또는 long과 같은 프리미티브
  • 단일 String 인수를 허용하는 생성자가 있는 개체
  • 단일 String 인수를 허용하는 정적 valueOf() 메서드가 있는 개체
  • List<T>, Set<T>, 또는 SortedSet<T> T > T는 목록의 다른 조건을 충족
참고

삽입 주석에 지원되는 데이터 유형에 대한 요구 사항이 다른 경우 주석에 대한 토론에서 차이점이 강조 표시됩니다.

47.2. Cryostat-RS API 사용

47.2.1. Cryostat-RS 주석 유형

표준 Cryostat-RS API는 필드,ans 속성 및 메서드 매개 변수에 값을 삽입하는 데 사용할 수 있는 주석을 지정합니다. 주석은 세 가지 유형으로 분할할 수 있습니다.

47.2.2. 요청 URI에서 데이터 삽입

47.2.2.1. 개요

RESTful 웹 서비스를 설계하기 위한 모범 사례 중 하나는 각 리소스에 고유한 URI가 있어야 한다는 것입니다. 개발자는 이 원칙을 사용하여 기본 리소스 구현에 많은 정보를 제공할 수 있습니다. 리소스에 대한 URI 템플릿을 설계할 때 개발자는 리소스 구현에 삽입할 수 있는 매개 변수 정보를 포함하도록 템플릿을 빌드할 수 있습니다. 개발자는 쿼리 및 매트릭스 매개 변수를 활용하여 리소스 구현에 대한 정보를 제공할 수도 있습니다.

47.2.2.2. URI 경로에서 데이터 가져오기

리소스에 대한 정보를 얻는 일반적인 메커니즘 중 하나는 리소스에 대한 URI 템플릿을 만드는 데 사용되는 변수를 사용하는 것입니다. 이 작업은 javax.ws.rs.PathParam 주석을 사용하여 수행됩니다. @PathParam 주석에는 데이터를 삽입할 URI 템플릿 변수를 식별하는 단일 매개변수가 있습니다.

예 47.1. “URI 템플릿 변수에서 데이터 삽입” 에서 @PathParam 주석은 URI 템플릿 변수 색상 값이 item Cryostat 필드에 삽입되도록 지정합니다.

예 47.1. URI 템플릿 변수에서 데이터 삽입

import javax.ws.rs.Path;
import javax.ws.rs.PathParam
...

@Path("/boxes/{shape}/{color}")
class Box
{
  ...

  @PathParam("color")
  String itemColor;

  ...
}
Copy to Clipboard Toggle word wrap

@PathParam 주석에서 지원하는 데이터 유형은 “지원되는 데이터 유형” 에 설명된 것과 다릅니다. @PathParam 주석이 데이터를 삽입하는 엔티티는 다음 유형 중 하나여야 합니다.

  • PathSegment

    값은 경로의 일치하는 부분의 최종 세그먼트가 됩니다.

  • List<PathSegment>

    값은 이름이 지정된 template 매개변수와 일치하는 경로 세그먼트에 해당하는 PathSegment 오브젝트 목록입니다.

  • int,char 또는 long과 같은 프리미티브
  • 단일 String 인수를 허용하는 생성자가 있는 개체
  • 단일 String 인수를 허용하는 정적 valueOf() 메서드가 있는 개체
47.2.2.3. 쿼리 매개변수 사용

웹에서 정보를 전달하는 일반적인 방법은 URI에서 쿼리 매개 변수 를 사용하는 것입니다. 쿼리 매개변수는 URI 끝에 표시되고 물음표(?)로 URI의 리소스 위치 부분과 구분됩니다. 이름과 값이 등호(=)로 구분된 이름 값 쌍으로 구성됩니다. 쿼리 매개 변수가 두 개 이상 지정되면 쌍이 together(; ) 또는 앰퍼샌드(&amp;)로 구분됩니다. 예 47.2. “쿼리 문자열이 포함된 URI” 쿼리 매개 변수가 있는 URI의 구문을 표시합니다.

예 47.2. 쿼리 문자열이 포함된 URI

http://fusesource.org?name=value;name2=value2;...
Copy to Clipboard Toggle word wrap
참고

앰퍼샌드 또는 앰퍼샌드를 사용하여 쿼리 매개변수를 분리할 수 있지만 둘 다 분리할 수는 없습니다.

javax.ws.rs.QueryParam 주석은 쿼리 매개 변수의 값을 추출하여 Cryostat-RS 리소스에 삽입합니다. 이 주석은 값을 추출하여 지정된 필드, Cryostat 속성 또는 매개 변수에 삽입하는 쿼리 매개변수의 이름을 식별하는 단일 매개 변수를 사용합니다. @QueryParam 주석은 “지원되는 데이터 유형” 에 설명된 유형을 지원합니다.

예 47.3. “쿼리 매개변수의 데이터를 사용하는 리소스 방법” 쿼리 매개변수 id 의 값을 메서드의 id 매개변수에 삽입하는 리소스 메서드를 표시합니다.

예 47.3. 쿼리 매개변수의 데이터를 사용하는 리소스 방법

import javax.ws.rs.QueryParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
...

@Path("/monstersforhire/")
public class MonsterService
{
  ...
  @POST
  @Path("/{type}")
  public void updateMonster(@PathParam("type") String type,
                            @QueryParam("id") String id)
  {
    ...
  }
  ...
}
Copy to Clipboard Toggle word wrap

/monstersforhire/da Cryostatiju?id=jonas 에 대한 HTTP POST 를 처리하려면 updateMonster() 메서드 유형이 da Cryostati ju 로 설정되고 idjonas 로 설정됩니다.

47.2.2.4. 매트릭스 매개변수 사용

URI 매트릭스 매개 변수(예: URI 쿼리 매개변수)는 리소스를 선택하는 추가 정보를 제공할 수 있는 이름/값 쌍입니다. 쿼리 매개변수와 달리 매트릭스 매개 변수는 URI의 아무 곳에나 표시될 수 있으며, URI의 계층 경로 세그먼트와 분리되어 있습니다. /mostersforhire/da Cryostatiju;id=jonas 에는 id/monstersforhire/japan;type=da Cryostatiju/flying;wingspan=40 이라는 하나의 매트릭스 매개변수가 있으며 유형wingspan 이라는 두 개의 매트릭스 매개변수가 있습니다.

참고

매트릭스 매개변수는 리소스의 URI를 계산할 때 평가되지 않습니다. 따라서 요청 URI /monstersforhire/japan;type=da Cryostatiju/flying;wingspan=40/monstersforhire/japan/flying.

매트릭스 매개변수 값은 javax.ws.rs.MatrixParam 주석을 사용하여 필드, 매개변수 또는 8080 속성에 삽입됩니다. 이 주석은 값을 추출하여 지정된 필드, Cryostat 속성 또는 매개 변수에 삽입하는 matrix 매개변수의 이름을 식별하는 단일 매개 변수를 사용합니다. @MatrixParam 주석은 “지원되는 데이터 유형” 에 설명된 유형을 지원합니다.

예 47.4. “매트릭스 매개 변수의 데이터를 사용하는 리소스 방법” 매트릭스 매개 변수 유형id 의 값을 메서드의 매개 변수에 삽입하는 리소스 메서드를 표시합니다.

예 47.4. 매트릭스 매개 변수의 데이터를 사용하는 리소스 방법

import javax.ws.rs.MatrixParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
...

@Path("/monstersforhire/")
public class MonsterService
{
  ...
  @POST
  public void updateMonster(@MatrixParam("type") String type,
                            @MatrixParam("id") String id)
  {
    ...
  }
  ...
}
Copy to Clipboard Toggle word wrap

/monstersforhire;type=da Cryostatiju;id=whale 에 HTTP POST 를 처리하려면 updateMonster() 메서드 유형이 da Cryostati ju 로 설정되고 idwhale 으로 설정됩니다.

참고

Cryostat-RS는 URI의 모든 매트릭스 매개변수를 한 번에 평가하므로 URI의 매트릭스 매개변수 위치에 제약 조건을 적용할 수 없습니다. 예: /monstersforhire/japan;type=da Cryostatiju/flying;wingspan=40 , /monstersforhire/japan/flying;type=da Cryostatiju;wingspan=40, 및 /monstersforhire/japan;/japan;/japan; type=da Cryostatiju;wingspan=40/flying 은 모두 Cryostat-RS API를 사용하여 구현된 RESTful 웹 서비스에서 동일한 것으로 처리됩니다.

47.2.2.5. URI 디코딩 비활성화

기본적으로 모든 요청 URI가 디코딩됩니다. 따라서 URI /monster/night%20stalker 와 URI /monster/night stalker 는 동일합니다. 자동 URI 디코딩을 사용하면 ASCII 문자 집합 외부에서 문자를 매개 변수로 쉽게 보낼 수 있습니다.

URI를 자동으로 디코딩하지 않으려면 javax.ws.rs.Encoded 주석을 사용하여 URI 디코딩을 비활성화할 수 있습니다. 주석을 사용하여 다음 수준에서 URI 디코딩을 비활성화할 수 있습니다.

  • 클래스 level-Decorating a class with the @Encoded 주석을 사용하면 클래스의 모든 매개변수, 필드 및 empty 속성에 대한 URI 디코딩이 비활성화됩니다.
  • 메서드 level-Decorating a method with the @Encoded 주석을 사용하면 클래스의 모든 매개변수에 대한 URI 디코딩이 비활성화됩니다.
  • @Encoded 주석을 사용하여 매개변수/필드 level-Decorating a parameter or field with the @Encoded 주석은 클래스의 모든 매개변수에 대한 URI 디코딩을 비활성화합니다.

예 47.5. “URI 디코딩 비활성화” getMonster() 메서드가 URI 디코딩을 사용하지 않는 리소스를 표시합니다. addMonster() 메서드는 type 매개변수에 대한 URI 디코딩만 비활성화합니다.

예 47.5. URI 디코딩 비활성화

@Path("/monstersforhire/")
public class MonsterService
{
  ...

  @GET
  @Encoded
  @Path("/{type}")
  public Monster getMonster(@PathParam("type") String type,
                            @QueryParam("id") String id)
  {
    ...
  }

  @PUT
  @Path("/{id}")
  public void addMonster(@Encoded @PathParam("type") String type,
                         @QueryParam("id") String id)
  {
    ...
  }
  ...
}
Copy to Clipboard Toggle word wrap
47.2.2.6. 오류 처리

URI 주입 주석 중 하나를 사용하여 데이터를 삽입하려고 할 때 오류가 발생하면 원래 예외를 래핑하는 WebApplicationException 예외가 생성됩니다. WebApplicationException 예외의 상태는 404 로 설정됩니다.

47.2.3. HTTP 메시지 헤더에서 데이터 삽입

47.2.3.1. 개요

일반적인 사용에서 요청 메시지의 HTTP 헤더는 메시지에 대한 일반 정보, 전송 중 처리 방법, 예상 응답에 대한 세부 정보를 전달합니다. 몇 가지 표준 헤더가 일반적으로 인식되고 사용되지만 HTTP 사양에서는 모든 이름/값 쌍을 HTTP 헤더로 사용할 수 있습니다. Cryostat-RS API는 HTTP 헤더 정보를 리소스 구현에 삽입하기 위한 간편한 메커니즘을 제공합니다.

가장 일반적으로 사용되는 HTTP 헤더 중 하나는 쿠키입니다. 쿠키를 사용하면 HTTP 클라이언트 및 서버가 여러 요청/응답 시퀀스에서 정적 정보를 공유할 수 있습니다. Cryostat-RS API는 템플릿에서 리소스 구현에 직접 데이터를 삽입하는 주석을 제공합니다.

47.2.3.2. HTTP 헤더에서 정보 삽입

javax.ws.rs.HeaderParam 주석은 HTTP 헤더 필드의 데이터를 매개 변수, 필드 또는ans 속성에 삽입하는 데 사용됩니다. 값이 추출되어 리소스 구현에 삽입되는 HTTP 헤더 필드의 이름을 지정하는 단일 매개변수가 있습니다. 연결된 매개변수, 필드 또는 8080 속성은 “지원되는 데이터 유형” 에 설명된 데이터 유형을 준수해야 합니다.

If- Cryostat-Since 헤더 삽입 클래스의 가장 오래된Date 필드에 HTTP If- Cryostat- since 헤더의 값을 삽입하는 코드를 표시합니다.

If- Cryostat-Since 헤더 삽입

import javax.ws.rs.HeaderParam;
...
class RecordKeeper
{
  ...
  @HeaderParam("If-Modified-Since")
  String oldestDate;
  ...
}
Copy to Clipboard Toggle word wrap

47.2.3.3. 쿠키에서 정보 삽입

쿠키는 특별한 유형의 HTTP 헤더입니다. 이는 첫 번째 요청에서 리소스 구현에 전달되는 하나 이상의 이름/값 쌍으로 구성됩니다. 첫 번째 요청 후 쿠키는 각 메시지와 함께 공급자와 소비자 간에 전달됩니다. 사용자가 요청을 생성하기 때문에 사용자만 쿠키를 변경할 수 있습니다. 쿠키는 일반적으로 여러 요청/응답 시퀀스에서 세션을 유지 관리하고, 사용자 설정을 저장하고, 유지할 수 있는 기타 데이터를 유지하는 데 사용됩니다.

javax.ws.rs.CookieParam 주석은 쿠키 필드에서 값을 추출하여 리소스 구현에 삽입합니다. 값을 추출할 쿠키 필드의 이름을 지정하는 단일 매개변수를 사용합니다. “지원되는 데이터 유형” 에 나열된 데이터 유형 외에도 @ Cookie Param 로 데코레이팅된 엔터티도 오브젝트일 수 있습니다.

예 47.6. “쿠키 삽입” CB 클래스의 필드에 handle 쿠키의 값을 삽입하는 코드를 표시합니다.

예 47.6. 쿠키 삽입

import javax.ws.rs.CookieParam;
...
class CB
{
  ...
  @CookieParam("handle")
  String handle;
  ...
}
Copy to Clipboard Toggle word wrap
47.2.3.4. 오류 처리

HTTP 메시지 삽입 주석 중 하나를 사용하여 데이터를 삽입하려고 할 때 오류가 발생하면 원래 예외를 래핑하는 WebApplicationException 예외가 생성됩니다. WebApplicationException 예외 상태는 400 으로 설정됩니다.

47.2.4. HTML 양식에서 데이터 삽입

47.2.4.1. 개요

HTML 양식은 사용자로부터 정보를 얻는 쉬운 수단이며 쉽게 만들 수 있습니다. 양식 데이터는 HTTP GET 요청 및 HTTP POST 요청에 사용할 수 있습니다.

GET
양식 데이터가 HTTP GET 요청의 일부로 전송되면 데이터가 쿼리 매개변수 세트로 URI에 추가됩니다. 쿼리 매개변수의 데이터를 삽입하는 방법은 “쿼리 매개변수 사용” 에서 설명합니다.
POST
양식 데이터가 HTTP POST 요청의 일부로 전송되면 데이터가 HTTP 메시지 본문에 배치됩니다. 양식 데이터는 양식 데이터를 지원하는 일반 엔티티 매개 변수를 사용하여 처리할 수 있습니다. @FormParam 주석을 사용하여 데이터를 추출하고 해당 조각을 리소스 메서드 매개변수에 삽입하여 처리할 수도 있습니다.
47.2.4.2. @FormParam 주석을 사용하여 양식 데이터 삽입

javax.ws.rs.FormParam 주석은 양식 데이터에서 필드 값을 추출하고 해당 값을 리소스 메서드 매개변수에 삽입합니다. 이 주석은 단일 매개변수를 사용하여 값을 추출하는 필드의 키를 지정합니다. 관련 매개변수는 “지원되는 데이터 유형” 에 설명된 데이터 유형을 준수해야 합니다.

중요

Cryostat-RS API Javadoc은 @FormParam 주석을 필드, 메서드 및 매개변수에 배치할 수 있음을 나타냅니다. 그러나 @FormParam 주석은 리소스 메서드 매개변수에 배치될 때만 의미가 있습니다.

47.2.4.3. 예제

리소스 메서드 매개변수에 데이터 삽입 양식 데이터를 매개 변수에 삽입하는 리소스 메서드를 표시합니다. 이 메서드는 클라이언트의 폼에 문자열 데이터를 포함하는 세 가지 필드제목,태그본문을포함하는 것으로 가정합니다.

리소스 메서드 매개변수에 데이터 삽입

import javax.ws.rs.FormParam;
import javax.ws.rs.POST;

...
@POST
public boolean updatePost(@FormParam("title") String title,
                          @FormParam("tags") String tags,
                          @FormParam("body") String post)
{
  ...
}
Copy to Clipboard Toggle word wrap

47.2.5. 삽입할 기본값 지정

47.2.5.1. 개요

보다 강력한 서비스 구현을 위해 선택적 매개변수를 기본값으로 설정할 수 있습니다. 이는 긴 URI 문자열을 입력하기 때문에 쿼리 매개변수 및 매트릭스 매개변수에서 가져온 값에 특히 유용할 수 있습니다. 또한 요청하는 시스템에 모든 값을 설정할 수 있는 적절한 정보가 없을 수 있으므로 쿠키에서 추출된 매개변수에 대한 기본값을 설정할 수도 있습니다.

javax.ws.rs.DefaultValue 주석은 다음 삽입 주석과 함께 사용할 수 있습니다.

  • @PathParam
  • @QueryParam
  • @MatrixParam
  • @FormParam
  • @HeaderParam
  • @CookieParam

@DefaultValue 주석은 주입 주석에 해당하는 데이터가 요청에 없는 경우 사용할 기본값을 지정합니다.

47.2.5.2. 구문

매개변수의 기본값을 설정하는 구문 @DefaultValue 주석을 사용하는 구문을 표시합니다.

매개변수의 기본값을 설정하는 구문

import javax.ws.rs.DefaultValue;
  ...
  void resourceMethod(@MatrixParam("matrix")
                      @DefaultValue("value)
                      int someValue, ... )
  ...
Copy to Clipboard Toggle word wrap

주석은 매개 변수, 8080 또는 필드 앞에 있어야 합니다. 관련 삽입 주석과 관련된 @DefaultValue 주석의 위치는 중요하지 않습니다.

@DefaultValue 주석은 단일 매개변수를 사용합니다. 주입 주석을 기반으로 적절한 데이터를 추출할 수 없는 경우 이 매개변수는 필드에 삽입되는 값입니다. 값은 모든 문자열 값일 수 있습니다. 값은 연결된 필드 유형과 호환되어야 합니다. 예를 들어, 연결된 필드가 int 유형의 경우 기본값 blue 값은 예외를 생성합니다.

47.2.5.3. 목록 및 세트 처리

주석이 달린 매개 변수 유형인 Quarkus 또는 필드가 List, Set 또는 SortedSet인 경우 결과 컬렉션에는 제공된 기본값에서 매핑된 단일 항목이 포함됩니다.

47.2.5.4. 예제

기본값 설정 다음은 @DefaultValue 를 사용하여 값이 삽입된 필드의 기본값을 지정하는 두 가지 예제를 보여줍니다.

기본값 설정

import javax.ws.rs.DefaultValue;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/monster")
public class MonsterService
{

  @Get
  public Monster getMonster(@QueryParam("id") @DefaultValue("42") int id,
                            @QueryParam("type") @DefaultValue("bogeyman") String type)
  {
    ...
  }

  ...
}
Copy to Clipboard Toggle word wrap

기본값 설정getMonster() 메서드는 GET 요청이 baseURI/monster 로 전송될 때 호출됩니다. 이 메서드에는 URI에 추가되는 두 개의 쿼리 매개 변수 idtype 이 필요합니다. 따라서 URI baseURI/monster?id=1&type=fom Cryostatiri 를 사용하는 GET 요청은 ID가 1인 Fom Cryostatiri를 반환합니다.

@DefaultValue 주석은 두 매개변수 모두에 배치되므로 쿼리 매개변수를 생략하면 getMonster() 메서드가 작동할 수 있습니다. baseURI/monster로 전송되는 GET 요청은 URI baseURI /monster?id=42&type=bogeyman 을 사용하여 GET 요청과 동일합니다.

47.2.6. Java Cryostat에 매개변수 삽입

47.2.6.1. 개요

REST를 통해 HTML 양식을 게시할 때 서버 측의 일반적인 패턴은 양식으로 수신된 모든 데이터(및 다른 매개 변수 및 HTML 헤더의 데이터일 수 있음)를 캡슐화하는 Java 빈을 만드는 것입니다. 일반적으로 이 Java 8080 생성은 두 가지 단계 프로세스입니다. 리소스 메서드는 삽입을 통해 양식 값(예: 메서드 매개 변수에 @FormParam 주석을 추가하여)을 수신하며, 리소스 메서드는 form 데이터를 전달하여,ans의 생성자를 호출합니다.

Cryostat-RS 2.0 @BeanParam 주석을 사용하면 이 패턴을 단일 단계로 구현할 수 있습니다. 양식 데이터는 빈 클래스의 필드에 직접 삽입할 수 있으며, 8080 자체는 Cryostat-RS 런타임을 통해 자동으로 생성됩니다. 예를 들어 가장 쉽게 설명할 수 있습니다.

47.2.6.2. target

@BeanParam 주석은 리소스 메서드 매개변수, 리소스 필드 또는ans 속성에 연결할 수 있습니다. 그러나 매개 변수 대상은 모든 리소스 클래스 라이프사이클에 사용할 수 있는 유일한 종류의 대상입니다. 다른 종류의 대상은 요청별 라이프사이클로 제한됩니다. 이 상황은 표 47.1. “@BeanParamParam Targets” 에 요약되어 있습니다.

Expand
표 47.1. @BeanParamParam Targets
대상리소스 클래스 라이프사이클

매개변수

All

필드

요청당 (기본값)

METHOD (속성)

요청당 (기본값)

47.2.6.3. CryostatParam 주석이 없는 예

다음 예제에서는 @BeanParam을 사용하지 않고 기존 접근 방식을 사용하여 Java 8080에서 양식 데이터를 캡처하는 방법을 보여줍니다.

// Java
import javax.ws.rs.POST;
import javax.ws.rs.FormParam;
import javax.ws.rs.core.Response;
...
@POST
public Response orderTable(@FormParam("orderId")  String orderId,
                           @FormParam("color")    String color,
                           @FormParam("quantity") String quantity,
                           @FormParam("price")    String price)
{
    ...
    TableOrder bean = new TableOrder(orderId, color, quantity, price);
    ...
    return Response.ok().build();
}
Copy to Clipboard Toggle word wrap

이 예에서 orderTable 방법은 조각 모음 웹 사이트에서 테이블 수를 주문하는 데 사용되는 양식을 처리합니다. 주문 폼이 게시되면 양식 값이 orderTable 메서드의 매개 변수에 삽입되고 orderTable 메서드는 삽입된 양식 데이터를 사용하여 TableOrder 클래스의 인스턴스를 명시적으로 만듭니다.

47.2.6.4. CryostatParam 주석의 예

이전 예제를 리팩토링하여 @BeanParam 주석을 활용할 수 있습니다. @BeanParam 접근 방식을 사용하는 경우 form 매개변수를 빈 클래스인 TableOrder 의 필드에 직접 삽입할 수 있습니다. 사실, @PathParam,@QueryParam,@FormParam,@MatrixParam,@CookieParam, @HeaderParam , @HeaderParam 을 포함하여, 8080 클래스의 표준 Cryostat-RS 매개변수 주석을 사용할 수 있습니다. 폼을 처리하기 위한 코드는 다음과 같이 리팩토링할 수 있습니다.

// Java
import javax.ws.rs.POST;
import javax.ws.rs.FormParam;
import javax.ws.rs.core.Response;
...
public class TableOrder {
    @FormParam("orderId")
    private String orderId;

    @FormParam("color")
    private String color;

    @FormParam("quantity")
    private String quantity;

    @FormParam("price")
    private String price;

    // Define public getter/setter methods
    // (Not shown)
    ...
}
...
@POST
public Response orderTable(@BeanParam TableOrder orderBean)
{
    ...
    // Do whatever you like with the 'orderBean' bean
    ...
    return Response.ok().build();
}
Copy to Clipboard Toggle word wrap

이제 빈 클래스인 TableOrder에 양식 주석이 추가되었으므로 리소스 메서드 서명의 모든 @FormParam 주석을 다음과 같이 단일 @BeanParam 주석으로 교체할 수 있습니다. 이제 폼이 orderTable 리소스 메서드에 게시되면, Cryostat-RS 런타임은 TableOrder 인스턴스인 orderBean 을 자동으로 생성하고, Cryostat 클래스의 매개 변수 주석으로 지정된 모든 데이터를 삽입합니다.

47.3. 매개변수입니다.

47.3.1. 개요

매개 변수 변환기를 사용하면 모든 유형의 필드,ans 속성 또는 리소스 메서드 인수에 매개 변수( 문자열 유형)를 삽입할 수 있습니다. 적절한 매개 변수 변환기를 구현하고 바인딩하면 parameter String 값을 대상 유형으로 변환할 수 있도록 Cryostat-RS 런타임을 확장할 수 있습니다.

47.3.2. 자동 변환

매개 변수는 String 의 인스턴스로 수신되므로 항상 문자열 유형의 필드, 빈 속성 및 메서드 매개 변수에 직접 삽입할 수 있습니다. 또한 Cryostat-RS 런타임에는 매개변수 문자열을 다음 유형으로 자동으로 변환하는 기능이 있습니다.

  1. 기본 유형.
  2. 단일 문자열 인수를 허용하는 생성자가 있는 형식입니다.Types that have a constructor that accepts a single string argument.
  3. 형식의 인스턴스를 반환하는 단일 String 인수가 있는 static 메서드 valueOf 또는 fromString 이 있는 형식입니다.Types that have a static method named valueOf or fromString with a single string argument that returns an instance of the type.
  4. T가 2 또는 3에 설명된 유형 중 하나인 경우 list < T >, Set< T > 또는 SortedSet <T> .

47.3.3. 매개변수 변환기

자동 변환이 적용되지 않는 형식에 매개 변수를 삽입하려면 유형에 대한 사용자 지정 매개 변수 변환기를 정의할 수 있습니다. 매개 변수 변환기는 사용자 지정 형식에서 문자열에서 문자열으로의 변환을 정의하고 사용자 지정 유형에서 문자열으로의 역방향 방향을 정의할 수 있는 확장입니다.A parameter converter is a Cryostat-RS extension that enables you to define conversion from String to a custom type, and also in the reverse direction, from the custom type to a String.

47.3.4. 팩토리 패턴

Cryostat-RS 매개변수 변환기 메커니즘은 팩토리 패턴을 사용합니다. 따라서 매개 변수 변환기를 직접 등록하는 대신 필요에 따라 매개 변수 변환기(유형, javax.ws.rs.ext.ParamConverterProvider)를 등록하여 매개 변수 변환기(type, javax.ws.rs.ext.ParamConverter)를 생성해야 합니다.

47.3.5. ParamConverter 인터페이스

javax.ws.rs.ext.ParamConverter 인터페이스는 다음과 같이 정의됩니다.

// Java
package javax.ws.rs.ext;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.ws.rs.DefaultValue;

public interface ParamConverter<T> {

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public static @interface Lazy {}

    public T fromString(String value);

    public String toString(T value);
}
Copy to Clipboard Toggle word wrap

자체 ParamConverter 클래스를 구현하려면 이 인터페이스를 구현하여 fromString 메서드를 재정의하고 매개 변수 문자열을 대상 유형으로 변환하려면 toString 메서드(대상 유형을 문자열로 다시 변환)를 수행해야 합니다.

47.3.6. ParamConverterProvider 인터페이스

javax.ws.rs.ext.ParamConverterProvider 인터페이스는 다음과 같이 정의됩니다.

// Java
package javax.ws.rs.ext;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

public interface ParamConverterProvider {
    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation annotations[]);
}
Copy to Clipboard Toggle word wrap

고유한 ParamConverterProvider 클래스를 구현하려면 이 인터페이스를 구현하여 ParamConverter 인스턴스를 생성하는 팩토리 메서드인 getConverter 메서드를 재정의해야 합니다.

47.3.7. 매개변수 변환기 공급자 바인딩

매개변수 변환기 공급자를 애플리케이션에서 사용할 수 있도록 하려면 다음과 같이 @Provider 주석을 사용하여 구현 클래스에 주석을 달아야 합니다.

// Java
...
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;

@Provider
public class TargetTypeProvider implements ParamConverterProvider {
    ...
}
Copy to Clipboard Toggle word wrap

이 주석을 사용하면 배포 중 매개 변수 변환기 공급자가 자동으로 등록됩니다.

47.3.8. 예제

다음 예제에서는 매개 변수 문자열을 TargetType 유형으로 변환할 수 있는 기능이 있는 ParamConverter Provider 및 ParamConverter를 구현하는 방법을 보여줍니다.

// Java
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;

@Provider
public class TargetTypeProvider implements ParamConverterProvider {

    @Override
    public <T> ParamConverter<T> getConverter(
        Class<T> rawType,
        Type genericType,
        Annotation[] annotations
    ) {
        if (rawType.getName().equals(TargetType.class.getName())) {
            return new ParamConverter<T>() {

                @Override
                public T fromString(String value) {
                    // Perform conversion of value
                    // ...
                    TargetType convertedValue = // ... ;
                    return convertedValue;
                }

                @Override
                public String toString(T value) {
                    if (value == null) { return null; }
                    // Assuming that TargetType.toString is defined
                    return value.toString();
                }
            };
        }
        return null;
    }

}
Copy to Clipboard Toggle word wrap

47.3.9. 매개변수 변환기 사용

이제 TargetType의 매개변수 변환기를 정의했으므로 TargetType 필드 및 인수에 매개변수를 직접 삽입할 수 있습니다. 예를 들면 다음과 같습니다.

// Java
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
...
@POST
public Response updatePost(@FormParam("target") TargetType target)
{
  ...
}
Copy to Clipboard Toggle word wrap

47.3.10. 기본값의 지연 변환

매개변수에 기본값을 지정하는 경우( @DefaultValue 주석을 사용하여) 기본값을 즉시 대상 유형으로 변환하는지(기본 동작) 또는 필요한 경우에만 기본값을 변환해야 하는지(lazy 변환)할지 여부를 선택할 수 있습니다. 지연 변환을 선택하려면 대상 유형에 @ParamConverter.Lazy 주석을 추가합니다. 예를 들면 다음과 같습니다.

// Java
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.ext.ParamConverter.Lazy;
...
@POST
public Response updatePost(
    @FormParam("target")
    @DefaultValue("default val")
    @ParamConverter.Lazy
    TargetType target)
{
  ...
}
Copy to Clipboard Toggle word wrap

47.4. Apache CXF 확장 사용

47.4.1. 개요

Apache CXF는 개발자가 일련의 삽입 주석을 단일 주석으로 교체할 수 있는 표준 Cryostat-WS 주입 메커니즘에 대한 확장을 제공합니다. 단일 주석은 주석을 사용하여 추출된 데이터의 필드가 포함된 8080에 배치됩니다. 예를 들어 리소스 메서드에서 id,type, size 라는 세 개의 쿼리 매개 변수를 포함하는 요청 URI가 필요한 경우 단일 @QueryParam 주석을 사용하여 해당 필드가 있는ans에 모든 매개 변수를 삽입할 수 있습니다.

참고

대신 @BeanParam 주석을 사용하는 것이 좋습니다(undercloud-RS 2.0 이후 사용 가능). 표준화된 @BeanParam 접근 방식은 독점 Apache CXF 확장보다 유연하므로 권장되는 대안입니다. 자세한 내용은 47.2.6절. “Java Cryostat에 매개변수 삽입”의 내용을 참조하십시오.

47.4.2. 지원되는 삽입 주석

이 확장은 모든 삽입 매개 변수를 지원하지 않습니다. 다음 항목만 지원합니다.

  • @PathParam
  • @QueryParam
  • @MatrixParam
  • @FormParam

47.4.3. 구문

주석에서 빈에 직렬 삽입을 사용하려면 다음 두 가지 작업을 수행해야 합니다.

  1. 주석의 매개변수를 빈 문자열로 지정합니다. 예를 들어 @PathParam("") 은 URI 템플릿 변수의 시퀀스를 빈으로 직렬화하도록 지정합니다.
  2. 주석이 달린 매개 변수가 삽입되는 값과 일치하는 필드가 있는 8080인지 확인합니다.

47.4.4. 예제

예 47.7. “metrics에 쿼리 매개변수 삽입” 빈에 여러 쿼리 매개 변수를 삽입하는 예를 보여줍니다. 리소스 메서드는 요청 URI에 typeid 라는 두 개의 쿼리 매개 변수를 포함할 것으로 예상합니다. 해당 값은 Monster 8080의 해당 필드에 삽입됩니다.

예 47.7. metrics에 쿼리 매개변수 삽입

import javax.ws.rs.QueryParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
...

@Path("/monstersforhire/")
public class MonsterService
{
  ...
  @POST
  public void updateMonster(@QueryParam("") Monster bean)
  {
    ...
  }
  ...
}

public class Monster
{
  String type;
  String id;

  ...
}
Copy to Clipboard Toggle word wrap

48장. 소비자에 정보 반환

초록

RESTful 요청은 최소한 HTTP 응답 코드를 소비자에게 반환해야 합니다. 대부분의 경우 plain CryostatB 오브젝트 또는 GenericEntity 오브젝트를 반환하여 요청을 충족할 수 있습니다. 리소스 메서드가 응답 엔티티와 함께 추가 메타데이터를 반환해야 하는 경우 Cryostat-RS 리소스 메서드는 필요한 HTTP 헤더 또는 기타 메타데이터를 포함하는 Response 오브젝트를 반환할 수 있습니다.

48.1. 반환 유형

소비자에게 반환되는 정보는 리소스 메서드가 반환하는 정확한 오브젝트 유형을 결정합니다. 이는 명확한 것처럼 보일 수 있지만 Java 반환 개체와 RESTful 소비자로 반환되는 항목 간의 매핑은 일대일가 아닙니다. 최소한 RESTful 소비자는 응답 본문 외에도 유효한 HTTP 반환 코드를 반환해야 합니다. Java 객체에 포함된 데이터의 매핑은 소비자가 기꺼이 수락하는 MIME 유형에 의해 영향을 받습니다.

Java 개체를 RESTful 응답 메시지에 매핑하는 데 관련된 문제를 해결하기 위해 리소스 메서드는 다음 네 가지 유형의 Java 구문을 반환할 수 있습니다.

48.2. 일반 Java 구문 반환

48.2.1. 개요

대부분의 경우 리소스 클래스는 표준 Java 유형, CryostatB 오브젝트 또는 애플리케이션에 엔터티 공급자가 있는 모든 오브젝트를 반환할 수 있습니다. 이러한 경우 런타임은 반환되는 개체의 Java 클래스를 사용하여 MIME 유형 정보를 결정합니다. 또한 런타임은 소비자에게 보낼 적절한 HTTP 반환 코드를 결정합니다.

48.2.2. 반환 가능한 유형

리소스 메서드는 void 또는 엔터티 작성자가 제공되는 Java 유형을 반환할 수 있습니다. 기본적으로 런타임에는 다음에 대한 공급자가 있습니다.

  • Java primitives
  • Java 프리미티브의 숫자 표현
  • CryostatB 오브젝트

“기본적으로 지원되는 유형” 기본적으로 지원되는 모든 반환 유형을 나열합니다. “사용자 정의 작성자” 사용자 지정 엔터티 작성기를 구현하는 방법을 설명합니다.Describes how to implement a custom entity writer.

48.2.3. MIME 유형

런타임은 먼저 리소스 메서드 및 리소스 클래스의 @Produces 주석을 확인하여 반환된 엔터티의 MIME 유형을 결정합니다. 하나를 찾으면 주석에 지정된 MIME 유형을 사용합니다. 리소스 구현에 의해 지정된 항목을 찾지 못하면 엔터티 공급자를 사용하여 적절한 MIME 유형을 결정합니다.

기본적으로 런타임은 다음과 같이 MIME 유형을 할당합니다.

  • Java 프리미티브와 해당 숫자 표현에는 MIME 유형의 application/octet-stream 이 할당됩니다.
  • CryostatB 오브젝트에는 MIME 유형의 application/xml 이 할당됩니다.

애플리케이션은 “사용자 정의 작성자” 에 설명된 대로 사용자 정의 엔티티 공급자를 구현하여 다른 매핑을 사용할 수 있습니다.

48.2.4. 응답 코드

리소스 메서드가 일반 Java 구성을 반환하면 리소스 메서드가 예외를 발생하지 않고 완료하면 런타임에서 응답의 상태 코드를 자동으로 설정합니다. 상태 코드는 다음과 같이 설정됩니다.

  • 204(Content 없음)-리소스 메서드의 반환 유형이 무효화
  • 204(No Content) - 반환된 엔티티의 값은 null입니다.
  • 200(OK)- 반환 된 엔티티의 값은 null이 아닙니다

리소스 메서드 완료 전에 예외가 발생하는 경우 50장. 예외 처리 에 설명된 대로 반환 상태 코드가 설정됩니다.

48.3. 애플리케이션의 응답 미세 조정

48.3.1. 응답 빌드의 기본 사항

48.3.1.1. 개요

RESTful 서비스는 리소스 메서드가 일반 Java 구성을 반환할 때 허용되는 것보다 더 정확한 응답을 소비자에 더 정확하게 제어해야 하는 경우가 많습니다. Cryostat-RS Response 클래스를 사용하면 리소스 메서드가 소비자에게 전송된 반환 상태를 일부 제어하고 응답에서 HTTP 메시지 헤더 및 쿠키를 지정할 수 있습니다.

응답 오브젝트는 소비자로 반환되는 엔티티를 나타내는 오브젝트를 래핑합니다. Response 개체는 ResponseBuilder 클래스를 팩토리로 사용하여 인스턴스화됩니다.

ResponseBuilder 클래스에는 응답의 메타데이터를 조작하는 데 사용되는 많은 메서드도 있습니다. 예를 들어 ResonseBuilder 클래스에는 HTTP 헤더 및 캐시 제어 지시문을 설정하기 위한 메서드가 포함되어 있습니다.

48.3.1.2. 응답과 응답 빌더 간의 관계

Response 클래스에는 보호된 생성자가 있으므로 직접 인스턴스화할 수 없습니다. Response 클래스로 묶은 ResponseBuilder 클래스를 사용하여 생성됩니다. ResponseBuilder 클래스는 생성된 응답에 캡슐화될 모든 정보의 소유자입니다. ResponseBuilder 클래스에는 메시지에서 HTTP 헤더 속성을 설정하는 모든 메서드가 있습니다.

Response 클래스는 적절한 응답 코드를 쉽게 설정하고 엔터티를 래핑하는 몇 가지 메서드를 제공합니다. 공통 응답 상태 코드 각각에 대한 메서드가 있습니다. 엔터티 본문 또는 필수 메타데이터를 포함하는 상태에 해당하는 메서드에는 해당 정보를 연결된 응답 빌더로 직접 설정할 수 있는 버전이 포함됩니다.

ResponseBuilder 클래스의 build() 메서드는 메서드가 호출될 때 응답 빌더에 저장된 정보가 포함된 응답 오브젝트를 반환합니다. 응답 오브젝트가 반환되면 응답 빌더가 clean 상태로 반환됩니다.

48.3.1.3. 응답 빌더 가져오기

응답 빌더를 가져오는 방법은 다음 두 가지가 있습니다.

  • Response 클래스를 사용하여 응답 빌더 가져오기 에 표시된 대로 Response 클래스의 정적 메서드를 사용합니다.

    Response 클래스를 사용하여 응답 빌더 가져오기

    import javax.ws.rs.core.Response;
    
    Response r = Response.ok().build();
    Copy to Clipboard Toggle word wrap

    이러한 방식으로 응답 빌더를 가져올 때 여러 단계에서 조작할 수 있는 인스턴스에 액세스할 수 없습니다. 모든 작업을 단일 메서드 호출으로 문자열을 지정해야 합니다.

  • Apache CXF 특정 ResponseBuilderImpl 클래스 사용. 이 클래스를 사용하면 응답 빌더에서 직접 작업할 수 있습니다. 그러나 모든 응답 빌더 정보를 수동으로 설정해야 합니다.

    예 48.1. “ResponseBuilderImpl 클래스를 사용하여 응답 빌더 가져오기” ResponseBuilderImpl 클래스를 사용하여 Response 클래스를 사용하여 응답 빌더 가져오기 를 다시 작성하는 방법을 보여줍니다.

    예 48.1. ResponseBuilderImpl 클래스를 사용하여 응답 빌더 가져오기

    import javax.ws.rs.core.Response;
    import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;
    
    ResponseBuilderImpl builder = new ResponseBuilderImpl();
    builder.status(200);
    Response r = builder.build();
    Copy to Clipboard Toggle word wrap
    참고

    Response 클래스의 메서드에서 ResponseBuilder 로 반환된 ResponseBuilder를 Response Builder 개체로 간단히 할당할 수도 있습니다.

48.3.1.4. 더 많은 정보

Response 클래스에 대한 자세한 내용은 Response 클래스의 Javadoc 을 참조하십시오.

ResponseBuilder 클래스에 대한 자세한 내용은 ResponseBuilder 클래스의 Javadoc 을 참조하십시오.

Apache CXF ResponseBuilderIml 클래스에 대한 자세한 내용은 ResponseBuilderImpl Javadoc.

48.3.2. 일반적인 사용 사례에 대한 응답 생성

48.3.2.1. 개요

Response 클래스는 RESTful 서비스에 필요한 더 일반적인 응답을 처리하기 위한 바로 가기 메서드를 제공합니다. 이러한 메서드는 제공된 값 또는 기본값을 사용하여 적절한 헤더 설정을 처리합니다. 또한 적절한 경우 엔티티의 채우기를 처리합니다.

48.3.2.2. 성공적인 요청에 대한 응답 생성

요청이 성공적으로 처리되면 애플리케이션은 요청이 충족되었음을 확인하는 응답을 보내야 합니다. 이 응답에는 엔티티가 포함될 수 있습니다.

응답을 성공적으로 완료할 때 가장 일반적인 응답은 OK 입니다. OK 응답에는 일반적으로 요청에 해당하는 엔티티가 포함됩니다. Response 클래스에는 응답 상태를 200 으로 설정하고 포함된 응답 빌더에 제공된 엔터티를 추가하는 오버로드된 ok() 메서드가 있습니다. ok() 메서드의 5 가지 버전이 있습니다. 가장 일반적으로 사용되는 변형은 다음과 같습니다.

  • response .ok()- status 200 및 빈 엔터티 본문으로 응답을 생성합니다.
  • response .ok(java.lang.Object 엔티티)- 200 상태의 응답을 생성하고, 제공된 오브젝트를 응답 엔티티 본문에 저장하고, 오브젝트를 인트로스펙션하여 엔터티 미디어 유형을 결정합니다.

200 응답으로 응답 생성 OK 상태로 응답을 생성하는 예를 보여줍니다.

200 응답으로 응답 생성

import javax.ws.rs.core.Response;
import demo.jaxrs.server.Customer;
...

Customer customer = new Customer("Jane", 12);

return Response.ok(customer).build();
Copy to Clipboard Toggle word wrap

요청자가 엔티티 본문을 원하지 않는 경우 200 OK 상태 대신 204 No Content 상태를 보내는 것이 더 적합할 수 있습니다. Response.noContent() 메서드는 적절한 응답 오브젝트를 생성합니다.

204 status로 응답 생성 204 상태의 응답을 생성하는 예를 보여줍니다.

204 status로 응답 생성

import javax.ws.rs.core.Response;

return Response.noContent().build();
Copy to Clipboard Toggle word wrap

48.3.2.3. 리디렉션을 위한 응답 생성

Response 클래스는 리디렉션 응답 상태 세 개를 처리하기 위한 메서드를 제공합니다.

303 기타 보기

303 Other 상태는 요청된 리소스가 요청을 처리하기 위해 소비자를 새 리소스로 영구적으로 리디렉션해야 하는 경우 유용합니다.

Response 클래스 seeOther() 메서드는 303 상태로 응답을 생성하고 메시지의 위치 필드에 새 리소스 URI를 배치합니다. seeOther() 메서드는 새 URI를 java.net.URI 오브젝트로 지정하는 단일 매개변수를 사용합니다.

Cryostat가 아닙니다.

Cryo stat Not Cryostat 상태는 요청의 특성에 따라 다양한 작업에 사용할 수 있습니다. 이전 GET 요청 이후 요청된 리소스가 변경되지 않았음을 나타내는 데 사용할 수 있습니다. 또한 리소스를 수정 요청으로 인해 리소스가 변경되지 않았음을 나타내는 데 사용할 수도 있습니다.

Response 클래스 not Cryostat() 메서드는 Cryostat 상태로 응답을 생성하고 HTTP 메시지에서 수정된 날짜 속성을 설정합니다. not Cryostat() 메서드의 세 가지 버전이 있습니다.

  • notModified
  • notModifiedjavax.ws.rs.core.Entitytag
  • notModifiedjava.lang.Stringtag
307 임시 리디렉션

307 임시 리디렉션 상태는 요청된 리소스가 소비자를 새 리소스로 전달해야 하지만 소비자가 이 리소스를 계속 사용하여 향후 요청을 처리하기를 원하는 경우 유용합니다.

Response 클래스 temporaryRedirect() 메서드는 307 상태의 응답을 생성하고 새 리소스 URI를 메시지의 위치 필드에 배치합니다. temporaryRedirect() 메서드는 새 URI를 java.net.URI 오브젝트로 지정하는 단일 매개변수를 사용합니다.

Cryostat 상태로 응답 생성 Cryostat 상태로 응답을 생성하는 예를 보여줍니다.

Cryostat 상태로 응답 생성

import javax.ws.rs.core.Response;

return Response.notModified().build();
Copy to Clipboard Toggle word wrap

48.3.2.4. 신호 오류에 대한 응답 생성

Response 클래스는 두 가지 기본 처리 오류에 대한 응답을 생성하는 메서드를 제공합니다.

  • serverError-creates a response with a status of 500 Internal Server Error.
  • notcceptablejava.util.List<javax.ws.rs.core.Variant>변형- 허용 가능한 리소스 유형 목록을 포함하는 엔터티 본문 406 Not Acceptable 상태로 응답을 생성합니다.

500 status로 응답 생성 500 상태의 응답을 생성하는 예를 보여줍니다.

500 status로 응답 생성

import javax.ws.rs.core.Response;

return Response.serverError().build();
Copy to Clipboard Toggle word wrap

48.3.3. 고급 응답 처리

48.3.3.1. 개요

Response 클래스 메서드는 일반적인 사례에 대한 응답을 생성하기 위한 짧은 컷을 제공합니다. 캐시 제어 지시문을 지정하거나 사용자 지정 HTTP 헤더를 추가하거나 Response 클래스에서 처리되지 않은 상태를 보내는 등 더 복잡한 케이스를 처리해야 하는 경우 Response Builder 클래스 메서드를 사용하여 response () 메서드를 사용하여 응답 오브젝트를 생성하기 전에 응답을 채워야 합니다.

“응답 빌더 가져오기” 에서 설명한 대로 Apache CXF ResponseBuilderImpl 클래스를 사용하여 직접 조작할 수 있는 응답 빌더 인스턴스를 생성할 수 있습니다.

48.3.3.2. 사용자 정의 헤더 추가

사용자 지정 헤더는 ResponseBuilder 클래스의 header() 메서드를 사용하여 응답에 추가됩니다. header() 메서드는 다음 두 매개변수를 사용합니다.

  • name-a string that specifies the name of the header
  • value- 헤더에 저장된 데이터를 포함하는 Java 오브젝트

header() 메서드를 반복적으로 호출하여 메시지에 여러 헤더를 설정할 수 있습니다.

응답에 헤더 추가 응답에 헤더를 추가하기 위한 코드를 표시합니다.

응답에 헤더 추가

import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.header("username", "joe");
Response r = builder.build();
Copy to Clipboard Toggle word wrap

48.3.3.3. 쿠키 추가

사용자 지정 헤더는 ResponseBuilder 클래스의 cookie() 메서드를 사용하여 응답에 추가됩니다. cookie() 메서드는 하나 이상의 쿠키를 사용합니다. 각 쿠키는 javax.ws.rs.core.NewCookie 오브젝트에 저장됩니다. NewCookie 클래스의 컨트랙터 중 가장 쉬운에는 두 가지 매개변수가 필요합니다.

  • name- 쿠키 이름을 지정하는 문자열
  • value-a cookie 값을 지정하는 문자열

cookie() 메서드를 반복적으로 호출하여 여러 쿠키를 설정할 수 있습니다.

응답에 쿠키 추가 는 응답에 쿠키를 추가하기 위한 코드를 표시합니다.

응답에 쿠키 추가

import javax.ws.rs.core.Response;
import javax.ws.rs.core.NewCookie;

NewCookie cookie = new NewCookie("username", "joe");

Response r = Response.ok().cookie(cookie).build();
Copy to Clipboard Toggle word wrap

주의

null 매개 변수 목록을 사용하여 cookie() 메서드를 호출하면 이미 응답과 연결된 모든 쿠키가 지워집니다.

48.3.3.4. 응답 상태 설정

Response 클래스의 도우미 메서드에서 지원하는 상태 중 하나가 아닌 상태를 반환하려면 Response Builder 클래스의 status() 메서드를 사용하여 응답의 상태 코드를 설정할 수 있습니다. status() 메서드에는 두 가지 변형이 있습니다. 하나는 응답 코드를 지정하는 int 를 사용합니다. 다른 하나는 Response.Status 오브젝트를 사용하여 응답 코드를 지정합니다.

Response.Status 클래스는 Response 클래스로 묶은 열거입니다. 정의된 HTTP 응답 코드의 대부분에 대한 항목이 있습니다.

응답에 헤더 추가 404 Not Found 로 응답 상태를 설정하는 코드를 표시합니다.

응답에 헤더 추가

import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.status(404);
Response r = builder.build();
Copy to Clipboard Toggle word wrap

48.3.3.5. 캐시 제어 지시문 설정

ResponseBuilder 클래스의 cacheControl() 메서드를 사용하면 응답에서 캐시 제어 헤더를 설정할 수 있습니다. cacheControl() 메서드는 응답에 대한 캐시 제어 지시문을 지정하는 javax.ws.rs.CacheControl 개체를 사용합니다.

CacheControl 클래스에는 HTTP 사양에서 지원하는 모든 캐시 제어 지시문에 해당하는 메서드가 있습니다. 여기서 지시문은 setter 메서드에서 부울 값을 사용하는 단순한 값 또는 오프 값입니다. 지시문에 max-age 지시문과 같은 숫자 값이 필요한 경우 setter는 int 값을 사용합니다.

응답에 헤더 추가 no-store 캐시 제어 지시문을 설정하기 위한 코드를 표시합니다.

응답에 헤더 추가

import javax.ws.rs.core.Response;
import javax.ws.rs.core.CacheControl;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

CacheControl cache = new CacheControl();
cache.setNoCache(true);

ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.cacheControl(cache);
Response r = builder.build();
Copy to Clipboard Toggle word wrap

48.4. 일반 유형 정보를 사용하여 엔터티 반환

48.4.1. 개요

애플리케이션에 반환된 개체의 MIME 유형 또는 응답을 직렬화하는 데 사용되는 엔터티 공급자를 더 많이 제어해야 하는 경우가 있습니다. Cryostat-RS javax.ws.core.GenericEntity<T > 클래스는 엔터티를 나타내는 개체의 일반 유형을 지정하는 메커니즘을 제공하여 엔터티 직렬화에 대한 세분화된 제어를 제공합니다.

48.4.2. GenericEntity 오브젝트 사용

응답을 직렬화하는 엔터티 공급자를 선택하는 데 사용되는 기준 중 하나는 오브젝트의 일반 유형입니다. 오브젝트의 일반 유형은 오브젝트의 Java 유형을 나타냅니다. 공통 Java 유형 또는 CryostatB 개체가 반환되면 런타임에서 Java 리플렉션을 사용하여 일반 유형을 결정할 수 있습니다. 그러나 Cryostat-RS Response 개체가 반환되면 런타임에서 래핑된 엔터티의 일반 유형을 확인할 수 없으며 개체의 실제 Java 클래스가 Java 유형으로 사용됩니다.

엔터티 공급자가 올바른 일반 유형 정보를 제공하도록 엔터티를 GenericEntity<T > 개체로 래핑하여 반환된 Response 개체에 추가할 수 있습니다.

리소스 메서드는 GenericEntity<T > 오브젝트를 직접 반환할 수도 있습니다. 실제로 이 방법은 거의 사용되지 않습니다. GenericEntity<T > 개체에 래핑된 엔터티에 대해 저장된 일반 유형 정보와 래핑되지 않은 엔티티의 반영에 의해 결정된 일반 유형 정보는 일반적으로 동일합니다.

48.4.3. GenericEntity 오브젝트 생성

GenericEntity<T > 개체를 만드는 방법은 다음 두 가지가 있습니다.

  1. 래핑되는 엔터티를 사용하여 GenericEntity<T& gt; 클래스의 하위 클래스를 만듭니다. 하위 클래스를 사용하여 GenericEntity<T> 오브젝트 생성 런타임 시 일반 유형을 사용할 수 있는 List<String > 유형의 엔터티가 포함된 GenericEntity<T > 개체를 만드는 방법을 보여줍니다.

    하위 클래스를 사용하여 GenericEntity<T> 오브젝트 생성

    import javax.ws.rs.core.GenericEntity;
    
    List<String> list = new ArrayList<String>();
    ...
    GenericEntity<List<String>> entity =
      new GenericEntity<List<String>>(list) {};
    Response response = Response.ok(entity).build();
    Copy to Clipboard Toggle word wrap

    GenericEntity<T > 개체를 만드는 데 사용되는 하위 클래스는 일반적으로 익명입니다.

  2. 엔터티에 일반 유형 정보를 제공하여 인스턴스를 직접 생성합니다. 예 48.2. “GenericEntity<T> 오브젝트 직접 인스턴스화” AtomicInteger 유형의 엔티티가 포함된 응답을 만드는 방법을 보여줍니다.

    예 48.2. GenericEntity<T> 오브젝트 직접 인스턴스화

    import javax.ws.rs.core.GenericEntity;
    
    AtomicInteger result = new AtomicInteger(12);
    GenericEntity<AtomicInteger> entity =
      new GenericEntity<AtomicInteger>(result,
                                          result.getClass().getGenericSuperclass());
    Response response = Response.ok(entity).build();
    Copy to Clipboard Toggle word wrap

48.5. 비동기 응답

48.5.1. 서버에서 비동기 처리

48.5.1.1. 개요

서버 측에서 호출을 비동기적으로 처리하는 목적은 스레드를 보다 효율적으로 사용할 수 있고, 궁극적으로 서버의 모든 요청 스레드가 차단되므로 클라이언트 연결 시도가 거부되는 시나리오를 방지하는 것입니다. 비동기적으로 호출이 처리되면 요청 스레드가 거의 즉시 해제됩니다.

참고

서버 측에서 비동기 처리가 활성화된 경우에도 클라이언트는 서버에서 응답을 수신할 때까지 차단된 상태로 유지됩니다. 클라이언트 측에서 비동기 동작을 보려면 클라이언트 측 비동기 처리를 구현해야 합니다. 49.6절. “클라이언트에서 비동기 처리”을 참조하십시오.

48.5.1.2. 비동기 처리를 위한 기본 모델

그림 48.1. “비동기 처리를 위한 스레드 모델” 서버 측에서 비동기 처리를 위한 기본 모델의 개요를 보여줍니다.

그림 48.1. 비동기 처리를 위한 스레드 모델

asyncresponse 01

개요에서는 비동기 모델에서 다음과 같이 요청이 처리됩니다.In outline, a request is processed as follows in the asynchronous model:

  1. 비동기 리소스 메서드는 요청 스레드 내에서 호출되며 나중에 응답을 보내는 데 필요한 AsyncResponse 오브젝트에 대한 참조를 수신합니다.
  2. 리소스 메서드는 요청을 처리하는 데 필요한 모든 정보 및 처리 논리를 포함하는 Runnable 오브젝트로 일시 중지된 요청을 캡슐화합니다.
  3. 리소스 메서드는 실행 가능한 오브젝트를 executor 스레드 풀의 차단 대기열에 푸시합니다.
  4. 이제 리소스 메서드가 반환될 수 있으므로 요청 스레드가 확보됩니다.
  5. Runnable 개체가 큐의 맨 위에 도달하면 executor 스레드 풀의 스레드 중 하나에 의해 처리됩니다. 그런 다음 캡슐화된 AsyncResponse 오브젝트를 사용하여 응답을 클라이언트에 다시 보냅니다.
48.5.1.3. Java executor를 사용한 스레드 풀 구현

java.util.concurrent API는 전체 스레드 풀 구현을 매우 쉽게 생성할 수 있는 강력한 API입니다. Java 동시성 API의 용어에서 스레드 풀은 executor 라고 합니다. 작업 스레드와 피드를 제공하는 차단 대기열을 포함하여 전체 작업 스레드 풀을 생성하려면 한 줄의 코드만 필요합니다.

예를 들어 그림 48.1. “비동기 처리를 위한 스레드 모델” 에 표시된 Executor Thread Pool 과 같은 전체 작업 스레드 풀을 생성하려면 다음과 같이 java.util.concurrent.Executor 인스턴스를 생성합니다.

Executor executor = new ThreadPoolExecutor(
    5,                                    // Core pool size
    5,                                    // Maximum pool size
    0,                                    // Keep-alive time
    TimeUnit.SECONDS,                     // Time unit
    new ArrayBlockingQueue<Runnable>(10)  // Blocking queue
);
Copy to Clipboard Toggle word wrap

이 생성자는 최대 10개의 실행 가능한 개체를 보유할 수 있는 단일 차단 큐로 5개의 스레드가 있는 새 스레드 풀을 생성합니다. 작업을 스레드 풀에 제출하려면 executor.execute 메서드를 호출하여 비동기 작업을 캡슐화하는 실행 가능한 개체에 대한 참조를 전달합니다.

48.5.1.4. 비동기 리소스 메서드 정의

비동기적인 리소스 메서드를 정의하려면 @Suspended 주석을 사용하여 javax.ws.rs.container.AsyncResponse 유형의 인수를 삽입하고 메서드에서 void 를 반환하는지 확인합니다. 예를 들면 다음과 같습니다.

// Java
...
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;

@Path("/bookstore")
public class BookContinuationStore {
    ...
    @GET
    @Path("{id}")
    public void handleRequestInPool(@PathParam("id") String id,
                                    @Suspended AsyncResponse response) {
        ...
    }
    ...
}
Copy to Clipboard Toggle word wrap

삽입된 AsyncResponse 오브젝트는 나중에 응답을 반환하는 데 사용되므로 리소스 메서드에서 void 를 반환해야 합니다.

48.5.1.5. AsyncResponse 클래스

javax.ws.rs.container.AsyncResponse 클래스는 들어오는 클라이언트 연결에 대한 추상 처리를 제공합니다. AsyncResponse 오브젝트가 리소스 메서드에 삽입되면 기본 TCP 클라이언트 연결이 처음에 일시 중지된 상태입니다. 나중에 응답을 반환할 준비가 되면 AsyncResponse 인스턴스에서 resume 를 호출하여 기본 TCP 클라이언트 연결을 다시 활성화하고 응답을 다시 전달할 수 있습니다. 또는 호출을 중단해야 하는 경우 AsyncResponse 인스턴스에서 cancel 을 호출할 수 있습니다.

48.5.1.6. 일시 중지된 요청을 실행 가능으로 캡슐화

그림 48.1. “비동기 처리를 위한 스레드 모델” 에 표시된 비동기 처리 시나리오에서는 일시 중지된 요청을 나중에 전용 스레드 풀에서 처리할 수 있는 대기열로 푸시합니다. 그러나 이 방법이 작동하려면 개체에서 일시 중지된 요청을 캡슐화하 는 방법이 있어야 합니다. 일시 중단된 요청 오브젝트는 다음 사항을 캡슐화해야 합니다.

  • 들어오는 요청의 매개 변수(있는 경우)입니다.
  • 들어오는 클라이언트 연결에 대한 처리와 응답을 다시 보내는 방법을 제공하는 AsyncResponse 오브젝트입니다.
  • 호출 논리입니다.

이러한 항목을 캡슐화하는 편리한 방법은 Runnable 클래스를 정의하여 일시 중지된 요청을 나타내는 것입니다. 여기서 Runnable.run() 메서드는 호출의 논리를 캡슐화합니다. 이 작업을 수행하는 가장 좋은 방법은 다음 예제와 같이 Runnable 을 로컬 클래스로 구현하는 것입니다.

48.5.1.7. 비동기 처리 예

비동기 처리 시나리오를 구현하려면 리소스 메서드의 구현에서 실행 가능한 개체(부팅된 요청을 표시)를 executor 스레드 풀에 전달해야 합니다. Java 7 및 8에서는 다음 예와 같이 Runnable 클래스를 로컬 클래스로 정의하기 위해 몇 가지 새로운 구문을 악용할 수 있습니다.

// Java
package org.apache.cxf.systest.jaxrs;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.CompletionCallback;
import javax.ws.rs.container.ConnectionCallback;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.container.TimeoutHandler;

import org.apache.cxf.phase.PhaseInterceptorChain;

@Path("/bookstore")
public class BookContinuationStore {

    private Map<String, String> books = new HashMap<String, String>();
    private Executor executor = new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS,
                                        new ArrayBlockingQueue<Runnable>(10));

    public BookContinuationStore() {
        init();
    }
    ...
    @GET
    @Path("{id}")
    public void handleRequestInPool(final @PathParam("id") String id,
                                    final @Suspended AsyncResponse response) {
        executor.execute(new Runnable() {
            public void run() {
                // Retrieve the book data for 'id'
                // which is presumed to be a very slow, blocking operation
                // ...
                bookdata = ...
                // Re-activate the client connection with 'resume'
                // and send the 'bookdata' object as the response
                response.resume(bookdata);
            }
        });
    }
    ...
}
Copy to Clipboard Toggle word wrap

리소스 메서드 인수인 idresponseRunnable 로컬 클래스의 정의로 바로 전달되는 방법을 확인합니다. 이 특수 구문을 사용하면 로컬 클래스에서 해당 필드를 정의하지 않고도 Runnable.run() 메서드에서 직접 리소스 메서드 인수를 사용할 수 있습니다.

중요

이 특수 구문이 작동하려면 리소스 메서드 매개 변수를 최종 로 선언 해야 합니다( 메서드 구현에서 변경하지 않아야 함).

48.5.2. 시간 초과 및 시간 초과 처리기

48.5.2.1. 개요

비동기 처리 모델은 REST 호출에 시간 초과를 적용할 수 있도록 지원합니다. 기본적으로 시간 초과로 인해 HTTP 오류 응답이 클라이언트에 다시 전송됩니다. 그러나 시간 초과 이벤트에 대한 응답을 사용자 지정할 수 있는 시간 초과 처리기 콜백을 등록할 수도 있습니다.

48.5.2.2. 처리기 없이 시간 초과 설정 예

간단한 호출 시간 초과를 정의하려면 다음 예와 같이 시간 초과 처리기를 지정하지 않고 AsyncResponse 오브젝트에서 setTimeout 메서드를 호출합니다.

// Java
// Java
...
import java.util.concurrent.TimeUnit;
...
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.container.TimeoutHandler;

@Path("/bookstore")
public class BookContinuationStore {
    ...
    @GET
    @Path("/books/defaulttimeout")
    public void getBookDescriptionWithTimeout(@Suspended AsyncResponse async) {
        async.setTimeout(2000, TimeUnit.MILLISECONDS);
        // Optionally, send request to executor queue for processing
        // ...
    }
    ...
}
Copy to Clipboard Toggle word wrap

java.util.concurrent.TimeUnit 클래스의 시간 단위를 사용하여 시간 초과 값을 지정할 수 있습니다. 위 예제에서는 executor 스레드 풀로 요청을 보내는 코드를 표시하지 않습니다. 시간 제한 동작을 테스트하려면 리소스 메서드 본문에 async.SetTimeout 에 대한 호출만 포함할 수 있으며 시간 초과는 모든 호출에 대해 트리거됩니다.

AsyncResponse.NO_TIMEOUT 값은 무한 타임아웃을 나타냅니다.

48.5.2.3. 기본 시간 제한 동작

기본적으로 호출 제한 시간이 트리거되면 Cryostat-RS 런타임에서 ServiceUnavailableException 예외를 발생시키고 상태 503 을 사용하여 HTTP 오류 응답을 다시 보냅니다.

48.5.2.4. TimeoutHandler 인터페이스

시간 초과 동작을 사용자 지정하려면 TimeoutHandler 인터페이스를 구현하여 시간 초과 처리기를 정의해야 합니다.

// Java
package javax.ws.rs.container;

public interface TimeoutHandler {
    public void handleTimeout(AsyncResponse asyncResponse);
}
Copy to Clipboard Toggle word wrap

구현 클래스에서 handleTimeout 메서드를 재정의하면 시간 초과를 처리하는 다음 방법 중에서 선택할 수 있습니다.

  • asyncResponse.cancel 메서드를 호출하여 응답을 취소합니다.
  • 응답 값과 함께 asyncResponse.resume 메서드를 호출하여 응답을 보냅니다.
  • asyncResponse.setTimeout 메서드를 호출하여 대기 기간을 확장합니다. (예를 들어, 10초 이상 대기하기 위해 asyncResponse.setTimeout(10, TimeUnit.SECONDS)을 호출할 수 있습니다.
48.5.2.5. 처리기를 사용하여 시간 초과 설정 예

시간 초과 처리기를 사용하여 호출 시간 초과를 정의하려면 다음 예와 같이 AsyncResponse 오브젝트에서 setTimeout 메서드와 setTimeoutHandler 메서드를 모두 호출합니다.

// Java
...
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.container.TimeoutHandler;

@Path("/bookstore")
public class BookContinuationStore {
    ...
    @GET
    @Path("/books/cancel")
    public void getBookDescriptionWithCancel(@PathParam("id") String id,
                                             @Suspended AsyncResponse async) {
        async.setTimeout(2000, TimeUnit.MILLISECONDS);
        async.setTimeoutHandler(new CancelTimeoutHandlerImpl());
        // Optionally, send request to executor queue for processing
        // ...
    }
    ...
}
Copy to Clipboard Toggle word wrap

여기서 이 예제에서는 호출 시간 초과를 처리하기 위해 CancelTimeoutHandlerImpl 시간 초과 처리기의 인스턴스를 등록합니다.

48.5.2.6. 시간 초과 처리기를 사용하여 응답을 취소

CancelTimeoutHandlerImpl 시간 제한 처리기는 다음과 같이 정의됩니다.

// Java
...
import javax.ws.rs.container.AsyncResponse;
...
import javax.ws.rs.container.TimeoutHandler;

@Path("/bookstore")
public class BookContinuationStore {
    ...
    private class CancelTimeoutHandlerImpl implements TimeoutHandler {

        @Override
        public void handleTimeout(AsyncResponse asyncResponse) {
            asyncResponse.cancel();
        }

    }
    ...
}
Copy to Clipboard Toggle word wrap

AsyncResponse 오브젝트에서 cancel 을 호출하면 HTTP 503(서비스를 사용할 수 없음) 오류 응답을 클라이언트에 전송하는 것입니다. 선택적으로 응답 메시지에서 Retry-After: HTTP 헤더를 설정하는 데 사용되는 cancel 메서드( int 또는 java.util.Date 값)에 인수를 지정할 수 있습니다. 그러나 클라이언트는 종종 Retry-After: 헤더를 무시합니다.

48.5.2.7. 실행 가능한 인스턴스에서 취소된 응답 처리

executor 스레드 풀에서 처리를 위해 대기 중인 요청을 실행 가능한 인스턴스로 캡슐화한 경우 스레드 풀이 요청을 처리하는 동안 AsyncResponse 가 취소되었음을 확인할 수 있습니다. 이러한 이유로 Runnable 인스턴스에 일부 코드를 추가하여 취소된 AsyncResponse 오브젝트에 대처할 수 있습니다. 예를 들면 다음과 같습니다.

// Java
...
@Path("/bookstore")
public class BookContinuationStore {
    ...
    private void sendRequestToThreadPool(final String id, final AsyncResponse response) {

        executor.execute(new Runnable() {
            public void run() {
                if ( !response.isCancelled() ) {
                    // Process the suspended request ...
                    // ...
                }
            }
        });

    }
    ...
}
Copy to Clipboard Toggle word wrap

48.5.3. 삭제된 연결 처리

48.5.3.1. 개요

클라이언트 연결이 끊어진 케이스를 처리하기 위해 콜백을 추가할 수 있습니다.

48.5.3.2. ConnectionCallback 인터페이스

삭제된 연결에 대한 콜백을 추가하려면 다음과 같이 정의된 javax.ws.rs.container.ConnectionCallback 인터페이스를 구현해야 합니다.

// Java
package javax.ws.rs.container;

public interface ConnectionCallback {
    public void onDisconnect(AsyncResponse disconnected);
}
Copy to Clipboard Toggle word wrap
48.5.3.3. 연결 콜백 등록

연결 콜백을 구현한 후 register 방법 중 하나를 호출하여 현재 AsyncResponse 오브젝트에 등록해야 합니다. 예를 들어 다음과 같은 유형의 연결 콜백을 등록하려면 MyConnectionCallback:

asyncResponse.register(new MyConnectionCallback());
Copy to Clipboard Toggle word wrap
48.5.3.4. 연결 콜백을 위한 일반적인 시나리오

일반적으로 연결 콜백을 구현하는 주요 이유는 삭제된 클라이언트 연결과 연결된 리소스를 해제하는 것입니다. 여기서 AsyncResponse 인스턴스를 키로 사용하여 해제해야 하는 리소스를 확인할 수 있습니다.

48.5.4. 콜백 등록

48.5.4.1. 개요

호출이 완료되면 알림을 받기 위해 선택적으로 AsyncResponse 인스턴스에 콜백을 추가할 수 있습니다. 이 콜백을 호출할 수 있는 처리에는 다음 두 가지 대체 지점이 있습니다.

  • 요청 처리가 완료되고 응답이 이미 클라이언트에 다시 전송된 후
  • 요청 처리가 완료되고 매핑되지 않은 Throwable 이 호스팅 I/O 컨테이너로 전파되었습니다.
48.5.4.2. CompletionCallback 인터페이스

완료 콜백을 추가하려면 다음과 같이 정의된 javax.ws.rs.container.CompletionCallback 인터페이스를 구현해야 합니다.

// Java
package javax.ws.rs.container;

public interface CompletionCallback {
    public void onComplete(Throwable throwable);
}
Copy to Clipboard Toggle word wrap

일반적으로 throwable 인수는 null 입니다. 그러나 요청 처리로 인해 매핑되지 않은 예외가 발생한 경우 throwable에 매핑되지 않은 예외 인스턴스가 포함됩니다.However, if the request processing resulted in an unmapped exception, throwable contains the unmapped exception instance.

48.5.4.3. 완료 콜백 등록

완료 콜백을 구현한 후 register 방법 중 하나를 호출하여 현재 AsyncResponse 오브젝트에 등록해야 합니다. 예를 들어, 완료 콜백 유형을 등록하려면 MyCompletionCallback:

asyncResponse.register(new MyCompletionCallback());
Copy to Clipboard Toggle word wrap

49장. JAX-RS 2.0 Client API

초록

Cryostat-RS 2.0은 REST 호출 또는 HTTP 클라이언트 호출을 수행하는 데 사용할 수 있는 완전한 기능을 갖춘 클라이언트 API를 정의합니다. 여기에는 유창한 API(요청 빌드를 단순화하기 위한), 메시지 구문 분석 프레임워크(유사 공급자라고 하는 플러그인 유형) 및 클라이언트 측의 비동기 호출 지원이 포함됩니다.

49.1. Introduction to the Cryostat-RS 2.0 Client API

49.1.1. 개요

Cryostat-RS 2.0은 HTTP 요청을 단계별로 빌드한 다음 적절한 HTTP 동사(GET, POST, PUT 또는 DELETE)를 사용하여 요청을 호출할 수 있는 fluent API를 정의합니다.

참고

블루프린트 XML 또는 Spring XML( jaxrs:client 요소 사용)에서 Cryostat-RS 클라이언트를 정의할 수도 있습니다. 이 방법에 대한 자세한 내용은 18.2절. “Cryostat-RS 클라이언트 끝점 구성” 을 참조하십시오.

49.1.2. 종속 항목

애플리케이션에서 Cryostat-RS 2.0 클라이언트 API를 사용하려면 프로젝트의 pom.xml 파일에 다음 Maven 종속성을 추가해야 합니다.

<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-rs-client</artifactId>
  <version>3.3.6.fuse-7_12_0-00020-redhat-00001</version>
</dependency>
Copy to Clipboard Toggle word wrap

비동기 호출 기능을 사용하려면 49.6절. “클라이언트에서 비동기 처리”참조) 다음 Maven 종속성도 필요합니다.

<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-transports-http-hc</artifactId>
  <version>3.3.6.fuse-7_12_0-00020-redhat-00001</version>
</dependency>
Copy to Clipboard Toggle word wrap

49.1.3. 클라이언트 API 패키지

Cryostat-RS 2.0 클라이언트 인터페이스 및 클래스는 다음 Java 패키지에 있습니다.

javax.ws.rs.client
Copy to Clipboard Toggle word wrap

Cryostat-RS 2.0 Java 클라이언트를 개발할 때 일반적으로 코어 패키지에서 클래스에 액세스해야 합니다.

javax.ws.rs.core
Copy to Clipboard Toggle word wrap

49.1.4. 간단한 클라이언트 요청의 예

다음 코드 조각은 Cryostat-RS 2.0 클라이언트 API를 사용하여 GET HTTP 메서드로 호출하는 http://example.org/bookstore Cryostat-RS 서비스를 호출하는 데 사용되는 간단한 예제를 보여줍니다.

// Java
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
Response res = client.target("http://example.org/bookstore/books/123")
    .request("application/xml").get();
Copy to Clipboard Toggle word wrap

49.1.5. fluent API

Cryostat-RS 2.0 클라이언트 API는 유창한 API (때로 도메인별 언어라고도 함)로 설계되었습니다. fluent API에서는 Java 메서드가 간단한 언어의 명령처럼 보이는 방식으로 단일 문으로 Java 메서드 체인이 호출됩니다. Cryostat-RS 2.0에서 fluent API는 REST 요청을 빌드하고 호출하는 데 사용됩니다.

49.1.6. REST 호출을 수행하는 단계

Cryostat-RS 2.0 클라이언트 API를 사용하면 다음과 같이 클라이언트 호출이 빌드되고 일련의 단계로 호출됩니다.

  1. 클라이언트를 부트스트랩합니다.
  2. 대상을 구성합니다.
  3. 빌드 및 호출을 수행합니다.
  4. 응답을 구문 분석합니다.

49.1.7. 클라이언트 부트스트랩

첫 번째 단계는 javax.ws.rs.client.Client 오브젝트를 생성하여 클라이언트를 부트스트랩하는 것입니다. 이 Client 인스턴스는 비교적 중량한 오브젝트로, Cryostat-RS 클라이언트(비셉터 및 추가 CXF 기능 포함)를 지원하는 데 필요한 기술 스택을 나타냅니다. 이상적으로는 새 개체를 생성하는 대신 가능한 경우 클라이언트 개체를 다시 사용해야 합니다.

Client 개체를 생성하려면 다음과 같이 ClientBuilder 클래스에서 정적 메서드를 호출합니다.

// Java
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
...
Client client = ClientBuilder.newClient();
...
Copy to Clipboard Toggle word wrap

49.1.8. 대상 구성

대상을 구성하면 REST 호출에 사용할 URI를 효과적으로 정의합니다. 다음 예제에서는 path(String) 메서드를 사용하여 기본 URI를 정의한 다음 기본 URI에 경로 세그먼트를 추가하는 방법을 보여줍니다.

// Java
import javax.ws.rs.client.WebTarget;
...
WebTarget base = client.target("http://example.org/bookstore/");
WebTarget books = base.path("books").path("{id}");
...
Copy to Clipboard Toggle word wrap

49.1.9. 빌드 및 호출 만들기Build and make the invocation

이는 실제로 두 단계로 구성되어 있습니다. 먼저 HTTP 요청( 헤더 포함, 허용 미디어 유형 등 포함)을 빌드합니다. 두 번째는 관련 HTTP 메서드를 호출합니다(필요한 경우 요청 메시지 본문을 선택적으로 제공).

예를 들어 application/xml 미디어 유형을 수락하는 요청을 생성하고 호출하려면 다음을 수행합니다.

// Java
import javax.ws.rs.core.Response;
...
Response resp = books.resolveTemplate("id", "123").request("application/xml").get();
Copy to Clipboard Toggle word wrap

49.1.10. 응답 구문 분석

마지막으로 이전 단계에서 얻은 resp ose,spose를 구문 분석해야 합니다. 일반적으로 응답은 다른 HTTP 메타데이터 및 HTTP 메시지 본문(있는 경우)과 함께 HTTP 헤더를 캡슐화하는 javax.ws.rs.core.Response 오브젝트 형식으로 반환됩니다.

반환된 HTTP 메시지에 문자열 형식으로 액세스하려는 경우 다음과 같이 readEntity 메서드를 호출하여 쉽게 수행할 수 있습니다 .

// Java
...
String msg = resp.readEntity(String.class);
Copy to Clipboard Toggle word wrap

readEntity 에 대한 인수로 String.class 를 지정하여 응답의 메시지 본문에 항상 액세스할 수 있습니다. 메시지 본문의 일반적인 변환 또는 변환의 경우 엔터티 공급자 를 제공하여 변환을 수행할 수 있습니다. 자세한 내용은 49.4절. “요청 및 응답 구문 분석” 에서 참조하십시오.

49.2. 클라이언트 대상 빌드

49.2.1. 개요

초기 Client 인스턴스를 생성한 후 다음 단계는 요청 URI를 빌드하는 것입니다. WebTarget 빌더 클래스를 사용하면 URI 경로 및 쿼리 매개변수를 포함하여 URI의 모든 측면을 구성할 수 있습니다.

49.2.2. WebTarget 빌더 클래스

javax.ws.rs.WebTarget 빌더 클래스는 요청에 대한 REST URI를 빌드할 수 있는 fluent API의 일부를 제공합니다.

49.2.3. 클라이언트 대상 생성

WebTarget 인스턴스를 생성하려면 javax.ws.rs.client.Client 인스턴스에서 대상 메서드 중 하나를 호출합니다. 예를 들면 다음과 같습니다.

// Java
import javax.ws.rs.client.WebTarget;
...
WebTarget base = client.target("http://example.org/bookstore/");
Copy to Clipboard Toggle word wrap

49.2.4. 기본 경로 및 경로 세그먼트

대상 방법을 사용하여 한 번에 모두 전체 경로를 지정하거나 대상 메서드의 조합을 사용하여 기본 경로를 지정한 다음 경로 세그먼트 조각을 추가할 수 있습니다. 기본 경로와 경로 세그먼트를 결합하면 약간 다른 대상에서 여러 호출에 대해 기본 경로 WebTarget 오브젝트를 쉽게 다시 사용할 수 있다는 이점이 있습니다. 예를 들면 다음과 같습니다.

// Java
import javax.ws.rs.client.WebTarget;
...
WebTarget base = client.target("http://example.org/bookstore/");
WebTarget headers     = base.path("bookheaders");
// Now make some invocations on the 'headers' target...
...
WebTarget collections = base.path("collections");
// Now make some invocations on the 'collections' target...
...
Copy to Clipboard Toggle word wrap

49.2.5. URI 템플릿 매개변수

대상 경로의 구문은 URI 템플릿 매개변수도 지원합니다. 즉, template 매개변수 {param} 을 사용하여 경로 세그먼트를 초기화할 수 있으며, 이후 지정된 값으로 확인됩니다. 예를 들면 다음과 같습니다.

// Java
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
WebTarget base = client.target("http://example.org/bookstore/");
WebTarget books = base.path("books").path("{id}");
...
Response resp = books.resolveTemplate("id", "123").request("application/xml").get();
Copy to Clipboard Toggle word wrap

여기서 resolveTemplate 메서드는 경로 세그먼트 {id} 를 값 123 으로 바꿉니다.

49.2.6. 쿼리 매개변수 정의

쿼리 매개변수는 URI 경로에 추가할 수 있습니다. 여기서 쿼리 매개변수의 시작은 단일 ? 문자로 표시됩니다. 이 메커니즘을 사용하면 구문을 사용하여 일련의 이름/값 쌍을 설정할 수 있습니다. ?name1=value1&name2=value2&…​

WebTarget 인스턴스를 사용하면 다음과 같이 queryParam 메서드를 사용하여 쿼리 매개변수를 정의할 수 있습니다.

// Java
WebTarget target = client.target("http://example.org/bookstore/")
                         .queryParam("userId","Agamemnon")
                         .queryParam("lang","gr");
Copy to Clipboard Toggle word wrap

49.2.7. 매트릭스 매개변수 정의

매트릭스 매개변수는 쿼리 매개변수와 다소 유사하지만 널리 지원되지 않으며 다른 구문을 사용합니다. WebTarget 인스턴스에 matrix 매개변수를 정의하려면 matrixParam(String, Object) 메서드를 호출합니다.

49.3. 클라이언트 호출 빌드

49.3.1. 개요

대상 URI를 빌드한 후 WebTarget 빌더 클래스를 사용하여 HTTP 헤더, 쿠키 등 요청의 다른 측면(예: Invocation.Builder 클래스를 사용하여 구성)을 구성합니다. 호출을 빌드하는 마지막 단계는 적절한 HTTP 동사(GET, POST, PUT 또는 DELETE)를 호출하고 필요한 경우 메시지 본문을 제공하는 것입니다.

49.3.2. invocation.Builder 클래스

javax.ws.rs.client.Invocation.Builder 빌더 클래스는 HTTP 메시지의 내용을 빌드하고 HTTP 메서드를 호출할 수 있는 fluent API의 부분을 제공합니다.

49.3.3. 호출 빌더 생성

Invocation.Builder 인스턴스를 생성하려면 javax.ws.rs.client.WebTarget 인스턴스에서 요청 메서드 중 하나를 호출합니다. 예를 들면 다음과 같습니다.

// Java
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Invocation.Builder;
...
WebTarget books = client.target("http://example.org/bookstore/books/123");
Invocation.Builder invbuilder = books.request();
Copy to Clipboard Toggle word wrap

49.3.4. HTTP 헤더 정의

다음과 같이 헤더 메서드를 사용하여 요청 메시지에 HTTP 헤더 를 추가할 수 있습니다.

Invocation.Builder invheader = invbuilder.header("From", "fionn@example.org");
Copy to Clipboard Toggle word wrap

49.3.5. 쿠키 정의

다음과 같이 쿠키 방법을 사용하여 요청 메시지에 쿠키를 추가할 수 있습니다.

Invocation.Builder invcookie = invbuilder.cookie("myrestclient", "123xyz");
Copy to Clipboard Toggle word wrap

49.3.6. 속성 정의

다음과 같이 속성 메서드를 사용하여 이 요청 컨텍스트에서 속성을 설정할 수 있습니다.

Invocation.Builder invproperty = invbuilder.property("Name", "Value");
Copy to Clipboard Toggle word wrap

49.3.7. 허용되는 미디어 유형, 언어 또는 인코딩 정의

허용되는 미디어 유형, 언어 또는 인코딩을 다음과 같이 정의할 수 있습니다.

Invocation.Builder invmedia = invbuilder.accept("application/xml")
                                        .acceptLanguage("en-US")
                                        .acceptEncoding("gzip");
Copy to Clipboard Toggle word wrap

49.3.8. HTTP 메서드 호출

REST 호출을 빌드하는 프로세스는 HTTP 호출을 수행하는 HTTP 메서드를 호출하여 종료됩니다. 다음 메서드( javax.ws.rs.client.SyncInvoker 기본 클래스에서 상속됨)를 호출할 수 있습니다.

get
post
delete
put
head
trace
options
Copy to Clipboard Toggle word wrap

호출하려는 특정 HTTP 동사가 이 목록에 없는 경우 일반 메서드 메서드를 사용하여 HTTP 메서드 를 호출할 수 있습니다.

49.3.9. 입력한 응답

모든 HTTP 호출 메서드는 형식화되지 않은 변형과 형식화 변형(추가 인수를 사용함)이 제공됩니다. 기본 get() 메서드(패키지 없음)를 사용하여 요청을 호출하면 javax.ws.rs.core.Response 개체가 호출에서 반환됩니다. 예를 들면 다음과 같습니다.

Response res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").get();
Copy to Clipboard Toggle word wrap

그러나 get(Class<T>) 메서드를 사용하여 특정 유형으로 응답하도록 요청할 수도 있습니다. 예를 들어 요청을 호출하고 응답을 BookInfo 개체로 반환하도록 요청하려면 다음을 수행합니다.

BookInfo res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").get(BookInfo.class);
Copy to Clipboard Toggle word wrap

그러나 이 기능이 작동하려면 응답 형식인 application/xml 을 요청된 유형에 매핑할 수 있는 Client 인스턴스에 적절한 엔터티 공급자 를 등록해야 합니다. 엔터티 공급자에 대한 자세한 내용은 49.4절. “요청 및 응답 구문 분석” 을 참조하십시오.

49.3.10. post 또는 put에 발신 메시지 지정

요청에 메시지 본문을 포함하는 HTTP 메서드(예: POST 또는 PUT)의 경우 메시지 본문을 메서드의 첫 번째 인수로 지정해야 합니다. 메시지 본문은 javax.ws.rs.client.Entity 개체로 지정해야 합니다. 여기서 엔터티 는 메시지 내용 및 관련 미디어 유형을 캡슐화합니다. 예를 들어 메시지 콘텐츠가 문자열 유형으로 제공되는 POST 메서드를 호출하려면 다음을 수행합니다.

import javax.ws.rs.client.Entity;
...
Response res = client.target("http://example.org/bookstore/registerbook")
                     .request("application/xml")
                     .put(Entity.entity("Red Hat Install Guide", "text/plain"));
Copy to Clipboard Toggle word wrap

필요한 경우 Entity.entity() 생성자 메서드는 등록된 엔터티 공급자를 사용하여 제공된 메시지 인스턴스를 지정된 미디어 유형에 자동으로 매핑합니다. 메시지 본문을 간단한 문자열 유형으로 지정할 수 있습니다.

49.3.11. 지연된 호출

HTTP 요청을 즉시 호출하는 대신(예: get() 메서드를 호출하여), 나중에 호출할 수 있는 javax.ws.rs.client.Invocation 오브젝트를 생성할 수 있는 옵션이 있습니다. Invocation 오브젝트는 HTTP 메서드를 포함하여 보류 중인 호출의 모든 세부 정보를 캡슐화합니다.

다음 방법을 사용하여 Invocation 오브젝트를 빌드할 수 있습니다.

buildGet
buildPost
buildDelete
buildPut
build
Copy to Clipboard Toggle word wrap

예를 들어 GET Invocation 오브젝트를 생성하고 나중에 호출하려면 다음과 같은 코드를 사용할 수 있습니다.

import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Response;
...
Invocation getBookInfo = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").buildGet();
...
// Later on, in some other part of the application:
Response = getBookInfo.invoke();
Copy to Clipboard Toggle word wrap

49.3.12. 비동기 호출

Cryostat-RS 2.0 클라이언트 API는 클라이언트 측에서 비동기 호출을 지원합니다. 비동기 호출을 만들려면 request() 뒤에 나오는 메서드 체인에서 async() 메서드를 호출합니다. 예를 들면 다음과 같습니다.

Future<Response> res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get();
Copy to Clipboard Toggle word wrap

비동기 호출을 수행할 때 반환된 값은 java.util.concurrent.Future 오브젝트입니다. 비동기 호출에 대한 자세한 내용은 49.6절. “클라이언트에서 비동기 처리” 을 참조하십시오.

49.4. 요청 및 응답 구문 분석

49.4.1. 개요

HTTP 호출을 수행하는 데 중요한 측면은 클라이언트가 발신 요청 메시지와 들어오는 응답을 구문 분석할 수 있어야 한다는 것입니다. Cryostat-RS 2.0에서 키 개념은 미디어 유형으로 태그된 원시 메시지를 나타내는 Entity 클래스입니다. 원시 메시지를 구문 분석하려면 특정 Java 유형으로 미디어 유형을 변환 할 수있는 기능이 있는 여러 엔터티 공급자 를 등록할 수 있습니다.

즉, Cryostat-RS 2.0의 컨텍스트에서 Entity 는 원시 메시지의 표현이며 엔터티 공급자는 원시 메시지를 구문 분석하는 기능을 제공하는 플러그인입니다( media 유형 기반).

49.4.2. 엔터티

엔터티 는 메타데이터(media type, language, encoding)에 의해 보강된 메시지 본문입니다. 엔터티 인스턴스는 메시지를 원시 형식으로 보유하고 있으며 특정 미디어 유형과 연결되어 있습니다. Entity 개체의 내용을 Java 개체로 변환하려면 지정된 미디어 유형을 필수 Java 유형에 매핑할 수 있는 엔터티 공급자가 필요합니다.

49.4.3. 변형

javax.ws.rs.core.Variant 오브젝트는 다음과 같이 엔터티 와 연결된 메타데이터를 캡슐화합니다.

  • 미디어 유형,
  • 언어,
  • 인코딩.

효과적으로 EntityVariant 메타데이터로 보강한 HTTP 메시지 콘텐츠로 구성할 수 있습니다.

49.4.4. 엔터티 공급자

엔터티 공급자는 미디어 유형과 Java 유형 간의 매핑 기능을 제공하는 클래스입니다. 효과적으로 엔터티 공급자를 특정 미디어 유형(또는 여러 미디어 유형)의 메시지를 구문 분석하는 기능을 제공하는 클래스로 생각할 수 있습니다. 엔티티 공급자의 두 가지 유형이 있습니다.

MessageBodyReader
미디어 유형에서 Java 유형으로 매핑할 수 있는 기능을 제공합니다.
MessageBodyWriter
Java 유형에서 미디어 유형으로 매핑할 수 있는 기능을 제공합니다.

49.4.5. 표준 엔티티 공급자

다음 Java 및 미디어 유형 조합에 대한 엔터티 공급자는 표준으로 제공됩니다.

byte[]
모든 미디어 유형( */* ).
java.lang.String
모든 미디어 유형( */* ).
java.io.InputStream
모든 미디어 유형( */* ).
java.io.Reader
모든 미디어 유형( */* ).
java.io.File
모든 미디어 유형( */* ).
javax.activation.DataSource
모든 미디어 유형( */* ).
javax.xml.transform.Source
XML 유형(텍스트/xml,application/xmlapplication/*+xml형식의 미디어 유형).
javax.xml.bind.JAXB Cryostat 및 application-supplied CryostatB 클래스
XML 유형(텍스트/xml,application/xmlapplication/*+xml형식의 미디어 유형).
MultivaluedMap<String,String>
양식 콘텐츠(application/x-www-form-urlencoded).
StreamingOutput
모든 미디어 유형(*/*), MessageBodyWriter 만 해당합니다.
java.lang.Boolean, java.lang.Character, java.lang.Number
텍스트/설명만 사용할 수 있습니다. boxing/unboxing 변환을 통해 지원되는 해당 기본 유형.

49.4.6. 응답 오브젝트

기본 반환 유형은 입력되지 않은 응답을 나타내는 javax.ws.rs.core.Response 유형입니다. Response 오브젝트는 메시지 본문, HTTP 상태, HTTP 헤더, 미디어 유형 등을 포함하여 전체 HTTP 응답에 대한 액세스를 제공합니다.

49.4.7. 응답 상태 액세스

HTTP 상태 코드를 반환하는 getStatus 메서드를 통해 응답 상태에 액세스할 수 있습니다.

int status = resp.getStatus();
Copy to Clipboard Toggle word wrap

또는 getStatusInfo 메서드에서 설명 문자열도 제공합니다.

String statusReason = resp.getStatusInfo().getReasonPhrase();
Copy to Clipboard Toggle word wrap

49.4.8. 반환된 헤더 액세스

다음 메서드 중 하나를 사용하여 HTTP 헤더에 액세스할 수 있습니다.

MultivaluedMap<String,Object>
getHeaders()

MultivaluedMap<String,String>
getStringHeaders()

String
getHeaderString(String name)
Copy to Clipboard Toggle word wrap

예를 들어 응답에 Date 헤더가 있음을 알고 있는 경우 다음과 같이 액세스할 수 있습니다.

String dateAsString = resp.getHeaderString("Date");
Copy to Clipboard Toggle word wrap

49.4.9. 반환된 쿠키 액세스

다음과 같이 getCookies 방법을 사용하여 응답에 설정된 모든 새 쿠키를 액세스할 수 있습니다.

import javax.ws.rs.core.NewCookie;
...
java.util.Map<String,NewCookie> cookieMap = resp.getCookies();
java.util.Collection<NewCookie> cookieCollection = cookieMap.values();
Copy to Clipboard Toggle word wrap

49.4.10. 반환된 메시지 콘텐츠에 액세스

Response 오브젝트에서 readEntity 메서드 중 하나를 호출하여 반환된 메시지 콘텐츠에 액세스할 수 있습니다. readEntity 메서드는 사용 가능한 엔티티 공급자를 자동으로 호출하여 메시지를 요청된 유형으로 변환합니다( readEntity의 첫 번째 인수로 지정됨). 예를 들어 메시지 콘텐츠에 문자열 유형으로 액세스하려면 다음을 수행합니다.

String messageBody = resp.readEntity(String.class);
Copy to Clipboard Toggle word wrap

49.4.11. 컬렉션 반환 값

반환된 메시지에 Java 일반 유형(예: List 또는 Collection 유형)으로 액세스해야 하는 경우 javax.ws.rs.core.GenericType<T > 구성을 사용하여 요청 메시지 유형을 지정할 수 있습니다. 예를 들면 다음과 같습니다.

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.GenericType;
import java.util.List;
...
GenericType<List<String>> stringListType = new GenericType<List<String>>() {};

Client client = ClientBuilder.newClient();
List<String> bookNames = client.target("http://example.org/bookstore/booknames")
                     .request("text/plain")
                     .get(stringListType);
Copy to Clipboard Toggle word wrap

49.5. 클라이언트 끝점 구성

49.5.1. 개요

기능 및 공급자를 등록하고 구성하여 기본 javax.ws.rs.client.client.Client 오브젝트의 기능을 보강할 수 있습니다.

49.5.2. 예제

다음 예제에서는 로깅 기능, 사용자 지정 엔터티 공급자 및 prettyLogging 속성을 true 로 설정하도록 구성된 클라이언트를 보여줍니다.

// Java
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import org.apache.cxf.feature.LoggingFeature;
...
Client client = ClientBuilder.newClient();
client.register(LoggingFeature.class)
      .register(MyCustomEntityProvider.class)
      .property("LoggingFeature.prettyLogging","true");
Copy to Clipboard Toggle word wrap

49.5.3. 오브젝트 등록을 위한 구성 가능한 API

Client 클래스는 register 메서드의 여러 변형을 제공하는 오브젝트 등록에 대해 Configurable API를 지원합니다. 대부분의 경우 다음 예와 같이 클래스 또는 오브젝트 인스턴스를 등록합니다.

client.register(LoggingFeature.class)
client.register(new LoggingFeature())
Copy to Clipboard Toggle word wrap

레지스터 변형에 대한 자세한 내용은 Configurable 의 참조 문서를 참조하십시오.

49.5.4. 클라이언트에서 구성할 수 있는 것은 무엇입니까?

클라이언트 끝점의 다음 측면을 구성할 수 있습니다.

  • 기능
  • 공급자
  • 속성
  • 필터
  • 인터셉터

49.5.5. 기능

javax.ws.rs.core.Feature 는 다른 기능 또는 기능을 Cryostat-RS 클라이언트에 추가하는 플러그인입니다. 종종 기능은 필요한 기능을 제공하기 위해 하나 이상의 인터셉터를 설치합니다.

49.5.6. 공급자

공급자는 매핑 기능을 제공하는 특정 종류의 클라이언트 플러그인입니다. Cryostat-RS 2.0 사양은 다음과 같은 유형의 공급자를 정의합니다.

엔터티 공급자
엔터티 공급자는 특정 미디어 유형 간에 Java 유형 간 매핑 기능을 제공합니다. 자세한 내용은 49.4절. “요청 및 응답 구문 분석” 에서 참조하십시오.
예외 매핑 공급자
예외 매핑 공급자는 확인된 런타임 예외를 Response 인스턴스에 매핑합니다.
컨텍스트 공급자
컨텍스트 공급자는 리소스 클래스 및 기타 서비스 공급자에 컨텍스트를 제공하는 데 사용됩니다.

49.5.7. 필터

Cryostat-RS 2.0 필터는 메시지 처리 파이프라인의 다양한 지점(extensionpoint)에서 URI, 헤더 및 기타 컨텍스트 데이터에 액세스할 수 있는 플러그인입니다. 자세한 내용은 61장. Cryostat-RS 2.0 필터 및 인터셉터의 내용을 참조하십시오.

49.5.8. 인터셉터

Cryostat-RS 2.0 인터셉터는 읽거나 쓸 때 요청 또는 응답의 메시지 본문에 액세스할 수 있는 플러그인입니다. 자세한 내용은 61장. Cryostat-RS 2.0 필터 및 인터셉터의 내용을 참조하십시오.

49.5.9. 속성

클라이언트에서 하나 이상의 속성을 설정하면 등록된 기능 또는 등록된 공급자의 구성을 사용자 지정할 수 있습니다.

49.5.10. 기타 구성 가능한 유형

javax.ws.rs.client.rs.rs. client.ClientBuilder ) 오브젝트뿐만 아니라 WebTarget 오브젝트도 구성할 수 있습니다. WebTarget 오브젝트의 구성을 변경하면 기본 클라이언트 구성이 깊이 복사되어 새 WebTarget 구성을 제공합니다. 따라서 원래 Client 오브젝트의 구성을 변경하지 않고 WebTarget 오브젝트의 구성을 변경할 수 있습니다.

49.6. 클라이언트에서 비동기 처리

49.6.1. 개요

Cryostat-RS 2.0은 클라이언트 측에서 호출의 비동기 처리를 지원합니다. 두 가지 비동기 처리 스타일이 지원됩니다 . java.util.concurrent.Future<V > 반환 값을 사용하거나 호출 콜백을 등록하는 것입니다.

49.6.2. Future 반환 값을 사용한 비동기 호출

비동기 처리에 Future<V> 방법을 사용하면 다음과 같이 클라이언트 요청을 비동기적으로 호출할 수 있습니다.Using the Future <V> approach to asynchronous processing, you can invoke a client request asynchronously, as follows:

// Java
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import java.util.concurrent.Future;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
Future<Response> futureResp = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get();
...
// At a later time, check (and wait) for the response:
Response resp = futureResp.get();
Copy to Clipboard Toggle word wrap

입력된 응답에 유사한 접근 방식을 사용할 수 있습니다. 예를 들어, 유형의 응답을 얻으려면 BookInfo:

Client client = ClientBuilder.newClient();
Future<BookInfo> futureResp = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get(BookInfo.class);
...
// At a later time, check (and wait) for the response:
BookInfo resp = futureResp.get();
Copy to Clipboard Toggle word wrap

49.6.3. 호출 콜백을 사용한 비동기 호출

Future<V> 개체를 사용하여 반환 값에 액세스하는 대신 다음과 같이 호출 콜백( javax.ws.rs.client.InvocationCallback<RESPONSE> )을 정의할 수 있습니다.

// Java
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import java.util.concurrent.Future;
import javax.ws.rs.core.Response;
import javax.ws.rs.client.InvocationCallback;
...
Client client = ClientBuilder.newClient();
Future<Response> futureResp = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get(
    new InvocationCallback<Response>() {
        @Override
        public void completed(final Response resp) {
            // Do something when invocation is complete
            ...
        }

        @Override
        public void failed(final Throwable throwable) {
            throwable.printStackTrace();
        }
    });
...
Copy to Clipboard Toggle word wrap

입력된 응답에 유사한 방법을 사용할 수 있습니다.

// Java
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import java.util.concurrent.Future;
import javax.ws.rs.core.Response;
import javax.ws.rs.client.InvocationCallback;
...
Client client = ClientBuilder.newClient();
Future<BookInfo> futureResp = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get(
    new InvocationCallback<BookInfo>() {
        @Override
        public void completed(final BookInfo resp) {
            // Do something when invocation is complete
            ...
        }

        @Override
        public void failed(final Throwable throwable) {
            throwable.printStackTrace();
        }
    });
...
Copy to Clipboard Toggle word wrap

50장. 예외 처리

초록

가능한 경우 리소스 메서드로 catch된 예외로 인해 유용한 오류가 요청 소비자로 반환되어야 합니다. Cryostat-RS 리소스 메서드는 WebApplicationException 예외를 throw할 수 있습니다. 예외를 적절한 응답에 매핑하기 위해 ExceptionMapper<E> 구현을 제공할 수도 있습니다.

50.1. Cryostat-RS 예외 클래스 개요

50.1.1. 개요

Cryostat-RS 1.x에서 사용 가능한 유일한 예외 클래스는 WebApplicationException 입니다. 그러나 Cryostat-WS 2.0 이후 많은 추가 Cryostat-RS 예외 클래스가 정의되어 있습니다.

50.1.2. Cryostat-RS 런타임 수준 예외

다음 예외는 Cryostat-RS 런타임에서만 발생해야 합니다(즉, 애플리케이션 수준 코드에서 이러한 예외를 throw 해서는 안 됩니다).

ProcessingException
(JAX-RS 2.0만 해당) javax.ws.rs.ProcessingException 은 요청 처리 중에 또는 Cryostat-RS 런타임의 응답 처리 중에 throw될 수 있습니다. 예를 들어 필터 체인의 오류 또는 인터셉터 체인 처리 오류로 인해 이 오류가 발생할 수 있습니다.
ResponseProcessingException
(JAX-RS 2.0만 해당) javax.ws.rs.client.ResponseProcessingExceptionProcessingException 의 하위 클래스이며 클라이언트 측 의 Cryostat-RS 런타임에서 오류가 발생할 때 throw될 수 있습니다.

50.1.3. Cryostat-RS 애플리케이션 수준 예외

다음 예외는 애플리케이션 수준 코드에서 throw(및 catch)합니다.

WebApplicationException
javax.ws.rs.WebApplicationException 은 서버 측의 애플리케이션 코드에서 throw될 수 있는 일반 애플리케이션 수준 level Cryostat-RS 예외입니다. 이 예외 유형은 HTTP 상태 코드, 오류 메시지 및 응답 메시지를 캡슐화할 수 있습니다. 자세한 내용은 50.2절. “WebApplicationException을 사용하여 보고”의 내용을 참조하십시오.
ClientErrorException
(JAX-RS 2.0만 해당) javax.ws.rs.ClientErrorException 예외 클래스는 WebApplicationException 에서 상속되며 HTTP 4xx 상태 코드를 캡슐화하는 데 사용됩니다.
ServerErrorException
(JAX-RS 2.0만 해당) javax.ws.rs.ServerErrorException 예외 클래스는 WebApplicationException 에서 상속되며 HTTP 5xx 상태 코드를 캡슐화하는 데 사용됩니다.
RedirectionException
(JAX-RS 2.0만 해당) javax.ws.rs.RedirectionException 예외 클래스는 WebApplicationException 에서 상속되며 HTTP 3xx 상태 코드를 캡슐화하는 데 사용됩니다.

50.2. WebApplicationException을 사용하여 보고

            errors
indexterm:[WebApplicationException]
Copy to Clipboard Toggle word wrap

50.2.1. 개요

Cryostat-RS API는 리소스 메서드에서 RESTful 클라이언트가 사용할 수 있는 예외를 쉽게 생성할 수 있도록 WebApplicationException 런타임 예외를 도입했습니다. WebApplicationException 예외에는 요청 출처로 돌아가기 위해 엔터티 본문을 정의하는 Response 오브젝트가 포함될 수 있습니다. 또한 엔터티 본문이 제공되지 않는 경우 HTTP 상태 코드를 클라이언트에 반환하는 메커니즘을 제공합니다.

50.2.2. 간단한 예외 생성

WebApplicationException 예외를 생성하는 가장 쉬운 방법은 인수 생성자나 WebApplicationException 예외에서 원래 예외를 래핑하는 생성자를 사용하는 것입니다. 두 생성자 모두 빈 응답이 있는 WebApplicationException을 생성합니다.

이러한 생성자 중 하나에 의해 생성된 예외가 발생하면 런타임에서 빈 엔터티 본문과 상태 코드가 500 Server Error 인 응답을 반환합니다.

50.2.3. 클라이언트에 반환되는 상태 코드 설정

500 이외의 오류 코드를 반환하려면 상태를 지정할 수 있는 네 가지 WebApplicationException 생성자 중 하나를 사용할 수 있습니다. 예 50.1. “상태 코드를 사용하여 WebApplicationException 생성” 에 표시된 이러한 생성자 중 두 개는 반환 상태를 정수로 가져옵니다.

예 50.1. 상태 코드를 사용하여 WebApplicationException 생성

WebApplicationExceptionintstatusWebApplicationExceptionjava.lang.Throwable의 경우int

예 50.2. “상태 코드를 사용하여 WebApplicationException 생성” 에 표시된 다른 두 개는 응답 상태를 Response.Status 인스턴스로 가져옵니다.

예 50.2. 상태 코드를 사용하여 WebApplicationException 생성

WebApplicationExceptionjavax.ws.rs.core.Response.Status상태WebApplicationExceptionjava.lang.Throwable원인javax.ws.rs.core.Response.Status상태

이러한 생성자 중 하나에 의해 생성된 예외가 발생하면 런타임에서 빈 엔터티 본문 및 지정된 상태 코드가 있는 응답을 반환합니다.

50.2.4. 엔터티 본문 제공

예외와 함께 메시지를 보내려면 Response 개체를 사용하는 WebApplicationException 생성자 중 하나를 사용할 수 있습니다. 런타임은 Response 오브젝트를 사용하여 클라이언트에 전송된 응답을 생성합니다. 응답에 저장된 엔티티는 메시지의 엔티티 본문에 매핑되고 응답의 status 필드는 메시지의 HTTP 상태에 매핑됩니다.

예 50.3. “예외를 사용하여 메시지 전송” 예외 이유가 포함된 클라이언트에 텍스트 메시지를 반환하고 HTTP 메시지 상태를 409 Conflict 로 설정하는 코드를 표시합니다.

예 50.3. 예외를 사용하여 메시지 전송

import javax.ws.rs.core.Response;
import javax.ws.rs.WebApplicationException;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;

...
ResponseBuilderImpl builder = new ResponseBuilderImpl();
builder.status(Response.Status.CONFLICT);
builder.entity("The requested resource is conflicted.");
Response response = builder.build();
throw WebApplicationException(response);
Copy to Clipboard Toggle word wrap

50.2.5. 일반 예외 확장

WebApplicationException 예외를 확장할 수 있습니다. 이를 통해 사용자 정의 예외를 생성하고 일부 보일러 플레이트 코드를 제거할 수 있습니다.

예 50.4. “WebApplicationException 확장” 예 50.3. “예외를 사용하여 메시지 전송” 에서 코드와 유사한 응답을 생성하는 새 예외를 표시합니다.

예 50.4. WebApplicationException 확장

public class ConflicteddException extends WebApplicationException
{
  public ConflictedException(String message)
  {
    ResponseBuilderImpl builder = new ResponseBuilderImpl();
    builder.status(Response.Status.CONFLICT);
    builder.entity(message);
    super(builder.build());
     }
}

...
throw ConflictedException("The requested resource is conflicted.");
Copy to Clipboard Toggle word wrap

50.3. Cryostat-RS 2.0 예외 유형

50.3.1. 개요

Cryostat-RS 2.0에는 애플리케이션 코드(기존 WebApplicationException 예외 유형 외에)를 throw(및 catch)할 수 있는 여러 가지 특정 HTTP 예외 유형이 도입되었습니다. 이러한 예외 유형은 HTTP 클라이언트 오류(HTTP 4xx 상태 코드) 또는 HTTP 서버 오류(HTTP 5xx 상태 코드)에 대해 표준 HTTP 상태 코드를 래핑하는 데 사용할 수 있습니다.

50.3.2. 예외 계층 구조

그림 50.1. “Cryostat-RS 2.0 애플리케이션 예외 계층 구조” Mellanox-RS 2.0에서 지원되는 애플리케이션 수준 예외의 계층 구조를 보여줍니다.

그림 50.1. Cryostat-RS 2.0 애플리케이션 예외 계층 구조

예외 01

50.3.3. WebApplicationException 클래스

javax.ws.rs.WebApplicationException 예외 클래스( Cryostat-RS 1.x 이후 사용 가능)는 Cryostat-RS 2.0 예외 계층 구조의 기반에 있으며 50.2절. “WebApplicationException을 사용하여 보고” 에 자세히 설명되어 있습니다.

50.3.4. ClientErrorException 클래스

javax.ws.rs.ClientErrorException 예외 클래스는 HTTP 클라이언트 오류(HTTP 4xx 상태 코드)를 캡슐화하는 데 사용됩니다. 애플리케이션 코드에서 이 예외 또는 해당 하위 클래스 중 하나를 throw할 수 있습니다.

50.3.5. ServerErrorException 클래스

javax.ws.rs.ServerErrorException 예외 클래스는 HTTP 서버 오류(HTTP 5xx 상태 코드)를 캡슐화하는 데 사용됩니다. 애플리케이션 코드에서 이 예외 또는 해당 하위 클래스 중 하나를 throw할 수 있습니다.

50.3.6. RedirectionException 클래스

javax.ws.rs.RedirectionException 예외 클래스는 HTTP 요청 리디렉션(HTTP 3xx 상태 코드)을 캡슐화하는 데 사용됩니다. 이 클래스의 생성자는 리디렉션 위치를 지정하는 URI 인수를 사용합니다. 리디렉션 URI는 getLocation() 메서드를 통해 액세스할 수 있습니다. 일반적으로 HTTP 리디렉션은 클라이언트 측에서 투명합니다.

50.3.7. 클라이언트 예외 하위 클래스

Cryostat-RS 2.0 애플리케이션에서 다음 HTTP 클라이언트 예외(HTTP 4xx 상태 코드)를 발생시킬 수 있습니다.

BadRequestException
400 Bad Request HTTP 오류 상태를 캡슐화합니다.
ForbiddenException
403 Forbidden HTTP 오류 상태를 캡슐화합니다.
NotAcceptableException
406 Not Acceptable HTTP 오류 상태를 캡슐화합니다.
NotAllowedException
405 Method Not Allowed HTTP 오류 상태를 캡슐화합니다.
NotAuthorizedException

401 Unauthorized HTTP 오류 상태를 캡슐화합니다. 이 예외는 다음 경우 중 하나로 발생할 수 있습니다.

  • 클라이언트에서 필요한 인증 정보(HTTP 인증 헤더에서)를 전송하지 않았거나
  • 클라이언트에서 자격 증명을 제공했지만 자격 증명이 유효하지 않았습니다.
NotFoundException
404 Not Found HTTP 오류 상태를 캡슐화합니다.
NotSupportedException
415 Unsupported Media Type HTTP 오류 상태를 캡슐화합니다.

50.3.8. 서버 예외 하위 클래스

Cryostat-RS 2.0 애플리케이션에서 다음 HTTP 서버 예외(HTTP 5xx 상태 코드)를 발생시킬 수 있습니다.

InternalServerErrorException
500 Internal Server Error HTTP 오류 상태를 캡슐화합니다.
ServiceUnavailableException
503 Service Unavailable HTTP 오류 상태를 캡슐화합니다.

50.4. 예외를 응답에 매핑

50.4.1. 개요

WebApplicationException 예외를 throw하는 인스턴스가 비현실적이거나 불가능합니다. 예를 들어 가능한 모든 예외를 catch한 다음 WebApplicationException을 생성하지 않을 수 있습니다. 애플리케이션 코드를 더 쉽게 작업할 수 있는 사용자 지정 예외를 사용할 수도 있습니다.

이러한 경우를 처리하기 위해 Cryostat-RS API를 사용하면 클라이언트에 보낼 Response 오브젝트를 생성하는 사용자 정의 예외 공급자를 구현할 수 있습니다. 사용자 정의 예외 공급자는 ExceptionMapper<E> 인터페이스를 구현하여 생성됩니다. Apache CXF 런타임으로 등록하면 E 유형의 예외가 발생할 때마다 사용자 지정 공급자가 사용됩니다.

50.4.2. 예외 매퍼를 선택하는 방법

예외 매퍼는 다음 두 가지 경우에 사용됩니다.

  • 예외 또는 해당 하위 클래스 중 하나가 throw되면 런타임에서 적절한 예외 매퍼를 확인합니다. throw된 특정 예외를 처리하는 경우 예외 매퍼가 선택됩니다. throw된 특정 예외에 대한 예외 매퍼가 없는 경우 예외의 가장 가까운 슈퍼 클래스의 예외 매퍼가 선택됩니다.
  • 기본적으로 WebApplicationException은 기본 매퍼인 WebApplicationExceptionMapper 에서 처리합니다. WebApplicationException 예외(예: 사용자 지정 RuntimeException 매퍼)를 처리할 수 있는 추가 사용자 지정 매퍼가 등록되더라도 사용자 지정 매퍼가 사용되지 않고 WebApplicationExceptionMapper 가 대신 사용됩니다.

    그러나 이 동작은 Message 오브젝트에서 default.wae.mapper.least.specific 속성을 true 로 설정하여 변경할 수 있습니다. 이 옵션을 활성화하면 기본 WebApplicationExceptionMapper 가 가장 낮은 우선 순위로 대체되므로 사용자 정의 예외 매퍼를 사용하여 WebApplicationException 예외를 처리할 수 있습니다. 예를 들어 이 옵션이 활성화된 경우 사용자 지정 RuntimeException 매퍼를 등록하여 WebApplicationException 예외를 catch할 수 있습니다. “WebApplicationException의 예외 매퍼 등록”을 참조하십시오.

예외에 대한 예외 매퍼가 없으면 예외가 ServletException 예외로 래핑되고 컨테이너 런타임으로 전달됩니다. 그러면 컨테이너 런타임에서 예외를 처리하는 방법을 결정합니다.

50.4.3. 예외 매퍼 구현

예외 매퍼는 javax.ws.rs.ext.ExceptionMapper<E> 인터페이스를 구현하여 생성됩니다. 예 50.5. “예외 매퍼 인터페이스” 에 표시된 대로 인터페이스에는 원래 예외를 매개변수로 사용하고 Response 오브젝트를 반환하는 단일 메서드 toResponse() 가 있습니다.

예 50.5. 예외 매퍼 인터페이스

public interface ExceptionMapper<E extends java.lang.Throwable>
{
  public Response toResponse(E exception);
}
Copy to Clipboard Toggle word wrap

예외 매퍼에서 생성한 Response 오브젝트는 다른 Response 오브젝트와 마찬가지로 런타임에서 처리합니다. 소비자에 대한 결과 응답에는 Response 오브젝트에 캡슐화된 status, headers 및 entity 본문이 포함됩니다.

예외 매퍼 구현은 런타임의 공급자로 간주됩니다. 따라서 @Provider 주석을 사용하여 데코레이터해야 합니다.

예외 매퍼가 Response 오브젝트를 빌드하는 동안 예외가 발생하면 런타임에서 500개의 Server Error 상태로 응답을 보냅니다.

예 50.6. “예외를 응답에 매핑” Spring AccessDeniedException 예외를 가로채고 403 Forbidden 상태 및 빈 엔터티 본문으로 응답을 생성하는 예외 매퍼를 표시합니다.

예 50.6. 예외를 응답에 매핑

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import org.springframework.security.AccessDeniedException;

@Provider
public class SecurityExceptionMapper implements ExceptionMapper<AccessDeniedException>
{

  public Response toResponse(AccessDeniedException exception)
  {
    return Response.status(Response.Status.FORBIDDEN).build();
  }

}
Copy to Clipboard Toggle word wrap

런타임은 모든 AccessDeniedException 예외를 catch하고 엔티티 본문 없이 Response 오브젝트를 생성합니다. 403. 그런 다음 런타임은 일반적인 응답의 경우와 같이 Response 오브젝트를 처리합니다. 결과적으로 소비자는 상태 403 으로 HTTP 응답을 수신합니다.

50.4.4. 예외 매퍼 등록

Cryostat-RS 애플리케이션에서 예외 매퍼를 사용하려면 먼저 예외 매퍼를 런타임에 등록해야 합니다. 예외 매퍼는 애플리케이션의 구성 파일에서 jaxrs:providers 요소를 사용하여 런타임과 함께 등록됩니다.

jaxrs:providers 요소는 jaxrs:server 요소의 자식이며 metrics 요소 목록을 포함합니다. Cryostat 요소는 하나의 예외 매퍼를 정의합니다.

예 50.7. “런타임에 예외 매퍼 등록” 사용자 지정 예외 매퍼, SecurityExceptionMapper 를 사용하도록 구성된 Cryostat-RS 서버가 표시됩니다.

예 50.7. 런타임에 예외 매퍼 등록

<beans ...>
  <jaxrs:server id="customerService" address="/">
    ...
    <jaxrs:providers>
      <bean id="securityException" class="com.bar.providers.SecurityExceptionMapper"/>
    </jaxrs:providers>
  </jaxrs:server>
</beans>
Copy to Clipboard Toggle word wrap

50.4.5. WebApplicationException의 예외 매퍼 등록

이 예외 유형은 기본 WebApplicationException Mapper 에서 자동으로 처리되기 때문에 WebApplicationException 예외에 대한 예외 매퍼를 등록하는 것은 특별한 경우입니다. 일반적으로 WebApplicationException 을 처리할 것으로 예상되는 사용자 정의 매퍼를 등록하더라도 기본 WebApplicationExceptionMapper 에서 계속 처리합니다. 이 기본 동작을 변경하려면 default.wae.mapper.least.specific 속성을 true 로 설정해야 합니다.

예를 들어 다음 XML 코드는 Cryostat-RS 끝점에서 default.wae.mapper.least.specific 속성을 활성화하는 방법을 보여줍니다.

<beans ...>
  <jaxrs:server id="customerService" address="/">
    ...
    <jaxrs:providers>
      <bean id="securityException" class="com.bar.providers.SecurityExceptionMapper"/>
    </jaxrs:providers>
    <jaxrs:properties>
      <entry key="default.wae.mapper.least.specific" value="true"/>
    </jaxrs:properties>
  </jaxrs:server>
</beans>
Copy to Clipboard Toggle word wrap

다음 예와 같이 인터셉터에서 default.wae.mapper.least.specific 속성을 설정할 수도 있습니다.

// Java
public void handleMessage(Message message)
{
    m.put("default.wae.mapper.least.specific", true);
    ...
Copy to Clipboard Toggle word wrap

51장. 엔터티 지원

초록

Apache CXF 런타임은 기본적으로 MIME 유형과 Java 오브젝트 간에 제한된 수의 매핑을 지원합니다. 개발자는 사용자 정의 리더 및 작성자를 구현하여 매핑을 확장할 수 있습니다. 사용자 정의 리더 및 작성자는 시작 시 런타임과 함께 등록됩니다.

51.1. 개요

런타임은 Cryostat-RS MessageBody Cryostat 및 MessageBodyWriter 구현을 사용하여 HTTP 메시지와 Java 표현 간에 데이터를 직렬화 및 역직렬화합니다. 독자와 작성자는 처리할 수 있는 MIME 유형을 제한할 수 있습니다.

런타임은 여러 공통 매핑에 대한 리더 및 작성자를 제공합니다. 애플리케이션에 고급 매핑이 필요한 경우 개발자는 MessageBody Cryostat 인터페이스 및/또는 MessageBodyWriter 인터페이스의 사용자 지정 구현을 제공할 수 있습니다. 사용자 정의 리더 및 작성자는 애플리케이션이 시작될 때 런타임에 등록됩니다.

51.2. 기본적으로 지원되는 유형

표 51.1. “기본적으로 지원되는 엔티티 매핑” Apache CXF에서 제공하는 엔터티 매핑을 상자에서 나열합니다.

Expand
표 51.1. 기본적으로 지원되는 엔티티 매핑
Java 유형MIME 유형

기본 유형

text/plain

java.lang.Number

text/plain

byte[]

*/*

java.lang.String

*/*

java.io.InputStream

*/*

java.io.Reader

*/*

java.io.File

*/*

javax.activation.DataSource

*/*

javax.xml.transform.Source

text/xml, application/xml, application/\*+xml

javax.xml.bind.JAXBElement

text/xml, application/xml, application/\*+xml

CryostatB 주석이 달린 오브젝트

text/xml, application/xml, application/\*+xml

javax.ws.rs.core.MultivaluedMap<String, String>

application/x-www-form-urlencoded [a]

javax.ws.rs.core.StreamingOutput

*/* [b]

[a] 이 매핑은 HTML 양식 데이터를 처리하는 데 사용됩니다.
[b] 이 매핑은 데이터를 소비자에게 반환하는 경우에만 지원됩니다.

51.3. 사용자 정의 리더

사용자 지정 엔터티 리더는 들어오는 HTTP 요청을 서비스의 구현이 조작할 수 있는 Java 유형으로 매핑해야 합니다. javax.ws.rs.ext.MessageBody Cryostat 인터페이스를 구현합니다.

예 51.1. “메시지 리더 인터페이스” 에 표시된 인터페이스에는 구현이 필요한 두 가지 방법이 있습니다.

예 51.1. 메시지 리더 인터페이스

package javax.ws.rs.ext;

public interface MessageBodyReader<T>
{
  public boolean isReadable(java.lang.Class<?> type,
                            java.lang.reflect.Type genericType,
                            java.lang.annotation.Annotation[] annotations,
                            javax.ws.rs.core.MediaType mediaType);

  public T readFrom(java.lang.Class<T> type,
                    java.lang.reflect.Type genericType,
                    java.lang.annotation.Annotation[] annotations,
                    javax.ws.rs.core.MediaType mediaType,
                    javax.ws.rs.core.MultivaluedMap<String, String> httpHeaders,
                    java.io.InputStream entityStream)
  throws java.io.IOException, WebApplicationException;
}
Copy to Clipboard Toggle word wrap
isReadable()

isReadable() 메서드는 판독기가 데이터 스트림을 읽고 적절한 유형의 엔터티 표현을 생성할 수 있는지 여부를 결정합니다. 독자가 적절한 유형의 엔티티를 만들 수 있는 경우 메서드는 true 를 반환합니다.

표 51.2. “판독기가 엔터티를 생성할 수 있는지 확인하는 데 사용되는 매개변수” isReadable() 메서드의 매개 변수에 대해 설명합니다.

Expand
표 51.2. 판독기가 엔터티를 생성할 수 있는지 확인하는 데 사용되는 매개변수
매개변수유형설명

type

class<T>

엔터티를 저장하는 데 사용되는 개체의 실제 Java 클래스를 지정합니다.

genericType

유형

엔터티를 저장하는 데 사용되는 개체의 Java 유형을 지정합니다. 예를 들어 메시지 본문을 메서드 매개 변수로 변환하는 경우 값은 Method.getGenericParameterTypes() 메서드에서 반환하는 메서드 매개변수의 유형이 됩니다.

annotations

Annotation[]

엔터티를 저장하도록 생성된 오브젝트 선언에 대한 주석 목록을 지정합니다. 예를 들어 메시지 본문을 메서드 매개 변수로 변환하는 경우 Method.getParameterAnnotations() 메서드에서 반환된 해당 매개 변수의 주석이 됩니다.

mediaType

MediatType

HTTP 엔티티의 MIME 유형을 지정합니다.

readFrom()

readFrom() 메서드는 HTTP 엔터티를 읽고 원하는 Java 오브젝트로 커버합니다. 읽기에 성공하면 메서드는 엔터티를 포함하는 생성된 Java 개체를 반환합니다. 입력 스트림을 읽을 때 오류가 발생하면 메서드에서 IOException 예외를 발생시켜야 합니다. HTTP 오류 응답이 필요한 오류가 발생하면 HTTP 응답이 있는 WebApplicationException이 throw되어야 합니다.

표 51.3. “엔터티를 읽는 데 사용되는 매개변수” readFrom() 메서드의 매개 변수에 대해 설명합니다.

Expand
표 51.3. 엔터티를 읽는 데 사용되는 매개변수
매개변수유형설명

type

class<T>

엔터티를 저장하는 데 사용되는 개체의 실제 Java 클래스를 지정합니다.

genericType

유형

엔터티를 저장하는 데 사용되는 개체의 Java 유형을 지정합니다. 예를 들어 메시지 본문을 메서드 매개 변수로 변환하는 경우 값은 Method.getGenericParameterTypes() 메서드에서 반환하는 메서드 매개변수의 유형이 됩니다.

annotations

Annotation[]

엔터티를 저장하도록 생성된 오브젝트 선언에 대한 주석 목록을 지정합니다. 예를 들어 메시지 본문을 메서드 매개 변수로 변환하는 경우 Method.getParameterAnnotations() 메서드에서 반환된 해당 매개 변수의 주석이 됩니다.

mediaType

MediatType

HTTP 엔티티의 MIME 유형을 지정합니다.

httpHeaders

MultivaluedMap<String, String>

엔터티와 연결된 HTTP 메시지 헤더를 지정합니다.

entityStream

InputStream

HTTP 엔티티를 포함하는 입력 스트림을 지정합니다.

중요

이 메서드는 입력 스트림을 종료하지 않아야 합니다.

MessageBody Cryostat 구현을 엔터티 리더로 사용하려면 javax.ws.rs.ext.Provider 주석으로 데코레이터해야 합니다. @Provider 주석은 제공된 구현에서 추가 기능을 제공하도록 런타임에 경고합니다. 구현도 “리더 및 작성자 등록” 에 설명된 대로 런타임에 등록해야 합니다.

기본적으로 사용자 지정 엔터티 공급자는 모든 MIME 유형을 처리합니다. javax.ws.rs.Consumes 주석을 사용하여 사용자 지정 엔터티 리더에서 처리할 MIME 유형을 제한할 수 있습니다. @Consumes 주석은 사용자 정의 엔터티 공급자가 읽을 수 있는 쉼표로 구분된 MIME 유형의 목록을 지정합니다. 엔터티가 지정된 MIME 유형이 아닌 경우 엔터티 공급자는 가능한 리더로 선택되지 않습니다.

예 51.2. “XML 소스 엔티티 리더” 엔터티 리더는 XML 엔터티를 사용하고 Source 개체에 저장합니다.

예 51.2. XML 소스 엔티티 리더

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
import org.apache.cxf.jaxrs.ext.xml.XMLSource;

@Provider
@Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" })
public class SourceProvider implements MessageBodyReader<Object>
{
  public boolean isReadable(Class<?> type,
                            Type genericType,
                            Annotation[] annotations,
                            MediaType mt)
  {
    return Source.class.isAssignableFrom(type) || XMLSource.class.isAssignableFrom(type);
  }

  public Object readFrom(Class<Object> source,
                         Type genericType,
                         Annotation[] annotations,
                         MediaType mediaType,
                         MultivaluedMap<String, String> httpHeaders,
                         InputStream is)
  throws IOException
  {
    if (DOMSource.class.isAssignableFrom(source))
    {
      Document doc = null;
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder;
      try
      {
        builder = factory.newDocumentBuilder();
        doc = builder.parse(is);
      }
      catch (Exception e)
      {
        IOException ioex = new IOException("Problem creating a Source object");
        ioex.setStackTrace(e.getStackTrace());
        throw ioex;
       }

       return new DOMSource(doc);
    }
    else if (StreamSource.class.isAssignableFrom(source) || Source.class.isAssignableFrom(source))
    {
      return new StreamSource(is);
    }
    else if (XMLSource.class.isAssignableFrom(source))
    {
      return new XMLSource(is);
    }

    throw new IOException("Unrecognized source");
  }
}
Copy to Clipboard Toggle word wrap

51.4. 사용자 정의 작성자

사용자 정의 엔터티 작성자는 Java 유형을 HTTP 엔터티에 매핑해야 합니다. javax.ws.rs.ext.MessageBodyWriter 인터페이스를 구현합니다.

예 51.3. “메시지 작성기 인터페이스” 에 표시된 인터페이스에는 구현이 필요한 세 가지 방법이 있습니다.

예 51.3. 메시지 작성기 인터페이스

package javax.ws.rs.ext;

public interface MessageBodyWriter<T>
{
  public boolean isWriteable(java.lang.Class<?> type,
                             java.lang.reflect.Type genericType,
                             java.lang.annotation.Annotation[] annotations,
                             javax.ws.rs.core.MediaType mediaType);

  public long getSize(T t,
                      java.lang.Class<?> type,
                      java.lang.reflect.Type genericType,
                      java.lang.annotation.Annotation[] annotations,
                      javax.ws.rs.core.MediaType mediaType);

  public void writeTo(T t,
                      java.lang.Class<?> type,
                      java.lang.reflect.Type genericType,
                      java.lang.annotation.Annotation[] annotations,
                      javax.ws.rs.core.MediaType mediaType,
                      javax.ws.rs.core.MultivaluedMap<String, Object> httpHeaders,
                      java.io.OutputStream entityStream)
  throws java.io.IOException, WebApplicationException;
}
Copy to Clipboard Toggle word wrap
isWriteable()

isWriteable() 메서드는 엔터티 작성자가 Java 유형을 적절한 엔티티 유형에 매핑할 수 있는지 여부를 결정합니다. 작성자가 매핑을 수행할 수 있는 경우 메서드는 true 를 반환합니다.

표 51.4. “엔터티를 읽는 데 사용되는 매개변수” isWritable() 메서드의 매개 변수에 대해 설명합니다.

Expand
표 51.4. 엔터티를 읽는 데 사용되는 매개변수
매개변수유형설명

type

class<T>

작성할 개체의 Java 클래스를 지정합니다.

genericType

유형

리소스 메서드 반환 유형의 반영 또는 반환된 인스턴스의 검사를 통해 작성할 개체의 Java 유형을 지정합니다. 48.4절. “일반 유형 정보를 사용하여 엔터티 반환” 에 설명된 GenericEntity 클래스는 이 값을 제어하도록 지원합니다.

annotations

Annotation[]

엔터티를 반환하는 메서드의 주석 목록을 지정합니다.

mediaType

MediatType

HTTP 엔티티의 MIME 유형을 지정합니다.

getSize()

getSize() 메서드는 writeTo() 앞에 호출됩니다. 작성 중인 엔터티의 길이(바이트)를 반환합니다. 양수 값이 반환되면 값은 HTTP 메시지의 Content-Length 헤더에 기록됩니다.

표 51.5. “엔터티를 읽는 데 사용되는 매개변수” getSize() 메서드의 매개변수에 대해 설명합니다.

Expand
표 51.5. 엔터티를 읽는 데 사용되는 매개변수
매개변수유형설명

t

generic

작성 중인 인스턴스를 지정합니다.

type

class<T>

작성할 개체의 Java 클래스를 지정합니다.

genericType

유형

리소스 메서드 반환 유형의 반영 또는 반환된 인스턴스의 검사를 통해 작성할 개체의 Java 유형을 지정합니다. 48.4절. “일반 유형 정보를 사용하여 엔터티 반환” 에 설명된 GenericEntity 클래스는 이 값을 제어하도록 지원합니다.

annotations

Annotation[]

엔터티를 반환하는 메서드의 주석 목록을 지정합니다.

mediaType

MediatType

HTTP 엔티티의 MIME 유형을 지정합니다.

writeTo()

writeTo() 메서드는 Java 개체를 원하는 엔터티 유형으로 변환하고 출력 스트림에 엔터티를 씁니다. 출력 스트림에 엔터티를 작성할 때 오류가 발생하면 메서드는 IOException 예외를 throw해야 합니다. HTTP 오류 응답이 필요한 오류가 발생하면 HTTP 응답이 있는 WebApplicationException이 throw되어야 합니다.

표 51.6. “엔터티를 읽는 데 사용되는 매개변수” writeTo() 메서드의 매개 변수에 대해 설명합니다.

Expand
표 51.6. 엔터티를 읽는 데 사용되는 매개변수
매개변수유형설명

t

generic

작성 중인 인스턴스를 지정합니다.

type

class<T>

작성할 개체의 Java 클래스를 지정합니다.

genericType

유형

리소스 메서드 반환 유형의 반영 또는 반환된 인스턴스의 검사를 통해 작성할 개체의 Java 유형을 지정합니다. 48.4절. “일반 유형 정보를 사용하여 엔터티 반환” 에 설명된 GenericEntity 클래스는 이 값을 제어하도록 지원합니다.

annotations

Annotation[]

엔터티를 반환하는 메서드의 주석 목록을 지정합니다.

mediaType

MediatType

HTTP 엔티티의 MIME 유형을 지정합니다.

httpHeaders

MultivaluedMap<String, Object>

엔터티와 연결된 HTTP 응답 헤더를 지정합니다.

entityStream

OutputStream

엔터티를 작성할 출력 스트림을 지정합니다.

MessageBodyWriter 구현을 엔터티 작성자로 사용하려면 javax.ws.rs.ext.Provider 주석으로 장식해야 합니다. @Provider 주석은 제공된 구현에서 추가 기능을 제공하도록 런타임에 경고합니다. 구현도 “리더 및 작성자 등록” 에 설명된 대로 런타임에 등록해야 합니다.

기본적으로 사용자 지정 엔터티 공급자는 모든 MIME 유형을 처리합니다. javax.ws.rs.Produces 주석을 사용하여 사용자 지정 엔터티 작성자가 처리할 MIME 유형을 제한할 수 있습니다. @Produces 주석은 사용자 정의 엔터티 공급자가 생성하는 MIME 유형의 쉼표로 구분된 목록을 지정합니다. 엔터티가 지정된 MIME 유형이 아닌 경우 엔터티 공급자는 가능한 작성자로 선택되지 않습니다.

예 51.4. “XML 소스 엔티티 작성기” 소스 개체를 사용하고 XML 엔터티를 생성하는 엔터티 작성기를 표시합니다.

예 51.4. XML 소스 엔티티 작성기

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import org.apache.cxf.jaxrs.ext.xml.XMLSource;

@Provider
@Produces({"application/xml", "application/*+xml", "text/xml" })
public class SourceProvider implements MessageBodyWriter<Source>
{

  public boolean isWriteable(Class<?> type,
                             Type genericType,
                             Annotation[] annotations,
                             MediaType mt)
  {
    return Source.class.isAssignableFrom(type);
  }

  public void writeTo(Source source,
                      Class<?> clazz,
                      Type genericType,
                      Annotation[] annotations,
                      MediaType mediatype,
                      MultivaluedMap<String, Object> httpHeaders,
                      OutputStream os)
  throws IOException
  {
    StreamResult result = new StreamResult(os);
    TransformerFactory tf = TransformerFactory.newInstance();
    try
    {
      Transformer t = tf.newTransformer();
      t.transform(source, result);
    }
    catch (TransformerException te)
    {
      te.printStackTrace();
      throw new WebApplicationException(te);
    }
  }

  public long getSize(Source source,
                      Class<?> type,
                      Type genericType,
                      Annotation[] annotations,
                      MediaType mt)
  {
    return -1;
  }
}
Copy to Clipboard Toggle word wrap

51.5. 리더 및 작성자 등록

Cryostat-RS 애플리케이션에서 사용자 지정 엔터티 공급자를 사용하려면 먼저 사용자 지정 공급자를 런타임에 등록해야 합니다. 공급자는 애플리케이션 구성 파일의 jaxrs:providers 요소 또는 Cryostat RSServerFactoryBean 클래스를 사용하여 런타임과 함께 등록됩니다.

jaxrs:providers 요소는 jaxrs:server 요소의 자식이며 metrics 요소 목록을 포함합니다. Cryostat 요소는 하나의 엔티티 공급자를 정의합니다.

예 51.5. “런타임을 사용하여 엔터티 공급자 등록” 사용자 지정 엔터티 공급자 집합을 사용하도록 구성된 Cryostat-RS 서버를 표시합니다.

예 51.5. 런타임을 사용하여 엔터티 공급자 등록

<beans ...>
  <jaxrs:server id="customerService" address="/">
    ...
    <jaxrs:providers>
      <bean id="isProvider" class="com.bar.providers.InputStreamProvider"/>
      <bean id="longProvider" class="com.bar.providers.LongProvider"/>
    </jaxrs:providers>
  </jaxrs:server>
</beans>
Copy to Clipboard Toggle word wrap

Cryo statRSServerFactoryBean 클래스는 구성 API에 대한 액세스를 제공하는 Apache CXF 확장입니다. 애플리케이션에 인스턴스화된 엔터티 공급자를 추가할 수 있는 setProvider() 메서드가 있습니다. 예 51.6. “엔터티 공급자를 프로그래밍 방식으로 등록” 엔터티 공급자를 프로그래밍 방식으로 등록하는 코드를 보여줍니다.

예 51.6. 엔터티 공급자를 프로그래밍 방식으로 등록

import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
...
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
...
SourceProvider provider = new SourceProvider();
sf.setProvider(provider);
...
Copy to Clipboard Toggle word wrap

52장. 컨텍스트 정보 가져오기 및 사용

초록

컨텍스트 정보에는 리소스의 URI, HTTP 헤더 및 기타 주입 주석을 사용하여 쉽게 사용할 수 없는 기타 세부 정보에 대한 자세한 정보가 포함됩니다. Apache CXF는 가능한 모든 컨텍스트 정보를 단일 오브젝트로 모호하게 하는 특수 클래스를 제공합니다.

52.1. 컨텍스트 소개

52.1.1. 컨텍스트 주석

javax.ws.rs.core.Context 주석을 사용하여 컨텍스트 정보를 필드 또는 리소스 메서드 매개변수에 삽입하도록 지정합니다. 컨텍스트 유형 중 하나의 필드 또는 매개 변수에 주석을 달면 주석이 달린 필드 또는 매개 변수에 적절한 컨텍스트 정보를 삽입하도록 런타임에 지시합니다.

52.1.2. 컨텍스트 유형

표 52.1. “컨텍스트 유형” 삽입할 수 있는 컨텍스트 정보 유형과 이를 지원하는 오브젝트를 나열합니다.

Expand
표 52.1. 컨텍스트 유형
개체컨텍스트 정보

UriInfo

전체 요청 URI

HttpHeaders

HTTP 메시지 헤더

요청

최상의 표현 변형을 결정하거나 사전 조건 집합이 설정되었는지 결정하는 데 사용할 수 있는 정보

SecurityContext

사용 중인 인증 체계, 요청 채널이 안전한 경우 및 사용자 원칙을 포함하여 요청자의 보안에 대한 정보

52.1.3. 컨텍스트 정보를 사용할 수 있는 위치

컨텍스트 정보는 Cryostat-RS 애플리케이션의 다음 부분에서 사용할 수 있습니다.

  • 리소스 클래스
  • 리소스 방법
  • 엔터티 공급자
  • 예외 매퍼

52.1.4. 범위

@Context 주석을 사용하여 삽입된 모든 컨텍스트 정보는 현재 요청에 따라 다릅니다. 이는 엔터티 공급자 및 예외 매퍼를 포함한 모든 경우에 적용됩니다.

52.1.5. 컨텍스트 추가

Cryostat-RS 프레임워크를 사용하면 개발자가 컨텍스트 메커니즘을 사용하여 삽입할 수 있는 정보 유형을 확장할 수 있습니다. Context<T> 오브젝트를 구현하고 런타임에 등록하여 사용자 지정 컨텍스트를 추가합니다.

52.2. 전체 요청 URI로 작업

초록

요청 URI에는 상당한 양의 정보가 포함되어 있습니다. 이 정보의 대부분은 47.2.2절. “요청 URI에서 데이터 삽입” 에 설명된 메서드 매개변수를 사용하여 액세스할 수 있지만 매개변수를 사용하면 URI 처리 방법에 대한 특정 제약 조건이 적용됩니다. 매개 변수를 사용하여 URI 세그먼트에 액세스해도 전체 요청 URI에 대한 리소스 액세스 권한도 제공되지 않습니다.

URI 컨텍스트를 리소스에 삽입하여 전체 요청 URI에 대한 액세스를 제공할 수 있습니다. URI는 UriInfo 개체로 제공됩니다. UriInfo 인터페이스는 여러 가지 방법으로 URI를 해독하는 기능을 제공합니다. 또한 URI를 클라이언트로 반환하기 위해 URI를 구성할 수 있는 UriBuilder 오브젝트로 제공할 수도 있습니다.

:Exerimental:

52.2.1. URI 정보 삽입

52.2.1.1. 개요

UriInfo 오브젝트인 클래스 필드 또는 메서드 매개 변수가 @Context 주석으로 데코레이팅되면 현재 요청에 대한 URI 컨텍스트가 UriInfo 오브젝트에 삽입됩니다.

52.2.1.2. 예제

클래스 필드에 URI 컨텍스트 삽입 URI 컨텍스트를 삽입하여 채워진 필드가 있는 클래스를 표시합니다.

클래스 필드에 URI 컨텍스트 삽입

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Path;
...
@Path("/monstersforhire/")
public class MonsterService
{
  @Context
  UriInfo requestURI;
  ...
}
Copy to Clipboard Toggle word wrap

52.2.2. URI 작업

52.2.2.1. 개요

URI 컨텍스트를 사용할 때의 주요 이점 중 하나는 서비스의 기본 URI에 대한 액세스와 선택한 리소스에 대한 URI의 경로 세그먼트에 대한 액세스를 제공한다는 것입니다. 이 정보는 URI를 기반으로 처리 결정을 수행하거나 응답의 일부로 반환하기 위해 URI 계산과 같은 여러 목적에 유용할 수 있습니다. 예를 들어, 요청의 기본 URI에 .com 확장 기능이 포함된 경우, 서비스는 미국 달러 사용을 결정할 수 있으며 기본 URI에 .co.uk 확장 기능이 포함된 경우 us social Pounds로 결정할 수 있습니다.

UriInfo 인터페이스는 URI 부분에 액세스하는 방법을 제공합니다.

  • 기본 URI
  • 리소스 경로
  • 전체 URI
52.2.2.2. 기본 URI 가져오기

기본 URI 는 서비스가 게시되는 루트 URI입니다. 서비스의 @Path 주석에 지정된 URI의 일부가 포함되어 있지 않습니다. 예를 들어, 예 47.5. “URI 디코딩 비활성화” 에 정의된 리소스를 구현하는 서비스가 http://fusesource.org 에 게시되고 에 요청이 이루어진 경우 기본 URI는 http://fusesource.org 입니다.http://fusesource.org/montersforhire/nightstalker?12

표 52.2. “리소스의 기본 URI에 액세스하는 방법” 기본 URI를 반환하는 메서드를 설명합니다.Describes the methods that return the base URI.

Expand
표 52.2. 리소스의 기본 URI에 액세스하는 방법
방법Desription

URIgetBaseUri

서비스의 기본 URI를 URI 오브젝트로 반환합니다.

UriBuildergetBaseUriBuilder

기본 URI를 javax.ws.rs.core.UriBuilder 오브젝트로 반환합니다. UriBuilder 클래스는 서비스에서 구현된 다른 리소스에 대한 URI를 생성하는 데 유용합니다.

52.2.2.3. 경로 가져오기

요청 URI의 경로 부분은 현재 리소스를 선택하는 데 사용된 URI의 일부입니다. 기본 URI는 포함되지 않지만 URI에 포함된 URI 템플릿 변수와 매트릭스 매개 변수가 포함됩니다.

경로 값은 선택한 리소스에 따라 다릅니다. 예를 들어 리소스 경로 가져오기 에 정의된 리소스의 경로는 다음과 같습니다.

  • rootPath/monstersforhire/
  • getterPath/mostersforhire/nightstalker

    GET 요청은 /monstersforhire/nightstalker 에서 수행되었습니다.

  • putterPath/mostersforhire/911

    PUT 요청은 /monstersforhire/911 에서 수행되었습니다.

리소스 경로 가져오기

@Path("/monstersforhire/")
public class MonsterService
{
  @Context
  UriInfo rootUri;

  ...

  @GET
  public List<Monster> getMonsters(@Context UriInfo getUri)
  {
    String rootPath = rootUri.getPath();
    ...
  }

  @GET
  @Path("/{type}")
  public Monster getMonster(@PathParam("type") String type,
                            @Context UriInfo getUri)
  {
    String getterPath = getUri.getPath();
    ...
  }

  @PUT
  @Path("/{id}")
  public void addMonster(@Encoded @PathParam("type") String type,
                         @Context UriInfo putUri)
  {
    String putterPath = putUri.getPath();
    ...
  }
  ...
}
Copy to Clipboard Toggle word wrap

표 52.3. “리소스 경로에 액세스하는 방법” 리소스 경로를 반환하는 방법을 설명합니다.

Expand
표 52.3. 리소스 경로에 액세스하는 방법
방법Desription

StringgetPath

리소스의 경로를 디코딩된 URI로 반환합니다.

문자열getPath부울디코딩

리소스의 경로를 반환합니다. false 를 지정하면 URI 디코딩이 비활성화됩니다.

List<PathSegment>getPathSegments

디코딩된 경로를 javax.ws.rs.core.PathSegment 오브젝트 목록으로 반환합니다. 매트릭스 매개 변수를 포함한 경로의 각 부분은 목록의 고유한 항목에 배치됩니다.

예를 들어 리소스 경로 상자/round# tall 은 세 개의 항목이 있는 목록을 생성합니다. box,round, and suffix .

list<PathSegment&gt;getPathSegments부울디코딩

path를 javax.ws.rs.core.PathSegment 오브젝트 목록으로 반환합니다. 매트릭스 매개 변수를 포함한 경로의 각 부분은 목록의 고유한 항목에 배치됩니다. false 를 지정하면 URI 디코딩이 비활성화됩니다.

예를 들어 리소스 경로 상자#tall /round는 box , popular , round 의 세 개의 항목이 있는 목록을 생성합니다.

52.2.2.4. 전체 요청 URI 가져오기

표 52.4. “전체 요청 URI에 액세스하는 방법” 전체 요청 URI를 반환하는 메서드를 설명합니다. 요청 URI 또는 리소스의 절대 경로를 반환하는 옵션이 있습니다. 차이점은 요청 URI에 URI에 추가된 쿼리 매개변수가 포함되어 있고 절대 경로에는 쿼리 매개변수가 포함되지 않는다는 것입니다.

Expand
표 52.4. 전체 요청 URI에 액세스하는 방법
방법Desription

URIgetRequestUri

쿼리 매개변수 및 매트릭스 매개 변수를 포함하여 전체 요청 URI를 java.net.URI 오브젝트로 반환합니다.

UriBuildergetRequestUriBuilder

쿼리 매개변수 및 매트릭스 매개변수를 javax.ws.rs.UriBuilder 오브젝트로 포함한 전체 요청 URI를 반환합니다. UriBuilder 클래스는 서비스에서 구현된 다른 리소스에 대한 URI를 생성하는 데 유용합니다.

URIgetAbsolutePath

매트릭스 매개 변수를 포함하여 전체 요청 URI를 java.net.URI 오브젝트로 반환합니다. 절대 경로에는 쿼리 매개변수가 포함되지 않습니다.

UriBuildergetAbsolutePathBuilder

매트릭스 매개 변수를 포함하여 전체 요청 URI를 javax.ws.rs.UriBuilder 오브젝트로 반환합니다. 절대 경로에는 쿼리 매개변수가 포함되지 않습니다.

URI http://fusesource.org/montersforhire/nightstalker?12 를 사용하여 요청한 경우 getRequestUri() 메서드는 http://fusesource.org/montersforhire/nightstalker?12 을 반환합니다. getAbsolutePath() 메서드는 http://fusesource.org/montersforhire/nightstalker 을 반환합니다.

52.2.3. URI 템플릿 변수의 값 가져오기

52.2.3.1. 개요

“경로 설정” 에 설명된 대로 리소스 경로에는 값에 동적으로 바인딩된 변수 세그먼트가 포함될 수 있습니다. 종종 이러한 변수 경로 세그먼트는 “URI 경로에서 데이터 가져오기” 에 설명된 대로 리소스 메서드의 매개변수로 사용됩니다. 그러나 URI 컨텍스트를 통해 액세스할 수도 있습니다.

52.2.3.2. 경로 매개변수를 가져오는 방법

UriInfo 인터페이스는 예 52.1. “URI 컨텍스트에서 경로 매개변수를 반환하는 방법” 에 표시된 두 가지 방법을 제공하여 경로 매개변수 목록을 반환합니다.

예 52.1. URI 컨텍스트에서 경로 매개변수를 반환하는 방법

MultivaluedMap<java.lang.String, java.lang.String>getPathParametersMultivaluedMap<java.lang.String, java.lang.String>getPathParametersbooleandecode

매개 변수를 사용하지 않는 getPathParameters() 메서드는 경로 매개 변수를 자동으로 디코딩합니다. URI 디코딩을 비활성화하려면 getPathParameters(false) 를 사용합니다.

값은 템플릿 ID를 키로 사용하여 맵에 저장됩니다. 예를 들어 리소스에 대한 URI 템플릿이 /{color}/box/{note} 인 경우 반환된 맵에는 색상이 있고 참고 된 두 개의 항목이 있습니다.

52.2.3.3. 예제

예 52.2. “URI 컨텍스트에서 경로 매개변수 추출” URI 컨텍스트를 사용하여 경로 매개 변수를 검색하는 코드를 표시합니다.

예 52.2. URI 컨텍스트에서 경로 매개변수 추출

import javax.ws.rs.Path;
import javax.ws.rs.Get;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.MultivaluedMap;

@Path("/monstersforhire/")
public class MonsterService

  @GET
  @Path("/{type}/{size}")
  public Monster getMonster(@Context UriInfo uri)
  {
    MultivaluedMap paramMap = uri.getPathParameters();
    String type = paramMap.getFirst("type");
    String size = paramMap.getFirst("size");
  }
}
Copy to Clipboard Toggle word wrap

53장. 주석 상속

초록

Cryostat-RS 주석은 주석이 달린 인터페이스를 구현하는 하위 클래스 및 클래스에 상속될 수 있습니다. 상속 메커니즘을 사용하면 하위 클래스 및 구현 클래스가 상위에서 상속된 주석을 재정의할 수 있습니다.

53.1. 개요

상속은 개발자가 특정 요구 사항을 충족할 수 있는 일반 개체를 만들 수 있기 때문에 Java에서 더 강력한 메커니즘 중 하나입니다. Cryostat-RS는 클래스를 슈퍼 클래스에서 상속하기 위해 클래스를 매핑하는 데 사용되는 주석을 허용하여 이 기능을 유지합니다.

Cryostat-RS의 주석 상속도 인터페이스를 지원하도록 확장됩니다. 구현 클래스는 구현하는 인터페이스에 사용되는 Cryostat-RS 주석을 상속합니다.

Cryostat-RS 상속 규칙은 상속된 주석을 재정의하는 메커니즘을 제공합니다. 그러나 슈퍼 클래스 또는 인터페이스에서 상속하는 구문에서 Cryostat-RS 주석을 완전히 제거할 수 없습니다.

53.2. 상속 규칙

리소스 클래스는 구현하는 인터페이스에서 Cryostat-RS 주석을 상속합니다. 리소스 클래스는 확장되는 슈퍼 클래스의 모든 Cryostat-RS 주석도 상속합니다. 슈퍼 클래스에서 상속된 주석은 am 인터페이스에서 상속된 주석보다 우선합니다.

예 53.1. “주석 상속” 에 표시된 코드 샘플에서 Kaijin 클래스의 getMonster() 메서드는 Kaiju 인터페이스의 @Path,@GET, @PathParam 주석을 상속합니다.

예 53.1. 주석 상속

public interface Kaiju
{
  @GET
  @Path("/{id}")
  public Monster getMonster(@PathParam("id") int id);
  ...
}

@Path("/kaijin")
public class Kaijin implements Kaiju
{
  public Monster getMonster(int id)
  {
    ...
  }
  ...
}
Copy to Clipboard Toggle word wrap

53.3. 상속된 주석 덮어쓰기

상속된 주석을 재정의하는 것은 새 주석을 제공하는 것만큼 쉽습니다. 하위 클래스 또는 구현 클래스가 메서드에 대한 자체 Cryostat-RS 주석을 제공하는 경우 해당 메서드에 대한 모든 Cryostat-RS 주석이 무시됩니다.

예 53.2. “주석 상속 덮어쓰기” 에 표시된 코드 샘플에서 Kaijin 클래스의 getMonster() 메서드는 Kaiju 인터페이스에서 주석을 상속하지 않습니다. 구현 클래스는 @Produces 주석을 재정의하여 인터페이스의 모든 주석을 무시합니다.

예 53.2. 주석 상속 덮어쓰기

public interface Kaiju
{
  @GET
  @Path("/{id}")
  @Produces("text/xml");
  public Monster getMonster(@PathParam("id") int id);
  ...
}

@Path("/kaijin")
public class Kaijin implements Kaiju
{

  @GET
  @Path("/{id}")
  @Produces("application/octect-stream");
  public Monster getMonster(@PathParam("id") int id)
  {
    ...
  }
  ...
}
Copy to Clipboard Toggle word wrap

54장. OpenAPI 지원을 사용하여 Cryostat-RS 끝점 확장

초록

CXF OpenApiFeature(org.apache.cxf.jaxrs.openapi.OpenApiFeature)를 사용하면 간단한 구성으로 게시된 Cryostat-RS 서비스 끝점을 확장하여 OpenAPI 문서를 생성할 수 있습니다.

OpenApiFeature는 Spring Boot 및 Karaf 구현 모두에서 지원됩니다.

54.1. OpenApiFeature 옵션

OpenApiFeature에서 다음 옵션을 사용할 수 있습니다.

Expand
표 54.1. OpenApiFeature 작업
이름설명Default

configLocation

OpenAPI 구성 위치

null

contactEmail

연락처 이메일+

null

contactName

연락처 이름+

null

contactUrl

연락처 링크+

null

customizer

customizer 클래스 인스턴스

null

description

description+

null

filterClass

보안 필터++

null

ignoredRoutes

모든 리소스를 스캔할 때 특정 경로를 제외합니다( scanAllResources)++ 참조

null

라이센스

라이센스+

null

licenseUrl

라이센스 URL+

null

prettyPrint

openapi.json을 생성할 때 JSON 문서 ++를 완전히 인쇄합니다.

true

propertiesLocation

속성 파일 위치

/swagger.properties

readAllResources

@Operation++ 없이 모든 작업도 읽습니다.

true

resourceClasses

++을 검사해야 하는 리소스 클래스 목록입니다.

null

resourcePackages

리소스를 스캔해야 하는 패키지 이름 목록

null

runAsFilter

기능을 필터로 실행

false

scan

모든 Cryostat-RS 리소스를 자동으로 스캔

true

scanKnownConfigLocations

알려진 OpenAPI 구성 위치(classpath 또는 filesystem)를 스캔합니다.

openapi-configuration.yaml
openapi-configuration.json
openapi.yaml
openapi.json
Copy to Clipboard Toggle word wrap

true

scannerClass

애플리케이션, 리소스 패키지, 리소스 클래스 및 클래스 경로 스캔의 범위를 지정하는 데 사용되는 Cryostat-RS API 스캐너 클래스의 이름, 리소스 검사 섹션을 참조하십시오.

null

securityDefinitions

보안 정의 목록+

null

supportSwaggerUi

SwaggerUI 지원 켜기/오프

null(== true)

swaggerUiConfig

Swagger UI 구성

null

swaggerUiMavenGroupAndArtifact

SwaggerUI를 고정하기 위한 Maven 아티팩트

null

swaggerUiVersion

SwaggerUI의 버전

null

termsOfServiceUrl

서비스 URL+의 용어

null

title

제목+

null

useContextBasedConfig

설정된 경우 각 OpenApiContext 인스턴스에 대해 고유한 컨텍스트 ID가 생성될 것입니다( 여러 서버 끝점 사용을참조하십시오). 또한 scan 속성을 false로 설정할 수 있습니다.

false

버전

version+

null

+ 옵션은 OpenAPI 클래스에 정의되어 있습니다.

++ 옵션은 SwaggerConfiguration 클래스에서 정의됩니다.

54.2. Karaf Implementations

이 섹션에서는 JAR 파일 내에 REST 서비스를 정의하고 Karaf 컨테이너의 Fuse에 배포하는 OpenApiFeature를 사용하는 방법을 설명합니다.

54.2.1. 빠른 시작 예

Fuse 소프트웨어 다운로드 페이지에서 Red Hat Fuse 빠른 시작을 다운로드할 수 있습니다.

빠른 시작 zip 파일에는 CXF를 사용하여 RESTful(JAX-RS) 웹 서비스를 생성하는 방법과 OpenAPI를 활성화하고 Cryostat-RS 엔드포인트에 주석을 달 수 있는 방법을 보여주는 퀵 스타트를 위한 /cxf/rest/ 디렉터리가 포함되어 있습니다.

54.2.2. OpenAPI 활성화

OpenAPI를 활성화하려면 다음이 포함됩니다.

  • CXF 클래스(org.apache.cxf.jaxrs.openapi.OpenApiFeature)를 < jaxrs:server > 정의에 추가하여 CXF 서비스를 정의하는 XML 파일 수정

    예를 들면 55.4 예제 XML 파일 을 참조하십시오.

  • REST 리소스 클래스에서 다음을 수행합니다.

    • 서비스에 필요한 각 주석에 대해 OpenAPI 주석을 가져옵니다.

      import io.swagger.annotations.*
      Copy to Clipboard Toggle word wrap

      여기서 * = Api,ApiOperation,ApiParam,ApiResponse,ApiResponses 등입니다.

      자세한 내용은 https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X.

      예를 들면 예 55.5 리소스 클래스 을 참조하십시오.

    • Cryostat-RS 주석이 달린 엔드포인트(@PATH,@PUT,@POST,@GET,@Produces,@Consumes,@DELETE,@PathParam 등)에 OpenAPI 주석을 추가합니다.

예를 들면 예 55.5 리소스 클래스 을 참조하십시오.

55.4 예제 XML 파일

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
    xmlns:cxf="http://cxf.apache.org/blueprint/core"
    xsi:schemaLocation="
      http://www.osgi.org/xmlns/blueprint/v1.0.0
https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
      http://cxf.apache.org/blueprint/jaxrs
http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
      http://cxf.apache.org/blueprint/core
http://cxf.apache.org/schemas/blueprint/core.xsd">

    <jaxrs:server id="customerService" address="/crm">
        <jaxrs:serviceBeans>
            <ref component-id="customerSvc"/>
        </jaxrs:serviceBeans>
        <jaxrs:providers>
           <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
        </jaxrs:providers>
        <jaxrs:features>
        <bean class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
          <property name="title" value="Fuse:CXF:Quickstarts - Customer Service" />
          <property name="description" value="Sample REST-based Customer Service" />
          <property name="version" value="${project.version}" />
        </bean>
        </jaxrs:features>
    </jaxrs:server>

    <cxf:bus>
        <cxf:features>
          <cxf:logging />
        </cxf:features>
        <cxf:properties>
            <entry key="skip.default.json.provider.registration" value="true" />
        </cxf:properties>
    </cxf:bus>

    <bean id="customerSvc" class="org.jboss.fuse.quickstarts.cxf.rest.CustomerService"/>

</blueprint>
Copy to Clipboard Toggle word wrap

예 55.5 리소스 클래스

.
.
.

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

.
.
.

@Path("/customerservice/")
@Api(value = "/customerservice", description = "Operations about customerservice")
public class CustomerService {

    private static final Logger LOG =
          LoggerFactory.getLogger(CustomerService.class);

    private MessageContext jaxrsContext;
    private long currentId                = 123;
    private Map<Long, Customer> customers = new HashMap<>();
    private Map<Long, Order> orders       = new HashMap<>();

    public CustomerService() {
        init();
    }


    @GET
    @Path("/customers/{id}/")
    @Produces("application/xml")
    @ApiOperation(value = "Find Customer by ID", notes = "More notes about this
        method", response = Customer.class)
    @ApiResponses(value = {
            @ApiResponse(code = 500, message = "Invalid ID supplied"),
            @ApiResponse(code = 204, message = "Customer not found")
            })
    public Customer getCustomer(@ApiParam(value = "ID of Customer to fetch",
        required = true) @PathParam("id") String id) {
        LOG.info("Invoking getCustomer, Customer id is: {}", id);
        long idNumber = Long.parseLong(id);
        return customers.get(idNumber);
    }


    @PUT
    @Path("/customers/")
    @Consumes({ "application/xml", "application/json" })
    @ApiOperation(value = "Update an existing Customer")
    @ApiResponses(value = {
            @ApiResponse(code = 500, message = "Invalid ID supplied"),
            @ApiResponse(code = 204, message = "Customer not found")
            })
    public Response updateCustomer(@ApiParam(value = "Customer object that needs
        to be updated", required = true) Customer customer) {
        LOG.info("Invoking updateCustomer, Customer name is: {}", customer.getName());
        Customer c = customers.get(customer.getId());
        Response r;
        if (c != null) {
            customers.put(customer.getId(), customer);
            r = Response.ok().build();
        } else {
            r = Response.notModified().build();
        }

        return r;
    }

    @POST
    @Path("/customers/")
    @Consumes({ "application/xml", "application/json" })
    @ApiOperation(value = "Add a new Customer")
    @ApiResponses(value = { @ApiResponse(code = 500, message = "Invalid ID
        supplied"), })
    public Response addCustomer(@ApiParam(value = "Customer object that needs to
        be updated", required = true) Customer customer) {
        LOG.info("Invoking addCustomer, Customer name is: {}", customer.getName());
        customer.setId(++currentId);

        customers.put(customer.getId(), customer);
        if (jaxrsContext.getHttpHeaders().getMediaType().getSubtype().equals("json"))
    {
            return Response.ok().type("application/json").entity(customer).build();
        } else {
            return Response.ok().type("application/xml").entity(customer).build();
        }
    }

    @DELETE
    @Path("/customers/{id}/")
    @ApiOperation(value = "Delete Customer")
    @ApiResponses(value = {
            @ApiResponse(code = 500, message = "Invalid ID supplied"),
            @ApiResponse(code = 204, message = "Customer not found")
            })
    public Response deleteCustomer(@ApiParam(value = "ID of Customer to delete",
        required = true) @PathParam("id") String id) {
        LOG.info("Invoking deleteCustomer, Customer id is: {}", id);
        long idNumber = Long.parseLong(id);
        Customer c = customers.get(idNumber);

        Response r;
        if (c != null) {
            r = Response.ok().build();
            customers.remove(idNumber);
        } else {
            r = Response.notModified().build();
        }

        return r;
    }

.
.
.

}
Copy to Clipboard Toggle word wrap

54.3. Spring 부팅 구현

이 섹션에서는 Spring Boot에서 Swagger2Feature를 사용하는 방법을 설명합니다.

OpenAPI 3 구현의 경우 OpenApiFeature(org.apache.cxf.jaxrs.openapi.OpenApiFeature)를 사용합니다.

54.3.1. 빠른 시작 예

빠른 시작 예(https://github.com/fabric8-quickstarts/spring-boot-cxf-jaxrs)는 Spring Boot에서 Apache CXF를 사용하는 방법을 보여줍니다. 빠른 시작에서는 Spring Boot를 사용하여 Swagger가 활성화된 CXF Cryostat-RS 끝점을 포함하는 애플리케이션을 구성합니다.

54.3.2. Swagger 활성화

Swagger 활성화에는 다음이 포함됩니다.

  • REST 애플리케이션에서는 다음을 수행합니다.

    • Swagger2Feature 가져오기:

      import org.apache.cxf.jaxrs.swagger.Swagger2Feature;
      Copy to Clipboard Toggle word wrap
    • CXF 끝점에 Swagger2Feature 추가:

      endpoint.setFeatures(Arrays.asList(new Swagger2Feature()));
      Copy to Clipboard Toggle word wrap

      예를 들면 55.1 예제 REST 애플리케이션 을 참조하십시오.

  • Java 구현 파일에서 서비스에 필요한 각 주석에 대한 Swagger API 주석을 가져옵니다.

    import io.swagger.annotations.*
    Copy to Clipboard Toggle word wrap

    여기서 * = Api,ApiOperation,ApiParam,ApiResponse,ApiResponses 등입니다.

    자세한 내용은 https://github.com/swagger-api/swagger-core/wiki/Annotations 을 참조하십시오.

    예를 들면 55.2 예제 Java 구현 파일 을 참조하십시오.

  • Java 파일에서 hieradata-RS 주석이 있는 끝점(@PATH,@PUT,@POST,@GET,@Produces,@ DELETE,@PathParam 등)에 Swagger 주석을 추가합니다.

    예를 들면 55.3 예제 Java 파일 예 을 참조하십시오.

55.1 예제 REST 애플리케이션

package io.fabric8.quickstarts.cxf.jaxrs;

import java.util.Arrays;

import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.swagger.Swagger2Feature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SampleRestApplication {

    @Autowired
    private Bus bus;

    public static void main(String[] args) {
        SpringApplication.run(SampleRestApplication.class, args);
    }

    @Bean
    public Server rsServer() {
        // setup CXF-RS
        JAXRSServerFactoryBean endpoint = new JAXRSServerFactoryBean();
        endpoint.setBus(bus);
        endpoint.setServiceBeans(Arrays.<Object>asList(new HelloServiceImpl()));
        endpoint.setAddress("/");
        endpoint.setFeatures(Arrays.asList(new Swagger2Feature()));
        return endpoint.create();
    }
}
Copy to Clipboard Toggle word wrap

55.2 예제 Java 구현 파일

import io.swagger.annotations.Api;

@Api("/sayHello")
public class HelloServiceImpl implements HelloService {

    public String welcome() {
        return "Welcome to the CXF RS Spring Boot application, append /{name} to call the hello service";
    }

    public String sayHello(String a) {
        return "Hello " + a + ", Welcome to CXF RS Spring Boot World!!!";
    }

}
Copy to Clipboard Toggle word wrap

55.3 예제 Java 파일 예

package io.fabric8.quickstarts.cxf.jaxrs;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.springframework.stereotype.Service;

@Path("/sayHello")
@Service
public interface HelloService {

    @GET
    @Path("")
    @Produces(MediaType.TEXT_PLAIN)
    String welcome();

    @GET
    @Path("/{a}")
    @Produces(MediaType.TEXT_PLAIN)
    String sayHello(@PathParam("a") String a);

}
Copy to Clipboard Toggle word wrap

54.4. OpenAPI 문서에 액세스

OpenApiFeature에서 OpenAPI 문서를 활성화하면 서비스 엔드포인트 위치에 구성된 위치 URL 다음에 /openapi.json 또는 /openapi.yaml 에서 사용할 수 있습니다.

예를 들어, http://host:port/context/services/ 에 게시된 Cryostat-RS 끝점의 경우 컨텍스트 는 웹 애플리케이션 컨텍스트이고 /services 는 서블릿 URL인 경우 http://host:port/context/services/openapi.jsonhttp://host:port/context/services/openapi.yaml 에서 OpenAPI 문서를 사용할 수 있습니다.

OpenApiFeature가 활성화되어 있으면 CXF Services 페이지가 OpenAPI 문서에 연결됩니다.

위의 예제에서는 http://host:port/context/services/services 로 이동한 다음 OpenAPI JSON 문서를 반환하는 링크를 따릅니다.

CORS 지원이 다른 호스트의 OpenAPI UI에서 정의에 액세스해야 하는 경우 cxf-rt-rs-security-cors 에서 CrossOriginResourceSharingFilter 를 추가할 수 있습니다.

54.5. 역방향 프록시를 통해 OpenAPI에 액세스

역방향 프록시를 통해 OpenAPI JSON 문서 또는 OpenAPI UI에 액세스하려면 다음 옵션을 설정합니다.

  • CXFServlet use-x-forwarded-headers init 매개변수를 true 로 설정합니다.

    • Spring Boot에서 매개변수 이름 앞에 cxf.servlet.init:을 접두사로 지정합니다.

      cxf.servlet.init.use-x-forwarded-headers=true
      Copy to Clipboard Toggle word wrap
    • Karaf에서 installDir/etc/org.apache.cxf.osgi.cfg 구성 파일에 다음 행을 추가합니다.

      cxf.servlet.init.use-x-forwarded-headers=true
      Copy to Clipboard Toggle word wrap

      참고: etc 디렉토리에 org.apache.cxf.osgi.cfg 파일이 없는 경우 하나를 생성할 수 있습니다.

  • OpenApiFeature basePath 옵션에 값을 지정하고 OpenAPI가 basePath 값을 캐싱하지 못하도록 하려면 OpenApiFeature usePathBasedConfig 옵션을 TRUE 로 설정합니다.

    <bean class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
        <property name="usePathBasedConfig" value="TRUE" />
    </bean>
    Copy to Clipboard Toggle word wrap

VII 부. Apache CXF Interceptors 개발

이 가이드에서는 메시지에서 사전 및 사후 처리를 수행할 수 있는 Apache CXF 인터셉터를 작성하는 방법을 설명합니다.

55장. Apache CXF Runtime의 인터셉터

초록

Apache CXF 런타임의 대부분의 기능은 인터셉터에 의해 구현됩니다. Apache CXF 런타임에서 생성한 모든 엔드포인트에는 메시지를 처리하기 위한 세 가지 잠재적인 인터셉터 체인이 있습니다. 이러한 체인의 인터셉터는 유선 간에 전송된 원시 데이터와 엔드포인트의 구현 코드에서 처리하는 Java 오브젝트 간에 메시지를 변환하는 역할을 합니다. 인터셉터는 적절한 순서로 처리가 이루어지도록 단계별로 구성됩니다.

55.1. 개요

Apache CXF의 많은 부분에서는 메시지 처리 작업이 포함됩니다. 소비자가 원격 서비스를 호출할 때 런타임은 데이터를 사용할 수 있는 메시지로 마샬링해야 하며, 이를 차선에 배치해야 합니다. 서비스 공급자는 메시지를 분리하고, 비즈니스 논리를 실행하고, 응답을 적절한 메시지 형식으로 마샬링해야 합니다. 그런 다음 소비자는 응답 메시지를 분리하고 적절한 요청과 상관 관계를 맺고 소비자의 애플리케이션 코드로 다시 전달해야 합니다. Apache CXF 런타임은 기본 마샬링 및 비마일링 외에도 메시지 데이터를 사용하여 여러 가지 다른 작업을 수행할 수 있습니다. 예를 들어 WS-RM이 활성화된 경우 런타임은 메시지를 마샬링하고 축소하기 전에 메시지 청크 및 승인 메시지를 처리해야 합니다. 보안이 활성화된 경우 런타임은 메시지 처리 순서의 일부로 메시지의 자격 증명을 확인해야 합니다.

그림 55.1. “Apache CXF 인터셉터 체인” 서비스 공급자가 요청 메시지를 수신할 때 걸리는 기본 경로를 표시합니다.

그림 55.1. Apache CXF 인터셉터 체인

인터셉터 체인 내 및 아웃 인터셉터 체인을 사용하여 끝점 표시

55.2. Apache CXF에서 메시지 처리

Apache CXF에서 개발한 소비자가 원격 서비스를 호출하면 다음과 같은 메시지 처리 시퀀스가 시작됩니다.

  1. Apache CXF 런타임은 요청을 처리하기 위해 아웃바운드 인터셉터 체인을 생성합니다.
  2. 호출이 양방향 메시지 교환을 시작하면 런타임은 인바운드 인터셉터 체인과 오류 처리 인터셉터 체인을 생성합니다.
  3. 요청 메시지는 아웃바운드 인터셉터 체인을 통해 순차적으로 전달됩니다.

    체인의 각 인터셉터는 메시지에서 일부 처리를 수행합니다. 예를 들어 Apache CXF가 message를 통해 message를 포함시키고, Apache CXF가 message를 전송했습니다.

  4. 아웃바운드 체인의 인터셉터 중 하나가 오류 조건을 생성하는 경우 체인은 예기치 않고 제어가 애플리케이션 수준 코드로 반환됩니다.

    인터셉터 체인은 이전에 호출한 모든 인터셉터에서 fault 처리 방법을 호출하여 적용되지 않습니다.

  5. 요청이 적절한 서비스 공급자에게 전달됩니다.
  6. 응답이 수신되면 인바운드 인터셉터 체인을 통해 순차적으로 전달됩니다.

    참고

    응답이 오류 메시지이면 오류 처리 인터셉터 체인으로 전달됩니다.

  7. 인바운드 체인의 인터셉터 중 오류 조건을 생성하는 경우 체인은 예기치 않은 것입니다.
  8. 메시지가 인바운드 인터셉터 체인의 끝에 도달하면 애플리케이션 코드로 다시 전달됩니다.

Apache CXF에서 개발한 서비스 공급자가 소비자로부터 요청을 수신하면 유사한 프로세스가 수행됩니다.

  1. Apache CXF 런타임은 요청 메시지를 처리하기 위해 인바운드 인터셉터 체인을 생성합니다.
  2. 요청이 양방향 메시지 교환의 일부인 경우 런타임은 아웃바운드 인터셉터 체인과 오류 처리 인터셉터 체인을 생성합니다.
  3. 요청은 인바운드 인터셉터 체인을 통해 순차적으로 전달됩니다.
  4. 인바운드 체인의 인터셉터 중 하나가 오류 조건을 생성하는 경우 체인은 예기치 않고 결함을 소비자에게 디스패치합니다.

    인터셉터 체인은 이전에 호출한 모든 인터셉터에서 fault 처리 방법을 호출하여 적용되지 않습니다.

  5. 요청이 인바운드 인터셉터 체인의 끝에 도달하면 서비스 구현에 전달됩니다.
  6. 응답이 준비되면 아웃바운드 인터셉터 체인을 통해 순차적으로 전달됩니다.

    참고

    응답이 예외인 경우 오류 처리 인터셉터 체인을 통해 전달됩니다.

  7. 아웃바운드 체인의 인터셉터가 오류 조건을 생성하는 경우 체인은 예기치 않고 오류 메시지가 전달됩니다.
  8. 요청이 아웃바운드 체인의 끝에 도달하면 소비자에게 전달됩니다.

55.3. 인터셉터

Apache CXF 런타임의 모든 메시지 처리는 인터셉터 에 의해 수행됩니다. 인터셉터는 애플리케이션 계층에 전달하기 전에 메시지 데이터에 액세스할 수 있는 Cryostat입니다. 메시지 변환, 메시지 제거 또는 메시지 데이터 검증 등 여러 작업을 수행할 수 있습니다. 예를 들어 인터셉터는 메시지 외부에서 보안 헤더를 읽고 외부 보안 서비스에 대한 자격 증명을 검증하고 메시지 처리를 계속할 수 있는지 결정할 수 있습니다.

인터셉터에서 사용할 수 있는 메시지 데이터는 다음과 같은 몇 가지 요인에 의해 결정됩니다.

  • 인터셉터의 체인
  • 인터셉터의 단계
  • 체인의 앞부분에서 발생하는 다른 인터셉터

55.4. 단계

인터셉터는 단계로 구성됩니다. 단계는 공통 기능을 사용하는 인터셉터의 논리 그룹입니다. 각 단계는 특정 유형의 메시지 처리를 담당합니다. 예를 들어 애플리케이션 계층에 전달되는 마샬링된 Java 오브젝트를 처리하는 인터셉터는 모두 동일한 단계에서 수행됩니다.

55.5. 인터셉터 체인

단계는 인터셉터 체인에 집계됩니다. 인터셉터 체인은 메시지가 인바운드인지 아웃바운드인지 여부에 따라 정렬되는 인터셉터 단계 목록입니다.

Apache CXF를 사용하여 생성된 각 끝점에는 세 가지 인터셉터 체인이 있습니다.

  • 인바운드 메시지에 대한 체인
  • 아웃 바운드 메시지를 위한 체인
  • 오류 메시지에 대한 체인

인터셉터 체인은 주로 엔드포인트에서 사용하는 바인딩 및 전송 선택에 따라 구성됩니다. 보안 또는 로깅과 같은 기타 런타임 기능을 추가하면 체인에 인터셉터도 추가됩니다. 개발자는 구성을 사용하여 체인에 사용자 정의 인터셉터를 추가할 수도 있습니다.

55.6. 인터셉터 개발

인터셉터의 기능에 관계없이 항상 동일한 기본 절차를 따릅니다.

  1. 56장. Interceptor API

    Apache CXF는 사용자 지정 인터셉터를 보다 쉽게 개발할 수 있도록 다양한 추상 인터셉터를 제공합니다.

  2. 57.2절. “인터셉터의 단계 지정”

    인터셉터는 메시지의 특정 부분을 사용할 수 있어야 하며 데이터가 특정 형식으로 되어 있어야 합니다. 메시지의 내용과 데이터 형식은 인터셉터의 단계에 따라 부분적으로 결정됩니다.

  3. 57.3절. “단계에서 인터셉터 배치 제한”

    일반적으로 단계 내에서 인터셉터의 순서가 중요하지 않습니다. 그러나 특정 상황에서는 인터셉터가 동일한 단계의 다른 인터셉터 이전 또는 이후에 실행되도록 하는 것이 중요할 수 있습니다.

  4. 58.2절. “메시지 처리”
  5. 58.3절. “오류 후 축소 해제”

    인터셉터가 실행된 후 활성 인터셉터 체인에서 오류가 발생하면 오류 처리 논리가 호출됩니다.

  6. 59장. 인터셉터를 사용하도록 끝점 구성

56장. Interceptor API

초록

인터셉터는 기본 인터셉터 인터페이스를 확장하는 PhaseInterceptor 인터페이스를 구현합니다. 이 인터페이스는 Apache CXF의 런타임에서 인터셉터 실행을 제어하기 위해 사용하는 여러 방법을 정의하고 애플리케이션 개발자가 구현하는 데 적합하지 않습니다. 인터셉터 개발을 단순화하기 위해 Apache CXF는 확장 가능한 여러 추상 인터셉터 구현을 제공합니다.

56.1. 인터페이스

Apache CXF의 모든 인터셉터는 예 56.1. “기본 인터셉터 인터페이스” 에 표시된 기본 인터셉터 인터페이스를 구현합니다.

예 56.1. 기본 인터셉터 인터페이스

package org.apache.cxf.interceptor;

public interface Interceptor<T extends Message>
{

  void handleMessage(T message) throws Fault;

  void handleFault(T message);

}
Copy to Clipboard Toggle word wrap

Interceptor 인터페이스는 개발자가 사용자 정의 인터셉터에 구현해야 하는 두 가지 방법을 정의합니다.

handleMessage()
handleMessage() 메서드는 인터셉터에서 대부분의 작업을 수행합니다. 메시지 체인의 각 인터셉터에서 호출되며 처리되는 메시지의 내용을 수신합니다. 개발자는 이 메서드에서 인터셉터의 메시지 처리 논리를 구현합니다. handleMessage() 메서드 구현에 대한 자세한 내용은 58.2절. “메시지 처리” 을 참조하십시오.
handleFault()
일반적인 메시지 처리가 중단되었을 때 handleFault() 메서드는 인터셉터에서 호출됩니다. 런타임은 인터셉터 체인을 되감기 때문에 호출되는 각 인터셉터의 handleFault() 메서드를 역순으로 호출합니다. handleFault() 메서드를 구현하는 방법에 대한 자세한 내용은 58.3절. “오류 후 축소 해제” 을 참조하십시오.

대부분의 인터셉터는 인터셉터 인터페이스를 직접 구현하지 않습니다. 대신 예 56.2. “단계 인터셉터 인터페이스” 에 표시된 PhaseInterceptor 인터페이스를 구현합니다. PhaseInterceptor 인터페이스는 인터셉터 체인에 참여하는 인터셉터를 허용하는 네 가지 방법을 추가합니다.

예 56.2. 단계 인터셉터 인터페이스

package org.apache.cxf.phase;
...

public interface PhaseInterceptor<T extends Message> extends Interceptor<T>
{

    Set<String> getAfter();

    Set<String> getBefore();

    String getId();

    String getPhase();

}
Copy to Clipboard Toggle word wrap

56.2. 추상 인터셉터 클래스

PhaseInterceptor 인터페이스를 직접 구현하는 대신 개발자는 AbstractPhaseInterceptor 클래스를 확장해야합니다. 이 추상 클래스는 PhaseInterceptor 인터페이스의 단계 관리 메서드에 대한 구현을 제공합니다. AbstractPhaseInterceptor 클래스는 handleFault() 메서드의 기본 구현도 제공합니다.

개발자는 handleMessage() 메서드 구현을 제공해야 합니다. 또한 handleFault() 메서드에 대해 다른 구현을 제공할 수 있습니다. 개발자 제공 구현은 일반 org.apache.cxf.message.Message 인터페이스에서 제공하는 방법을 사용하여 메시지 데이터를 조작할 수 있습니다.

Cryostat 메시지와 함께 작동하는 애플리케이션의 경우 Apache CXF는 AbstractSoapInterceptor 클래스를 제공합니다. 이 클래스를 확장하면 handleMessage() 메서드와 handleFault() 메서드를 org.apache.cxf.binding.soap.SoapMessage 오브젝트로 메시지 데이터에 액세스할 수 있습니다. SoapMessage 오브젝트에는 message에서 Cryostat 헤더, Cryostat 및 기타 Cryostat 메타데이터를 검색하는 방법이 있습니다.

57장. 인터셉터가 Invoked 시기 확인

초록

인터셉터는 단계로 구성됩니다. 인터셉터를 실행하는 단계에 따라 액세스할 수 있는 메시지 데이터의 부분이 결정됩니다. 인터셉터는 동일한 단계에서 다른 인터셉터와의 관계에서 해당 위치를 결정할 수 있습니다. 인터셉터의 단계와 단계 내의 위치는 인터셉터의 생성자 논리의 일부로 설정됩니다.

57.1. 인터셉터 위치 지정

사용자 지정 인터셉터를 개발할 때 가장 먼저 고려해야 할 사항은 메시지 처리 체인에서 인터셉터가 속하는 위치입니다. 개발자는 다음 두 가지 방법 중 하나로 메시지 처리 체인에서 인터셉터의 위치를 제어할 수 있습니다.

  • 인터셉터의 단계 지정
  • 단계 내 인터셉터 위치에 제약 조건 지정

일반적으로 인터셉터의 위치를 지정하는 코드는 인터셉터의 생성자에 배치됩니다. 이를 통해 런타임은 인터셉터를 인스턴스화하고 애플리케이션 수준 코드에서 명시적 작업 없이 인터셉터 체인에 적절한 위치를 배치할 수 있습니다.

57.2. 인터셉터의 단계 지정

57.2.1. 개요

인터셉터는 단계로 구성됩니다. 인터셉터의 단계는 메시지 처리 시퀀스에서 호출되는 시기를 결정합니다. 개발자는 인터셉터의 단계 생성자를 지정합니다. 단계는 프레임워크에서 제공하는 상수 값을 사용하여 지정됩니다.

57.2.2. 단계

단계는 인터셉터의 논리 컬렉션입니다. 그림 57.1. “인터셉터 단계” 에 표시된 대로 단계 내의 인터셉터를 순차적으로 호출됩니다.

그림 57.1. 인터셉터 단계

인터셉터는 단계별로 연결되어 있습니다.

단계는 정렬된 목록에 함께 연결되어 인터셉터 체인을 형성하고 메시지 처리 프로세스에서 정의된 논리 단계를 제공합니다. 예를 들어 인바운드 인터셉터 체인의 RECEIVE 단계의 인터셉터 그룹은 유선에서 선택한 원시 메시지 데이터를 사용하여 전송 수준 세부 정보를 처리합니다.

그러나 어떤 단계에서든 수행할 수 있는 작업은 적용되지 않습니다. 단계 내의 인터셉터는 단계의 영성 상태에 있는 작업을 준수하는 것이 좋습니다.

Apache CXF에서 정의한 전체 단계 목록은 62장. Apache CXF 메시지 처리 단계 에서 확인할 수 있습니다.

57.2.3. 단계 지정

Apache CXF는 단계를 지정하는 데 사용할 org.apache.cxf.Phase 클래스를 제공합니다. 클래스는 상수 컬렉션입니다. Apache CXF에서 정의한 각 단계는 단계 클래스에서 해당 상수를 갖습니다. 예를 들어 RECEIVE 단계는 값 Phase.RECEIVE로 지정됩니다.

57.2.4. 단계 설정

인터셉터의 단계는 인터셉터의 생성자에 설정됩니다. AbstractPhaseInterceptor 클래스는 인터셉터를 인스턴스화하기 위한 세 가지 생성자를 정의합니다.

  • 공용 AbstractPhaseInterceptor(String 단계)- 인터셉터의 단계를 지정된 단계로 설정하고 인터셉터의 ID를 인터셉터의 클래스 이름으로 자동으로 설정합니다.

    이 생성자는 대부분의 사용 사례를 충족합니다.

  • public AbstractPhaseInterceptor(String id, string 단계)- 인터셉터의 ID를 첫 번째 매개 변수로 전달된 문자열에 설정하고 인터셉터의 단계를 두 번째 문자열로 설정합니다.
  • 공용 AbstractPhaseInterceptor(String 단계, 부울 uniqueId)- 인터셉터에서 생성된 고유 ID를 사용해야 하는지 여부를 지정합니다. uniqueId 매개변수가 true 이면 시스템에서 인터셉터의 ID가 계산됩니다. uniqueId 매개변수가 false 인 경우 인터셉터의 ID가 인터셉터의 클래스 이름으로 설정됩니다.

사용자 정의 인터셉터 단계를 설정하는 권장 방법은 예 57.1. “인터셉터의 단계 설정” 과 같이 super() 메서드를 사용하여 AbstractPhaseInterceptor 생성자에 단계를 전달하는 것입니다.

예 57.1. 인터셉터의 단계 설정

import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class StreamInterceptor extends AbstractPhaseInterceptor<Message>
 {

    public StreamInterceptor()
   {
     super(Phase.PRE_STREAM);
    }
}
Copy to Clipboard Toggle word wrap

예 57.1. “인터셉터의 단계 설정” 에 표시된 StreamInterceptor 인터셉터는 PRE_STREAM 단계에 배치됩니다.

57.3. 단계에서 인터셉터 배치 제한

57.3.1. 개요

인터셉터를 단계에 배치하면 인터셉터가 제대로 작동하는지 확인하기 위해 배치에 대한 충분한 제어 기능을 제공하지 못할 수 있습니다. 예를 들어, SAAJ API를 사용하여 메시지의 Cryostat 헤더를 검사해야 하는 인터셉터가 메시지를 SAAJ 개체로 변환하는 인터셉터 후에 실행해야 합니다. 또한 한 인터셉터가 다른 인터셉터에 필요한 메시지의 일부를 소비하는 경우가 있을 수 있습니다. 이러한 경우 개발자는 인터셉터 전에 실행해야 하는 인터셉터 목록을 제공할 수 있습니다. 개발자는 인터셉터 이후에 실행해야 하는 인터셉터 목록을 제공할 수도 있습니다.

중요

런타임은 인터셉터 단계 내에서만 이러한 목록을 적용할 수 있습니다. 개발자가 현재 단계 후에 실행해야 하는 인터셉터 목록에 이전 단계에서 인터셉터를 배치하면 런타임에서 요청을 무시합니다.

57.3.2. 전에 체인에 추가

인터셉터를 개발할 때 발생하는 한 가지 문제는 인터셉터에 필요한 데이터가 항상 존재하지 않는다는 것입니다. 이는 체인의 한 인터셉터가 나중에 인터셉터에 필요한 메시지 데이터를 사용할 때 발생할 수 있습니다. 개발자는 사용자 정의 인터셉터가 사용하는 것을 제어하고 인터셉터를 수정하여 문제를 해결할 수 있습니다. 그러나 Apache CXF에서 여러 인터셉터를 사용하고 개발자가 수정할 수 없기 때문에 이것이 항상 가능한 것은 아닙니다.

대체 솔루션은 사용자 정의 인터셉터가 사용자 지정 인터셉터에 필요한 메시지 데이터를 사용하는 인터셉터 앞에 사용자 지정 인터셉터를 배치하도록 하는 것입니다. 가장 쉬운 방법은 이전 단계에 배치하는 것이지만 항상 가능한 것은 아닙니다. 인터셉터를 하나 이상의 다른 인터셉터 앞에 배치해야 하는 경우 Apache CXF의 AbstractPhaseInterceptor 클래스는 두 가지 addBefore() 메서드를 제공합니다.

예 57.2. “다른 인터셉터 전에 인터셉터를 추가하는 방법” 에 표시된 대로 하나의 인터셉터 ID를 사용하고 다른 하나는 인터셉터 ID 컬렉션을 사용합니다. 여러 호출을 수행하여 목록에 인터셉터를 계속 추가할 수 있습니다.

예 57.2. 다른 인터셉터 전에 인터셉터를 추가하는 방법

publicaddBeforestringipublicaddBeforeCollection<String>i

예 57.3. “현재 인터셉터 이후 실행해야 하는 인터셉터 목록 지정” 에 표시된 대로 개발자는 사용자 정의 인터셉터의 constuctor에서 addBefore() 메서드를 호출합니다.

예 57.3. 현재 인터셉터 이후 실행해야 하는 인터셉터 목록 지정

public class MyPhasedOutInterceptor extends AbstractPhaseInterceptor
{

    public MyPhasedOutInterceptor() {
        super(Phase.PRE_LOGICAL);
        addBefore(HolderOutInterceptor.class.getName());
    }

...

}
Copy to Clipboard Toggle word wrap

대부분의 인터셉터는 인터셉터 ID에 클래스 이름을 사용합니다.

57.3.3. 다음 체인에 추가

인터셉터에 필요한 데이터가 없는 또 다른 이유는 데이터가 메시지 오브젝트에 배치되지 않았기 때문입니다. 예를 들어 인터셉터는 메시지 데이터를 Cryostat 메시지로 사용하여 작업하려고 할 수 있지만 메시지를 message로 전환하기 전에 체인에 배치되면 작동하지 않습니다. 개발자는 사용자 정의 인터셉터가 사용하는 것을 제어하고 인터셉터를 수정하여 문제를 해결할 수 있습니다. 그러나 Apache CXF에서 여러 인터셉터를 사용하고 개발자가 수정할 수 없기 때문에 이것이 항상 가능한 것은 아닙니다.

대체 솔루션은 사용자 정의 인터셉터에 필요한 메시지 데이터를 생성하는 인터셉터 또는 인터셉터 뒤에 사용자 지정 인터셉터를 배치하도록 하는 것입니다. 가장 쉬운 방법은 이후 단계에 배치하는 것이지만 항상 가능한 것은 아닙니다. AbstractPhaseInterceptor 클래스는 인터셉터를 하나 이상의 다른 인터셉터 뒤에 배치해야 하는 경우 두 가지 addAfter() 메서드를 제공합니다.

예 57.4. “다른 인터셉터 후 인터셉터 추가 방법” 에 표시된 대로 한 가지 방법은 단일 인터셉터 ID를 사용하고 다른 방법은 인터셉터 ID 컬렉션을 사용합니다. 여러 호출을 수행하여 목록에 인터셉터를 계속 추가할 수 있습니다.

예 57.4. 다른 인터셉터 후 인터셉터 추가 방법

publicaddAfterstringipublicaddAfterCollection<String>i

예 57.5. “현재 인터셉터 전에 실행해야 하는 인터셉터 목록 지정” 에 표시된 대로 개발자는 사용자 정의 인터셉터의 constuctor에서 addAfter() 메서드를 호출합니다.

예 57.5. 현재 인터셉터 전에 실행해야 하는 인터셉터 목록 지정

public class MyPhasedOutInterceptor extends AbstractPhaseInterceptor
{

    public MyPhasedOutInterceptor() {
        super(Phase.PRE_LOGICAL);
        addAfter(StartingOutInterceptor.class.getName());
    }

...

}
Copy to Clipboard Toggle word wrap

대부분의 인터셉터는 인터셉터 ID에 클래스 이름을 사용합니다.

58장. 인터셉터 처리 논리 구현

초록

인터셉터를 쉽게 구현할 수 있습니다. 대부분의 처리 논리는 handleMessage() 메서드에 있습니다. 이 메서드는 메시지 데이터를 수신하고 필요에 따라 조작합니다. 개발자는 또한 오류 처리 사례를 처리하기 위해 몇 가지 특수 논리를 추가해야 할 수도 있습니다.

58.1. 인터셉터 흐름

그림 58.1. “인터셉터를 통한 흐름” 인터셉터를 통한 프로세스 흐름을 표시합니다.

그림 58.1. 인터셉터를 통한 흐름

interceptor1

일반적인 메시지 처리에서는 handleMessage() 메서드만 호출됩니다. handleMessage() 메서드는 인터셉터의 메시지 처리 논리가 배치되는 위치입니다.

인터셉터의 handleMessage() 메서드 또는 인터셉터 체인의 후속 인터셉터에서 오류가 발생하면 handleFault() 메서드가 호출됩니다. handleFault() 메서드는 오류가 발생하는 경우 인터셉터 후 정리에 유용합니다. 오류 메시지를 변경하는 데도 사용할 수 있습니다.

58.2. 메시지 처리

58.2.1. 개요

일반적인 메시지 처리에서는 인터셉터의 handleMessage() 메서드가 호출됩니다. 메시지 데이터를 Message 오브젝트로 수신합니다. Message 개체는 메시지의 실제 내용과 함께 메시지 또는 메시지 처리 상태와 관련된 여러 속성을 포함할 수 있습니다. Message 오브젝트의 정확한 내용은 체인의 현재 인터셉터 앞의 인터셉터에 따라 달라집니다.

58.2.2. 메시지 콘텐츠 가져오기

Message 인터페이스는 메시지 내용을 추출하는 데 사용할 수 있는 두 가지 메서드를 제공합니다.

  • public <T> TgetContentjava.lang.Class<T > 형식 getContent() 메서드는 지정된 클래스의 오브젝트에 있는 메시지의 내용을 반환합니다. 콘텐츠를 지정된 클래스의 인스턴스로 사용할 수 없는 경우 null이 반환됩니다. 사용 가능한 콘텐츠 유형 목록은 인터셉터 체인의 인터셉터 위치와 인터셉터 체인의 방향에 따라 결정됩니다.
  • publicCollection<Attachment> getAttachments () 메서드는 메시지와 연결된 바이너리 첨부 파일이 포함된 Java Collection 오브젝트를 반환합니다. 첨부 파일은 org.apache.cxf.message.Attachment 오브젝트에 저장됩니다. attachment 오브젝트는 바이너리 데이터를 관리하는 방법을 제공합니다.

    중요

    첨부 파일은 첨부 처리 인터셉터가 실행된 후에만 사용할 수 있습니다.

58.2.3. 메시지의 방향 확인

메시지 교환을 쿼리하여 메시지 방향을 결정할 수 있습니다. 메시지 교환은 인바운드 메시지와 아웃바운드 메시지를 별도의 속성에 저장합니다.[3]

메시지와 연결된 메시지 교환은 메시지의 getExchange() 메서드를 사용하여 검색됩니다. 예 58.1. “메시지 교환 가져오기” 에 표시된 대로 getExchange() 는 매개변수를 사용하지 않고 메시지 교환을 org.apache.cxf.message.Exchange 오브젝트로 반환합니다.

예 58.1. 메시지 교환 가져오기

ExchangegetExchange

교환 오브젝트에는 교환과 관련된 메시지를 받기 위해 예 58.2. “메시지 교환에서 메시지 가져오기” 에 표시된 네 가지 방법이 있습니다. 각 메서드는 메시지를 org.apache.cxf.Message 오브젝트로 반환하거나 메시지가 없는 경우 null을 반환합니다.

예 58.2. 메시지 교환에서 메시지 가져오기

messagegetInMessageMessagegetInFaultMessageMessagegetOutMessageMessagegetOutFaultMessage

예 58.3. “메시지 체인의 방향 확인” 현재 메시지가 아웃바운드인지 확인하기 위한 코드를 표시합니다. 이 메서드는 메시지 교환을 가져오고 현재 메시지가 교환의 아웃 바운드 메시지와 동일한지 확인합니다. 또한 아웃바운드 오류 오류 메시지를 아웃바운드 오류 가로채기 체인의 오류 메시지에 대해 현재 메시지를 확인합니다.

예 58.3. 메시지 체인의 방향 확인

public static boolean isOutbound()
{
   Exchange exchange = message.getExchange();
        return message != null
               && exchange != null
               && (message == exchange.getOutMessage()
                   || message == exchange.getOutFaultMessage());
}
Copy to Clipboard Toggle word wrap

58.2.4. 예제

예 58.4. “메시지 처리 방법 예” zip 압축 메시지를 처리하는 인터셉터의 코드를 표시합니다. 메시지 방향을 확인한 다음 적절한 작업을 수행합니다.

예 58.4. 메시지 처리 방법 예

import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;

import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class StreamInterceptor extends AbstractPhaseInterceptor<Message>
{

  ...

  public void handleMessage(Message message)
  {

        boolean isOutbound = false;
        isOutbound = message == message.getExchange().getOutMessage()
               || message == message.getExchange().getOutFaultMessage();

        if (!isOutbound)
        {
          try
          {
             InputStream is = message.getContent(InputStream.class);
             GZIPInputStream zipInput = new GZIPInputStream(is);
             message.setContent(InputStream.class, zipInput);
          }
          catch (IOException ioe)
          {
             ioe.printStackTrace();
           }
        }
         else
        {
         // zip the outbound message
        }
    }
  ...
}
Copy to Clipboard Toggle word wrap


[3] 또한 인바운드 및 아웃바운드 결함을 별도로 저장합니다.

58.3. 오류 후 축소 해제

58.3.1. 개요

인터셉터 체인을 실행하는 동안 오류가 발생하면 런타임은 인터셉터 체인을 트래버스하는 것을 중지하고 이미 실행된 체인에 있는 모든 인터셉터의 handleFault() 메서드를 호출하여 체인을 되돌립니다.

handleFault() 메서드는 일반 메시지 처리 중에 인터셉터가 사용하는 모든 리소스를 정리하는 데 사용할 수 있습니다. 메시지 처리가 성공적으로 완료된 경우에만 대기해야 하는 모든 작업을 롤백하는 데 사용할 수도 있습니다. 오류 메시지가 아웃바운드 오류 처리 인터셉터 체인에 전달되는 경우 handleFault() 메서드를 사용하여 결함 메시지에 정보를 추가할 수도 있습니다.

58.3.2. 메시지 페이로드 가져오기

handleFault() 메서드는 일반 메시지 처리에 사용되는 handleMessage() 메서드와 동일한 Message 오브젝트를 수신합니다. Message 오브젝트에서 메시지 내용을 가져오는 방법은 “메시지 콘텐츠 가져오기” 에 설명되어 있습니다.

58.3.3. 예제

예 58.5. “감지되지 않은 인터셉터 체인 처리” 인터셉터 체인이 예기치 않은 경우 원래 XML 스트림이 메시지로 다시 배치되도록 하는 데 사용되는 코드를 표시합니다.Shows code used to ensure that the original XML stream is placed back into the message when the interceptor chain is unwound.

예 58.5. 감지되지 않은 인터셉터 체인 처리

@Override
public void handleFault(SoapMessage message)
{
  super.handleFault(message);
  XMLStreamWriter writer = (XMLStreamWriter)message.get(ORIGINAL_XML_WRITER);
  if (writer != null)
  {
    message.setContent(XMLStreamWriter.class, writer);
  }
}
Copy to Clipboard Toggle word wrap

59장. 인터셉터를 사용하도록 끝점 구성

초록

인터셉터는 메시지 교환에 포함될 때 엔드포인트에 추가됩니다. 엔드포인트의 인터셉터 체인은 Apache CXF 런타임의 여러 구성 요소의 인터셉터 체인에서 구성됩니다. 인터셉터는 끝점의 구성 또는 런타임 구성 요소 중 하나의 구성에 지정됩니다. 구성 파일 또는 인터셉터 API를 사용하여 인터셉터를 추가할 수 있습니다.

59.1. 인터셉터를 연결할 위치 결정

59.1.1. 개요

인터셉터 체인을 호스팅하는 여러 런타임 오브젝트가 있습니다. 여기에는 다음이 포함됩니다.

  • 끝점 오브젝트
  • 서비스 오브젝트
  • 프록시 오브젝트
  • 엔드 포인트 또는 프록시를 생성하는 데 사용되는 팩토리 오브젝트
  • 바인딩
  • central 버스 오브젝트

개발자는 이러한 오브젝트 중 하나에 자체 인터셉터를 연결할 수 있습니다. 인터셉터를 연결하는 가장 일반적인 오브젝트는 버스와 개별 끝점입니다. 올바른 오브젝트를 선택하려면 이러한 런타임 개체를 결합하여 끝점을 만드는 방법을 이해해야 합니다. 설계에 따라 각 Cxf 관련 번들에는 자체 cxf 버스가 있습니다. 따라서 인터셉터가 버스에 구성되어 동일한 블루프린트 컨텍스트에서 서비스를 가져오거나 다른 번들로 생성하면 인터셉터가 처리되지 않습니다. 대신 가져온 서비스의 CryostatWS 클라이언트 또는 엔드포인트로 인터셉터를 직접 구성할 수 있습니다.

59.1.2. 끝점 및 프록시

인터셉터를 인터셉터를 배치하는 끝점 또는 프록시에 인터셉터를 연결하는 것이 가장 세분화된 방법입니다. 끝점 또는 프록시에 직접 연결된 모든 인터셉터는 특정 끝점 또는 프록시에만 영향을 미칩니다. 이는 서비스의 특정 구현에 고유한 인터셉터를 연결하는 데 적합합니다. 예를 들어 개발자가 단위를 지표에서 제국으로 변환하는 서비스 인스턴스 중 하나를 노출하려는 경우 인터셉터를 하나의 끝점에 직접 연결할 수 있습니다.

59.1.3. 팩토리

Spring 구성을 사용하여 엔드포인트 또는 프록시를 생성하는 데 사용되는 팩토리에 인터셉터를 연결하면 인터셉터를 엔드포인트 또는 프록시에 직접 연결하는 것과 동일한 효과가 있습니다. 그러나 인터셉터가 팩토리에 연결되면 프로그래밍 방식으로 팩토리에 연결된 인터셉터는 팩토리에서 생성한 모든 끝점 또는 프록시로 전파됩니다.

59.1.4. 바인딩

인터셉터를 바인딩에 연결하면 개발자가 바인딩을 사용하는 모든 끝점에 적용되는 인터셉터 집합을 지정할 수 있습니다. 예를 들어 개발자가 원시 XML 바인딩을 사용하는 모든 끝점을 특수 ID 요소를 포함하도록 강제 적용하려면 XML 바인딩에 요소를 추가하는 인터셉터를 연결할 수 있습니다.

59.1.5. Curther

인터셉터를 연결하는 가장 일반적인 위치는 버스입니다. 인터셉터가 버스에 연결되면 인터셉터가 해당 버스에서 관리하는 모든 엔드포인트로 전파됩니다. 인터셉터를 버스에 연결하는 것은 유사한 인터셉터 세트를 공유하는 여러 끝점을 생성하는 애플리케이션에서 유용합니다.

59.1.6. 첨부 지점 결합

엔드 포인트의 인터셉터 체인의 최종 세트는 나열된 객체에 의해 기여하는 인터셉터 체인의 모호성이므로 나열된 오브젝트 중 일부를 단일 끝점의 구성에 결합할 수 있습니다. 예를 들어 애플리케이션이 검증 토큰을 확인하는 인터셉터가 필요한 여러 끝점을 생성하면 해당 인터셉터가 애플리케이션의 버스에 연결됩니다. 이러한 엔드 포인트 중 하나가 유로를화 된 인터셉터가 필요한 경우 변환 인터셉터는 특정 엔드 포인트에 직접 연결됩니다.

59.2. 구성을 사용하여 인터셉터 추가

59.2.1. 개요

인터셉터를 엔드포인트에 연결하는 가장 쉬운 방법은 구성 파일을 사용하는 것입니다. 엔드포인트에 연결할 각 인터셉터는 표준 Spring 8080을 사용하여 구성됩니다. 그런 다음 Apache CXF 구성 요소를 사용하여 인터셉터 체인에 인터셉터의 8080을 추가할 수 있습니다.

연결된 인터셉터 체인이 있는 각 런타임 구성 요소는 특수 Spring 요소를 사용하여 구성할 수 있습니다. 각 구성 요소의 요소에는 인터셉터 체인을 지정하기 위한 표준 하위 세트가 있습니다. 구성 요소와 연결된 각 인터셉터 체인마다 한 명의 자식이 있습니다. 하위 항목은 인터셉터의 빈이 체인에 추가되도록 나열합니다.

59.2.2. 구성 요소

표 59.1. “인터셉터 체인 구성 요소” 런타임 구성 요소에 인터셉터를 연결하기 위한 네 가지 구성 요소에 대해 설명합니다.

Expand
표 59.1. 인터셉터 체인 구성 요소
element설명

inInterceptors

엔드포인트의 인바운드 인터셉터 체인에 추가하도록 인터셉터를 구성하는 빈 목록이 포함되어 있습니다.

outInterceptors

엔드포인트의 아웃바운드 인터셉터 체인에 추가할 인터셉터를 구성하는 빈 목록을 포함합니다.

inFaultInterceptors

엔드포인트의 인바운드 오류 처리 인터셉터 체인에 추가하도록 인터셉터를 구성하는 빈 목록이 포함되어 있습니다.

outFaultInterceptors

엔드포인트의 아웃바운드 오류 처리 인터셉터 체인에 추가하도록 인터셉터를 구성하는 빈 목록을 포함합니다.

모든 인터셉터 체인 구성 요소는 list 하위 요소를 사용합니다. list 요소에는 체인에 연결된 각 인터셉터에 대해 하나의 자식이 있습니다. 인터셉터는 인터셉터를 직접 구성하거나 인터셉터를 구성하는ans 요소를 참조하는 ref 요소를 사용하여 인터셉터를 지정할 수 있습니다.

59.2.3. 예

예 59.1. “버스에 인터셉터 연결” 버스의 인바운드 인터셉터 체인에 인터셉터를 연결하는 구성을 보여줍니다.

예 59.1. 버스에 인터셉터 연결

&lt;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:http="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="
       http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
       http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
  ...
  &lt;bean id="GZIPStream" class="demo.stream.interceptor.StreamInterceptor"/&gt;

  &lt;cxf:bus&gt;
    *&lt;cxf:inInterceptors&gt;
      &lt;list&gt;
        &lt;ref bean="GZIPStream"/&gt;
      &lt;/list&gt;
    &lt;/cxf:inInterceptors&gt;*
  &lt;/cxf:bus&gt;
&lt;/beans&gt;
Copy to Clipboard Toggle word wrap

예 59.2. “Cryostat-WS 서비스 공급자에 인터셉터 연결” 에 인터셉터를 연결하기 위한 구성을 표시하여 Cryostat-WS 서비스의 아웃 바운드 인터셉터 체인에 연결합니다.

예 59.2. Cryostat-WS 서비스 공급자에 인터셉터 연결

&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:wsa="http://cxf.apache.org/ws/addressing"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;

  &lt;jaxws:endpoint ...&gt;
    *&lt;jaxws:outInterceptors&gt;
      &lt;list&gt;
        &lt;bean id="GZIPStream" class="demo.stream.interceptor.StreamInterceptor" /&gt;
      &lt;/list&gt;
    &lt;/jaxws:outInterceptors&gt;*
  &lt;/jaxws:endpoint&gt;
&lt;/beans&gt;
Copy to Clipboard Toggle word wrap

59.2.4. 더 많은 정보

Spring 구성을 사용하여 끝점을 구성하는 방법에 대한 자세한 내용은 IV 부. 웹 서비스 엔드 포인트 구성 을 참조하십시오.

59.3. 프로그래밍 방식으로 인터셉터 추가

59.3.1. 인터셉터 추가 방법

인터셉터는 다음 두 가지 방법 중 하나를 사용하여 프로그래밍 방식으로 엔드포인트에 연결할 수 있습니다.

  • InterceptorProvider API
  • Java 주석

InterceptorProvider API를 사용하면 개발자가 인터셉터 체인이 있는 런타임 구성 요소에 인터셉터를 연결할 수 있지만 기본 Apache CXF 클래스를 사용해야 합니다. Java 주석은 서비스 인터페이스 또는 서비스 구현에만 추가할 수 있지만 개발자가 Cryostat-WS API 또는 Cryostat-RS API 내에 유지할 수 있습니다.

59.3.2. 인터셉터 공급자 API 사용

59.3.2.1. 개요

인터셉터는 인터셉터 공급자 인터페이스 에 표시된 InterceptorProvider 인터페이스를 구현하는 모든 구성 요소에 등록할 수 있습니다.

인터셉터 공급자 인터페이스

package org.apache.cxf.interceptor;

import java.util.List;

public interface InterceptorProvider
{
    List<Interceptor<? extends Message>> getInInterceptors();

    List<Interceptor<? extends Message>> getOutInterceptors();

    List<Interceptor<? extends Message>> getInFaultInterceptors();

    List<Interceptor<? extends Message>> getOutFaultInterceptors();
}
Copy to Clipboard Toggle word wrap

인터페이스의 네 가지 방법을 사용하면 각 끝점의 인터셉터 체인을 Java List 오브젝트로 검색할 수 있습니다. 개발자는 Java List 개체에서 제공하는 방법을 사용하여 모든 체인에 인터셉터를 추가하고 제거할 수 있습니다.

59.3.2.2. 절차

InterceptorProvider API를 사용하여 런타임 구성 요소의 인터셉터 체인에 인터셉터를 연결하려면 다음을 수행해야 합니다.

  1. 인터셉터가 연결되어 있는 체인을 사용하여 런타임 구성 요소에 대한 액세스 권한을 얻습니다.

    개발자는 Apache CXF 특정 API를 사용하여 표준 Java 애플리케이션 코드에서 런타임 구성 요소에 액세스해야 합니다. 런타임 구성 요소는 일반적으로 Cryostat-WS 또는 Cryostat-RS 아티팩트를 기본 Apache CXF 오브젝트로 캐스팅하여 액세스할 수 있습니다.

  2. 인터셉터의 인스턴스를 생성합니다.
  3. 적절한 get 방법을 사용하여 원하는 인터셉터 체인을 검색합니다.
  4. List 오브젝트의 add() 메서드를 사용하여 인터셉터를 인터셉터 체인에 연결합니다.

    이 단계는 일반적으로 인터셉터 체인을 검색하는 것과 결합됩니다.

59.3.2.3. 소비자에 인터셉터 연결

프로그래밍 방식으로 소비자에 인터셉터 연결 Cryostat-WS 소비자의 인바운드 인터셉터 체인에 인터셉터를 연결하는 코드를 표시합니다.

프로그래밍 방식으로 소비자에 인터셉터 연결

package com.fusesource.demo;

import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.cxf.endpoint.Client;

public class Client
{
  public static void main(String args[])
  {
    QName serviceName = new QName("http://demo.eric.org", "stockQuoteReporter");
    Service s = Service.create(serviceName);

    QName portName = new QName("http://demo.eric.org", "stockQuoteReporterPort");
    s.addPort(portName, "http://schemas.xmlsoap.org/soap/", "http://localhost:9000/EricStockQuote");

    quoteReporter proxy = s.getPort(portName, quoteReporter.class);

    Client cxfClient = (Client) proxy;

    ValidateInterceptor validInterceptor = new ValidateInterceptor();
    cxfClient.getInInterceptor().add(validInterceptor);

    ...
  }
}
Copy to Clipboard Toggle word wrap

프로그래밍 방식으로 소비자에 인터셉터 연결 의 코드는 다음을 수행합니다.

소비자에 대한 Cryostat-WS Service 오브젝트를 만듭니다.

소비자의 대상 주소를 제공하는 Service 오브젝트에 포트를 추가합니다.

서비스 공급자에서 메서드를 호출하는 데 사용되는 프록시를 생성합니다.

프록시를 org.apache.cxf.endpoint.Client 유형으로 캐스팅합니다.

인터셉터의 인스턴스를 생성합니다.

인터셉터를 인바운드 인터셉터 체인에 연결합니다.

59.3.2.4. 서비스 공급자에 인터셉터 연결

프로그래밍 방식으로 서비스 공급자에 인터셉터 연결 서비스 공급자의 아웃바운드 인터셉터 체인에 인터셉터를 연결하는 코드를 표시합니다.

프로그래밍 방식으로 서비스 공급자에 인터셉터 연결

package com.fusesource.demo;
import java.util.*;

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.frontend.EndpointImpl;

public class stockQuoteReporter implements quoteReporter
{
  ...
  public stockQuoteReporter()
  {
    ServerFactoryBean sfb = new ServerFactoryBean();
    Server server = sfb.create();
    EndpointImpl endpt = server.getEndpoint();

    AuthTokenInterceptor authInterceptor = new AuthTokenInterceptor();

    endpt.getOutInterceptor().add(authInterceptor);
  }
}
Copy to Clipboard Toggle word wrap

프로그래밍 방식으로 서비스 공급자에 인터셉터 연결 의 코드는 다음을 수행합니다.

기본 Apache CXF 개체에 대한 액세스를 제공하는 ServerFactoryBean 오브젝트를 생성합니다.

Apache CXF가 엔드포인트를 나타내는 데 사용하는 Server 개체를 가져옵니다.

서비스 공급자에 대한 Apache CXF EndpointImpl 개체를 가져옵니다.

인터셉터의 인스턴스를 생성합니다.

인터셉터를 엔드포인트에 연결합니다. 아웃바운드 인터셉터 체인입니다.

59.3.2.5. 버스에 인터셉터 연결

버스에 인터셉터 연결 버스의 인바운드 인터셉터 체인에 인터셉터를 연결하는 코드를 표시합니다.

버스에 인터셉터 연결

import org.apache.cxf.BusFactory;
org.apache.cxf.Bus;

...

Bus bus = BusFactory.getDefaultBus();

WatchInterceptor watchInterceptor = new WatchInterceptor();

bus..getInInterceptor().add(watchInterceptor);

...
Copy to Clipboard Toggle word wrap

버스에 인터셉터 연결 의 코드는 다음을 수행합니다.

런타임 인스턴스의 기본 버스를 가져옵니다.

인터셉터의 인스턴스를 생성합니다.

인터셉터를 인바운드 인터셉터 체인에 연결합니다.

WatchInterceptor 는 런타임 인스턴스에서 생성한 모든 끝점의 인바운드 인터셉터 체인에 연결됩니다.

59.3.3. Java 주석 사용

59.3.3.1. 개요

Apache CXF는 개발자가 엔드포인트에서 사용하는 인터셉터 체인을 지정할 수 있는 4가지 Java 주석을 제공합니다. 인터셉터를 엔드포인트에 연결하는 다른 수단과 달리 주석이 애플리케이션 수준 아티팩트에 연결됩니다. 사용되는 아티팩트는 주석의 효과 범위를 결정합니다.

59.3.3.2. 주석을 배치할 위치

주석은 다음 아티팩트에 배치할 수 있습니다.

  • 끝점을 정의하는 서비스 끝점 인터페이스(SEI)

    주석이 SEI에 배치되면 인터페이스를 구현하는 모든 서비스 공급자와 SEI를 사용하여 프록시를 생성하는 모든 소비자에 영향을 받습니다.

  • 서비스 구현 클래스

    주석이 구현 클래스에 배치되면 구현 클래스를 사용하는 모든 서비스 공급자에 영향을 받습니다.

59.3.3.3. 주석

주석은 모두 org.apache.cxf.interceptor 패키지에 있으며 표 59.2. “인터셉터 체인 주석” 에 설명되어 있습니다.

Expand
표 59.2. 인터셉터 체인 주석
주석설명

InInterceptors

인바운드 인터셉터 체인의 인터셉터를 지정합니다.

OutInterceptors

아웃바운드 인터셉터 체인의 인터셉터를 지정합니다.

InFaultInterceptors

인바운드 오류 인터셉터 체인의 인터셉터를 지정합니다.

OutFaultInterceptors

아웃바운드 오류 인터셉터 체인의 인터셉터를 지정합니다.

59.3.3.4. 인터셉터 나열

인터셉터 목록은 체인 주석에 인터셉터를 나열하는 구문 에 표시된 구문을 사용하여 정규화된 클래스 이름 목록으로 지정됩니다.

체인 주석에 인터셉터를 나열하는 구문

interceptors={"interceptor1", "interceptor2", ..., "interceptorN"}
Copy to Clipboard Toggle word wrap

59.3.3.5. 예제

서비스 구현에 인터셉터 연결 SayHiImpl 에서 제공하는 논리를 사용하는 엔드포인트의 인바운드 인터셉터 체인에 두 인터셉터 체인을 연결하는 주석을 표시합니다.

서비스 구현에 인터셉터 연결

import org.apache.cxf.interceptor.InInterceptors;

@InInterceptors(interceptors={"com.sayhi.interceptors.FirstLast", "com.sayhi.interceptors.LogName"})
public class SayHiImpl implements SayHi
{
  ...
}
Copy to Clipboard Toggle word wrap

60장. Fly에서 인터셉터 체인 조작

초록

인터셉터는 메시지 처리 논리의 일부로 끝점의 인터셉터 체인을 재구성할 수 있습니다. 새 인터셉터를 추가하고, 인터셉터를 제거하고, 인터셉터를 다시 정렬하며, 인터셉터 체인을 일시 중단할 수도 있습니다. 모든 on-the-fly 조작은 호출별로 수행되므로 끝점이 메시지 교환에 참여할 때마다 원래 체인이 사용됩니다.

60.1. 개요

인터셉터 체인은 생성을 분리한 메시지 교환만 있습니다. 각 메시지에는 처리를 담당하는 인터셉터 체인에 대한 참조가 포함되어 있습니다. 개발자는 이 참조를 사용하여 메시지의 인터셉터 체인을 변경할 수 있습니다. 체인은 각 교환기이므로 메시지의 인터셉터 체인에 대한 모든 변경 사항은 다른 메시지 교환에 영향을 미치지 않습니다.

60.2. 체인 라이프 사이클

인터셉터 체인과 체인의 인터셉터는 할당별로 인스턴스화됩니다. 메시지 교환에 참여하도록 엔드포인트를 호출하면 필요한 인터셉터 체인이 인터셉터 인스턴스와 함께 인스턴스화됩니다. 인터셉터 체인 생성을 초래한 메시지 교환이 완료되면 체인 및 인터셉터 인스턴스가 삭제됩니다.

즉, 인터셉터 체인 또는 인터셉터의 필드에 대한 모든 변경 사항은 메시지 교환을 통해 유지되지 않습니다. 따라서 인터셉터를 활성 체인에 배치하는 경우 활성 체인만 적용됩니다. 향후 메시지 교환은 엔드 포인트의 구성에 의해 결정된 대로 초기 상태에서 생성됩니다. 또한 개발자가 향후 메시지 처리를 변경하는 인터셉터에 플래그를 설정할 수 없음을 의미합니다.

인터셉터가 정보를 향후 인스턴스로 전달해야 하는 경우 메시지 컨텍스트에서 속성을 설정할 수 있습니다. 컨텍스트는 메시지 교환을 통해 유지됩니다.

60.3. 인터셉터 체인 가져오기

메시지의 인터셉터 체인을 변경하는 첫 번째 단계는 인터셉터 체인을 가져오는 것입니다. 이 작업은 예 60.1. “인터셉터 체인을 얻는 방법” 에 표시된 Message.getInterceptor Cryostat() 메서드를 사용하여 수행됩니다. 인터셉터 체인은 org.apache.cxf.interceptor.Interceptor Cryostat 오브젝트로 반환됩니다.

예 60.1. 인터셉터 체인을 얻는 방법

InterceptorChaingetInterceptorChain

60.4. 인터셉터 추가

Interceptor Cryostat 오브젝트에는 인터셉터 체인에 인터셉터를 추가하기 위한 예 60.2. “인터셉터 체인에 인터셉터를 추가하는 방법” 에 표시된 두 가지 방법이 있습니다. 하나는 하나의 인터셉터를 추가할 수 있고 다른 하나는 여러 인터셉터를 추가할 수 있습니다.

예 60.2. 인터셉터 체인에 인터셉터를 추가하는 방법

추가인터셉터<? extends Message>iaddCollection<Interceptor<? extends Message>>i

예 60.3. “인터셉터 체인 on-the-fly에 인터셉터 추가” 메시지의 인터셉터 체인에 단일 인터셉터를 추가하는 코드를 표시합니다.

예 60.3. 인터셉터 체인 on-the-fly에 인터셉터 추가

void handleMessage(Message message)
{
  ...
  AddledIntereptor addled = new AddledIntereptor();
  InterceptorChain chain = message.getInterceptorChain();
  chain.add(addled);
  ...
}
Copy to Clipboard Toggle word wrap

예 60.3. “인터셉터 체인 on-the-fly에 인터셉터 추가” 의 코드는 다음을 수행합니다.

체인에 추가할 인터셉터의 복사본을 인스턴스화합니다.

중요

체인에 추가되는 인터셉터는 현재 인터셉터 또는 현재 인터셉터보다 후자의 단계에 있어야 합니다.

현재 메시지의 인터셉터 체인을 가져옵니다.

새 인터셉터를 체인에 추가합니다.

60.5. 인터셉터 제거

Interceptor Cryostat 오브젝트에는 인터셉터 체인에서 인터셉터를 제거하기 위한 예 60.4. “인터셉터 체인에서 인터셉터를 제거하는 방법” 에 표시된 하나의 방법이 있습니다.

예 60.4. 인터셉터 체인에서 인터셉터를 제거하는 방법

Interceptor 제거<? extends Message&gt;i

예 60.5. “인터셉터 체인 on-the-fly에서 인터셉터 제거” 메시지의 인터셉터 체인에서 인터셉터를 제거하는 코드를 표시합니다.

예 60.5. 인터셉터 체인 on-the-fly에서 인터셉터 제거

void handleMessage(Message message)
{
  ...
  Iterator<Interceptor<? extends Message>> iterator =
            message.getInterceptorChain().iterator();
  Interceptor<?> removeInterceptor =  null;
  for (; iterator.hasNext(); ) {
    Interceptor<?> interceptor = iterator.next();
    if (interceptor.getClass().getName().equals("InterceptorClassName")) {
      removeInterceptor = interceptor;
      break;
    }
  }

  if (removeInterceptor !=  null) {
    log.debug("Removing interceptor {}",removeInterceptor.getClass().getName());
    message.getInterceptorChain().remove(removeInterceptor);
  }
  ...
}
Copy to Clipboard Toggle word wrap

여기서 InterceptorClassName 은 체인에서 제거하려는 인터셉터의 클래스 이름입니다.

61장. Cryostat-RS 2.0 필터 및 인터셉터

초록

Cryostat-RS 2.0은 REST 호출을 위해 처리 파이프라인에 필터 및 인터셉터를 설치하기 위한 표준 API 및 의미 체계를 정의합니다. 필터 및 인터셉터는 일반적으로 로깅, 인증, 권한 부여, 메시지 압축, 메시지 암호화 등과 같은 기능을 제공하는 데 사용됩니다.

61.1. Cryostat-RS 필터 및 인터셉터 소개

61.1.1. 개요

이 섹션에서는 Cryostat-RS 필터 및 인터셉터의 처리 파이프라인에 대한 개요를 제공하여 필터 체인 또는 인터셉터 체인을 설치할 수 있는 확장 지점을 강조 표시합니다.

61.1.2. 필터

Cryostat-RS 2.0 필터 는 CXF 클라이언트 또는 서버를 통과하는 모든 Cryostat-RS 메시지에 대한 개발자 액세스 권한을 제공하는 플러그인 유형입니다. 필터는 HTTP 헤더, 쿼리 매개변수, 미디어 유형 및 기타 메타데이터와 관련된 메타데이터를 처리하는 데 적합합니다. 필터에는 메시지 호출을 중단할 수 있는 기능이 있습니다(예: 보안 플러그인의 경우 사용).

원하는 경우 각 확장 지점에 여러 필터를 설치할 수 있습니다. 이 경우 필터가 체인에서 실행됩니다(실행 순서는 정의되지 않지만 설치된 각 필터에 대한 우선 순위 값을 지정하지 않는 한).

61.1.3. 인터셉터

Cryostat-RS 2.0 인터셉터 는 읽기 또는 쓰기로 메시지 본문에 대한 개발자 액세스 권한을 제공하는 플러그인 유형입니다. 인터셉터는 MessageBody Cryostat.readFrom 메서드 호출( reader interceptors용) 또는 MessageBodyWriter.writeTo 메서드 호출(기사 인터셉터용)을 중심으로 래핑됩니다.

원하는 경우 각 확장 지점에 여러 인터셉터를 설치할 수 있습니다. 이 경우 인터셉터가 체인에서 실행됩니다(실행 순서는 정의되지 않지만 설치된 각 인터셉터에 대한 우선 순위 값을 지정하지 않는 한).

61.1.4. 서버 처리 파이프라인

그림 61.1. “Server-Side 필터 및 인터셉터 확장 지점” 서버 측에 설치된 interceptors 및 interceptors에 대한 처리 파이프라인의 개요를 보여줍니다.

그림 61.1. Server-Side 필터 및 인터셉터 확장 지점

jaxrs20filters 01

61.1.5. 서버 확장 지점

서버 처리 파이프라인에서는 다음 확장 지점에 필터(또는 인터셉터)를 추가할 수 있습니다.

  1. PreMatchContainerRequest 필터
  2. ContainerRequest 필터
  3. ReadInterceptor
  4. ContainerResponse 필터
  5. WriteInterceptor

일치하는 리소스가 발생하기 전에 PreMatchContainerRequest 확장 지점에 도달하므로 현재 컨텍스트 메타데이터 중 일부를 사용할 수 없습니다.

61.1.6. 클라이언트 처리 파이프라인

그림 61.2. “클라이언트-Side 필터 및 인터셉터 확장 지점” 클라이언트 측에 설치된 interceptors 및 interceptors에 대한 처리 파이프라인의 개요를 보여줍니다.

그림 61.2. 클라이언트-Side 필터 및 인터셉터 확장 지점

jaxrs20filters 02

61.1.7. 클라이언트 확장 지점

클라이언트 처리 파이프라인에서는 다음 확장 지점에 필터(또는 인터셉터)를 추가할 수 있습니다.

  1. ClientRequest 필터
  2. WriteInterceptor
  3. ClientResponse 필터
  4. ReadInterceptor

61.1.8. 필터 및 인터셉터 순서

동일한 확장 지점에 여러 필터 또는 인터셉터를 설치하는 경우 필터의 실행 순서는 Java 소스의 @Priority 주석을 사용하여 할당된 우선 순위에 따라 다릅니다. 우선순위는 정수 값으로 표시됩니다. 일반적으로 우선 순위가 높은 숫자가 높은 필터는 서버 측의 리소스 메서드 호출에 더 가깝게 배치되지만 우선 순위가 낮은 필터는 클라이언트 호출에 더 근접하게 배치됩니다. 즉, 요청 메시지에서 작동하는 필터 및 인터셉터는 우선 순위 번호의 오름차순 으로 실행됩니다. 응답 메시지에서 작동하는 필터 및 인터셉터는 우선순위 번호의 내림차순으로 실행됩니다.

61.1.9. 클래스 필터링

사용자 정의 REST 메시지 필터를 생성하기 위해 다음 Java 인터페이스를 구현할 수 있습니다.

61.1.10. 인터셉터 클래스

사용자 정의 REST 메시지 인터셉터를 생성하기 위해 다음 Java 인터페이스를 구현할 수 있습니다.

61.2. 컨테이너 요청 필터

61.2.1. 개요

이 섹션에서는 서버( 컨테이너) 측에서 들어오는 요청 메시지를 가로채는 데 사용되는 컨테이너 요청 필터 를 구현하고 등록하는 방법을 설명합니다. 컨테이너 요청 필터는 종종 서버 측의 헤더를 처리하는 데 사용되며 모든 종류의 일반 요청 처리(즉, 라는 특정 리소스 메서드와 독립적인 처리)에 사용할 수 있습니다.

또한 컨테이너 요청 필터는 두 개의 고유한 확장 지점( PreMatchContainerRequest (리소스 일치 단계 전) 및 ContainerRequest (리소스 일치 단계 이후)에 설치할 수 있기 때문에 특별한 경우입니다.

61.2.2. ContainerRequestFilter 인터페이스

javax.ws.rs.container.ContainerRequestFilter 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.container;

import java.io.IOException;

public interface ContainerRequestFilter {
    public void filter(ContainerRequestContext requestContext) throws IOException;
}
Copy to Clipboard Toggle word wrap

ContainerRequestFilter 인터페이스를 구현하면 서버 측에서 다음 확장 포인트 중 하나에 대한 필터를 생성할 수 있습니다.

  • PreMatchContainerRequest
  • ContainerRequest

61.2.3. ContainerRequestContext 인터페이스

ContainerRequestFilter필터 메서드는 들어오는 요청 메시지 및 관련 메타데이터에 액세스하는 데 사용할 수 있는 javax.ws.rs.container.ContainerRequestContext 유형의 단일 인수를 수신합니다. ContainerRequestContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.container;

import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;


public interface ContainerRequestContext {

    public Object getProperty(String name);

    public Collection getPropertyNames();

    public void setProperty(String name, Object object);

    public void removeProperty(String name);

    public UriInfo getUriInfo();

    public void setRequestUri(URI requestUri);

    public void setRequestUri(URI baseUri, URI requestUri);

    public Request getRequest();

    public String getMethod();

    public void setMethod(String method);

    public MultivaluedMap getHeaders();

    public String getHeaderString(String name);

    public Date getDate();

    public Locale getLanguage();

    public int getLength();

    public MediaType getMediaType();

    public List getAcceptableMediaTypes();

    public List getAcceptableLanguages();

    public Map getCookies();

    public boolean hasEntity();

    public InputStream getEntityStream();

    public void setEntityStream(InputStream input);

    public SecurityContext getSecurityContext();

    public void setSecurityContext(SecurityContext context);

    public void abortWith(Response response);
}
Copy to Clipboard Toggle word wrap

61.2.4. PreMatchContainerRequest 필터의 샘플 구현

PreMatchContainerRequest 확장 지점(즉, 리소스 일치 전에 필터가 실행되는 경우)에 대한 컨테이너 요청 필터를 구현하려면 ContainerRequestFilter 인터페이스를 구현하는 클래스를 정의합니다. @PreMatching 주석으로 클래스에 주석을 답니다( PreMatchContainerRequest 확장 지점을 선택).

예를 들어 다음 코드는 우선순위가 20인 PreMatchContainerRequest 확장 지점에 설치된 간단한 컨테이너 요청 필터의 예를 보여줍니다.

// Java
package org.jboss.fuse.example;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.annotation.Priority;
import javax.ws.rs.ext.Provider;

@PreMatching
@Priority(value = 20)
@Provider
public class SamplePreMatchContainerRequestFilter implements
  ContainerRequestFilter {

  public SamplePreMatchContainerRequestFilter() {
    System.out.println("SamplePreMatchContainerRequestFilter starting up");
  }

  @Override
  public void filter(ContainerRequestContext requestContext) {
    System.out.println("SamplePreMatchContainerRequestFilter.filter() invoked");
  }
}
Copy to Clipboard Toggle word wrap

61.2.5. ContainerRequest 필터의 구현 예

ContainerRequest 확장 지점(즉, 리소스 일치 필터가 실행되는 경우)에 대한 컨테이너 요청 필터를 구현하려면 @PreMatching 주석 없이 ContainerRequestFilter 인터페이스를 구현하는 클래스를 정의합니다.

예를 들어 다음 코드는 우선 순위가 30인 ContainerRequest 확장 지점에 설치되는 간단한 컨테이너 요청 필터의 예를 보여줍니다.

// Java
package org.jboss.fuse.example;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;
import javax.annotation.Priority;

@Provider
@Priority(value = 30)
public class SampleContainerRequestFilter implements ContainerRequestFilter {

  public SampleContainerRequestFilter() {
    System.out.println("SampleContainerRequestFilter starting up");
  }

  @Override
  public void filter(ContainerRequestContext requestContext) {
    System.out.println("SampleContainerRequestFilter.filter() invoked");
  }
}
Copy to Clipboard Toggle word wrap

61.2.6. ResourceInfo 삽입

ContainerRequest 확장 지점(즉, 일치하는 리소스가 발생한 ) ResourceInfo 클래스를 삽입하여 일치하는 리소스 클래스 및 리소스 메서드에 액세스할 수 있습니다. 예를 들어 다음 코드는 ResourceInfo 클래스를 ContainerRequestFilter 클래스의 필드로 삽입하는 방법을 보여줍니다.

// Java
package org.jboss.fuse.example;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.ext.Provider;
import javax.annotation.Priority;
import javax.ws.rs.core.Context;

@Provider
@Priority(value = 30)
public class SampleContainerRequestFilter implements ContainerRequestFilter {

  @Context
  private ResourceInfo resinfo;

  public SampleContainerRequestFilter() {
    ...
  }

  @Override
  public void filter(ContainerRequestContext requestContext) {
    String resourceClass = resinfo.getResourceClass().getName();
    String methodName    = resinfo.getResourceMethod().getName();
    System.out.println("REST invocation bound to resource class: " + resourceClass);
    System.out.println("REST invocation bound to resource method: " + methodName);
  }
}
Copy to Clipboard Toggle word wrap

61.2.7. 호출 중단

컨테이너 요청 필터의 적절한 구현을 생성하여 서버 측 호출을 중단할 수 있습니다. 일반적으로 이 기능은 서버 측에서 보안 기능을 구현하는 데 유용합니다. 예를 들어 인증 기능 또는 권한 부여 기능을 구현하는 데 유용합니다. 들어오는 요청이 성공적으로 인증되지 않으면 컨테이너 요청 필터 내에서 호출을 중단할 수 있습니다.

예를 들어 다음 사전 일치 기능은 URI의 쿼리 매개변수에서 사용자 이름과 암호를 추출하고 인증 방법을 호출하여 사용자 이름 및 암호 자격 증명을 확인합니다. 인증에 실패하면 ContainerRequestContext 오브젝트에서 abortWith 를 호출하여 호출이 중단되고 클라이언트에 반환되는 오류 응답을 전달합니다.

// Java
package org.jboss.fuse.example;

import javax.annotation.Priority;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Provider;

@PreMatching
@Priority(value = 20)
@Provider
public class SampleAuthenticationRequestFilter implements
  ContainerRequestFilter {

  public SampleAuthenticationRequestFilter() {
    System.out.println("SampleAuthenticationRequestFilter starting up");
  }

  @Override
  public void filter(ContainerRequestContext requestContext) {
    ResponseBuilder responseBuilder = null;
    Response response = null;

    String userName = requestContext.getUriInfo().getQueryParameters().getFirst("UserName");
    String password = requestContext.getUriInfo().getQueryParameters().getFirst("Password");
    if (authenticate(userName, password) == false) {
      responseBuilder = Response.serverError();
      response = responseBuilder.status(Status.BAD_REQUEST).build();
      requestContext.abortWith(response);
    }
  }

  public boolean authenticate(String userName, String password) {
    // Perform authentication of 'user'
    ...
  }
}
Copy to Clipboard Toggle word wrap

61.2.8. 서버 요청 필터 바인딩

서버 요청 필터(즉, Apache CXF 런타임에 설치)를 바인딩 하려면 다음 단계를 수행합니다.

  1. 다음 코드 조각에 표시된 대로 컨테이너 요청 필터 클래스에 @Provider 주석을 추가합니다.

    // Java
    package org.jboss.fuse.example;
    
    import javax.ws.rs.container.ContainerRequestContext;
    import javax.ws.rs.container.ContainerRequestFilter;
    import javax.ws.rs.ext.Provider;
    import javax.annotation.Priority;
    
    @Provider
    @Priority(value = 30)
    public class SampleContainerRequestFilter implements ContainerRequestFilter {
      ...
    }
    Copy to Clipboard Toggle word wrap

    컨테이너 요청 필터 구현이 Apache CXF 런타임에 로드되면 REST 구현에서 로드된 클래스를 자동으로 검색하여 @Provider 주석( 검사 단계)으로 표시된 클래스를 검색합니다.

  2. XML에서 Cryostat-RS 서버 끝점을 정의할 때(예: 18.1절. “Cryostat-RS 서버 끝점 구성”참조) jaxrs:providers 요소의 공급자 목록에 서버 요청 필터를 추가합니다.

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
        xmlns:cxf="http://cxf.apache.org/blueprint/core"
        ...
    >
        ...
        <jaxrs:server id="customerService" address="/customers">
          ...
          <jaxrs:providers>
            <ref bean="filterProvider" />
          </jaxrs:providers>
          <bean id="filterProvider" class="org.jboss.fuse.example.SampleContainerRequestFilter"/>
    
        </jaxrs:server>
    
    </blueprint>
    Copy to Clipboard Toggle word wrap
    참고

    이 단계는 Apache CXF의 비표준 요구 사항입니다. Cryostat-RS 표준에 따라 @Provider 주석은 필터를 바인딩하는 데 필요한 모든 주석이어야 합니다. 그러나 실제로 표준 접근 방식은 다소 유연하지 않으며 많은 라이브러리가 대규모 프로젝트에 포함될 때 충돌하는 공급자로 이어질 수 있습니다.

61.3. 컨테이너 응답 필터

61.3.1. 개요

이 섹션에서는 서버 측에서 발신 응답 메시지를 가로채는 데 사용되는 컨테이너 응답 필터 를 구현하고 등록하는 방법을 설명합니다. 컨테이너 응답 필터를 사용하여 응답 메시지에서 헤더를 자동으로 채울 수 있으며 일반적으로 모든 종류의 일반 응답 처리에 사용할 수 있습니다.

61.3.2. ContainerResponseFilter 인터페이스

javax.ws.rs.container.ContainerResponseFilter 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.container;

import java.io.IOException;

public interface ContainerResponseFilter {
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
            throws IOException;
}
Copy to Clipboard Toggle word wrap

ContainerResponseFilter 를 구현하면 서버 측에서 ContainerResponse 확장 지점에 대한 필터를 생성하여 호출이 실행된 응답 메시지를 필터링할 수 있습니다.

참고

컨테이너 응답 필터를 사용하면 요청 메시지( requestContext 인수를 통해) 및 응답 메시지( responseContext 메시지를 통해)에 액세스할 수 있지만 이 단계에서만 응답을 수정할 수 있습니다.

61.3.3. ContainerResponseContext 인터페이스

ContainerResponseFilter필터 방법은 두 가지 인수를 수신합니다. javax.ws.rs.container.ContainerRequestContext 유형 인수와 javax.ws.rs.container.ContainerResponseContext. 이 인수는 발신 응답 메시지 및 관련 메타데이터에 액세스하는 데 사용할 수 있습니다. “ContainerRequestContext 인터페이스”

ContainerResponseContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.container;

import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyWriter;

public interface ContainerResponseContext {

    public int getStatus();

    public void setStatus(int code);

    public Response.StatusType getStatusInfo();

    public void setStatusInfo(Response.StatusType statusInfo);

    public MultivaluedMap<String, Object> getHeaders();

    public abstract MultivaluedMap<String, String> getStringHeaders();

    public String getHeaderString(String name);

    public Set<String> getAllowedMethods();

    public Date getDate();

    public Locale getLanguage();

    public int getLength();

    public MediaType getMediaType();

    public Map<String, NewCookie> getCookies();

    public EntityTag getEntityTag();

    public Date getLastModified();

    public URI getLocation();

    public Set<Link> getLinks();

    boolean hasLink(String relation);

    public Link getLink(String relation);

    public Link.Builder getLinkBuilder(String relation);

    public boolean hasEntity();

    public Object getEntity();

    public Class<?> getEntityClass();

    public Type getEntityType();

    public void setEntity(final Object entity);

    public void setEntity(
            final Object entity,
            final Annotation[] annotations,
            final MediaType mediaType);

    public Annotation[] getEntityAnnotations();

    public OutputStream getEntityStream();

    public void setEntityStream(OutputStream outputStream);
}
Copy to Clipboard Toggle word wrap

61.3.4. 샘플 구현

ContainerResponse 확장 지점(즉, 서버 측에서 호출이 실행된 후 필터가 실행되는 경우)에 대한 컨테이너 응답 필터를 구현하려면 ContainerResponseFilter 인터페이스를 구현하는 클래스를 정의합니다.

예를 들어 다음 코드는 우선 순위가 10인 ContainerResponse 확장 지점에 설치되는 간단한 컨테이너 응답 필터의 예를 보여줍니다.

// Java
package org.jboss.fuse.example;

import javax.annotation.Priority;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
@Priority(value = 10)
public class SampleContainerResponseFilter implements ContainerResponseFilter {

  public SampleContainerResponseFilter() {
    System.out.println("SampleContainerResponseFilter starting up");
  }

  @Override
  public void filter(
      ContainerRequestContext requestContext,
      ContainerResponseContext responseContext
  )
  {
    // This filter replaces the response message body with a fixed string
    if (responseContext.hasEntity()) {
      responseContext.setEntity("New message body!");
    }
  }
}
Copy to Clipboard Toggle word wrap

61.3.5. 서버 응답 필터 바인딩

서버 응답 필터(즉, Apache CXF 런타임에 설치)를 바인딩 하려면 다음 단계를 수행합니다.

  1. 다음 코드 조각에 표시된 대로 컨테이너 응답 필터 클래스에 @Provider 주석을 추가합니다.

    // Java
    package org.jboss.fuse.example;
    
    import javax.annotation.Priority;
    import javax.ws.rs.container.ContainerRequestContext;
    import javax.ws.rs.container.ContainerResponseContext;
    import javax.ws.rs.container.ContainerResponseFilter;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    @Priority(value = 10)
    public class SampleContainerResponseFilter implements ContainerResponseFilter {
      ...
    }
    Copy to Clipboard Toggle word wrap

    컨테이너 응답 필터 구현이 Apache CXF 런타임에 로드되면 REST 구현에서 로드된 클래스를 자동으로 검색하여 @Provider 주석( 검사 단계)으로 표시된 클래스를 검색합니다.

  2. XML에서 Cryostat-RS 서버 끝점을 정의할 때(예: 18.1절. “Cryostat-RS 서버 끝점 구성”참조) jaxrs:providers 요소의 공급자 목록에 서버 응답 필터를 추가합니다.

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
        xmlns:cxf="http://cxf.apache.org/blueprint/core"
        ...
    >
        ...
        <jaxrs:server id="customerService" address="/customers">
          ...
          <jaxrs:providers>
            <ref bean="filterProvider" />
          </jaxrs:providers>
          <bean id="filterProvider" class="org.jboss.fuse.example.SampleContainerResponseFilter"/>
    
        </jaxrs:server>
    
    </blueprint>
    Copy to Clipboard Toggle word wrap
    참고

    이 단계는 Apache CXF의 비표준 요구 사항입니다. Cryostat-RS 표준에 따라 @Provider 주석은 필터를 바인딩하는 데 필요한 모든 주석이어야 합니다. 그러나 실제로 표준 접근 방식은 다소 유연하지 않으며 많은 라이브러리가 대규모 프로젝트에 포함될 때 충돌하는 공급자로 이어질 수 있습니다.

61.4. 클라이언트 요청 필터

61.4.1. 개요

이 섹션에서는 클라이언트 측에서 발신 요청 메시지를 가로채는 데 사용되는 클라이언트 요청 필터 를 구현하고 등록하는 방법을 설명합니다. 클라이언트 요청 필터는 헤더를 처리하는 데 자주 사용되며 모든 종류의 일반 요청 처리에 사용할 수 있습니다.

61.4.2. ClientRequestFilter 인터페이스

javax.ws.rs.client.ClientRequestFilter 인터페이스는 다음과 같이 정의됩니다.

// Java
package javax.ws.rs.client;
...
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientRequestContext;
...
public interface ClientRequestFilter {
    void filter(ClientRequestContext requestContext) throws IOException;
}
Copy to Clipboard Toggle word wrap

ClientRequestFilter 를 구현하면 클라이언트 측에서 ClientRequest 확장 지점에 대한 필터를 만들어 메시지를 서버로 보내기 전에 요청 메시지를 필터링할 수 있습니다.

61.4.3. ClientRequestContext 인터페이스

ClientRequestFilterfilter 메서드는 발신 요청 메시지 및 관련 메타데이터에 액세스하는 데 사용할 수 있는 javax.ws.rs.client.ClientRequestContext 유형의 단일 인수를 수신합니다. ClientRequestContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.client;

import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyWriter;

public interface ClientRequestContext {

    public Object getProperty(String name);

    public Collection<String> getPropertyNames();

    public void setProperty(String name, Object object);

    public void removeProperty(String name);

    public URI getUri();

    public void setUri(URI uri);

    public String getMethod();

    public void setMethod(String method);

    public MultivaluedMap<String, Object> getHeaders();

    public abstract MultivaluedMap<String, String> getStringHeaders();

    public String getHeaderString(String name);

    public Date getDate();

    public Locale getLanguage();

    public MediaType getMediaType();

    public List<MediaType> getAcceptableMediaTypes();

    public List<Locale> getAcceptableLanguages();

    public Map<String, Cookie> getCookies();

    public boolean hasEntity();

    public Object getEntity();

    public Class<?> getEntityClass();

    public Type getEntityType();

    public void setEntity(final Object entity);

    public void setEntity(
            final Object entity,
            final Annotation[] annotations,
            final MediaType mediaType);

    public Annotation[] getEntityAnnotations();

    public OutputStream getEntityStream();

    public void setEntityStream(OutputStream outputStream);

    public Client getClient();

    public Configuration getConfiguration();

    public void abortWith(Response response);
}
Copy to Clipboard Toggle word wrap

61.4.4. 샘플 구현

ClientRequest 확장 지점(즉, 요청 메시지를 보내기 전에 필터가 실행되는 경우)에 대한 클라이언트 요청 필터를 구현하려면 ClientRequestFilter 인터페이스를 구현하는 클래스를 정의합니다.

예를 들어 다음 코드는 우선 순위가 20인 ClientRequest 확장 지점에 설치되는 간단한 클라이언트 요청 필터의 예를 보여줍니다.

// Java
package org.jboss.fuse.example;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.annotation.Priority;

@Priority(value = 20)
public class SampleClientRequestFilter implements ClientRequestFilter {

  public SampleClientRequestFilter() {
    System.out.println("SampleClientRequestFilter starting up");
  }

  @Override
  public void filter(ClientRequestContext requestContext) {
    System.out.println("ClientRequestFilter.filter() invoked");
  }
}
Copy to Clipboard Toggle word wrap

61.4.5. 호출 중단

적합한 클라이언트 요청 필터를 구현하여 클라이언트 측 호출을 중단할 수 있습니다. 예를 들어 클라이언트 측 필터를 구현하여 요청이 올바르게 포맷되었는지 확인하고 필요한 경우 요청을 중단할 수 있습니다.

다음 테스트 코드는 항상 요청을 중단하고 BAD_REQUEST HTTP 상태를 클라이언트 호출 코드로 반환합니다.

// Java
package org.jboss.fuse.example;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.annotation.Priority;

@Priority(value = 10)
public class TestAbortClientRequestFilter implements ClientRequestFilter {

  public TestAbortClientRequestFilter() {
    System.out.println("TestAbortClientRequestFilter starting up");
  }

  @Override
  public void filter(ClientRequestContext requestContext) {
    // Test filter: aborts with BAD_REQUEST status
    requestContext.abortWith(Response.status(Status.BAD_REQUEST).build());
  }
}
Copy to Clipboard Toggle word wrap

61.4.6. 클라이언트 요청 필터 등록

Cryostat-RS 2.0 클라이언트 API를 사용하여 javax.ws.rs.client.client .Client 개체 또는 javax.ws.rs.client.WebTarget 오브젝트에 직접 클라이언트 요청 필터를 등록할 수 있습니다. 효과적으로, 클라이언트 요청 필터를 선택적으로 다른 범위에 적용할 수 있으므로 특정 URI 경로만 필터의 영향을 받습니다.

예를 들어 다음 코드는 클라이언트 개체를 사용하여 수행한 모든 호출에 적용되도록 SampleClientRequestFilter 필터를 등록하고, TestAbortClientRequestFilter 필터를 등록하여 rest/TestAbortClientRequest RequestRequestRequest의 하위 경로에만 적용되도록 하는 방법을 보여줍니다.

// Java
...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
client.register(new SampleClientRequestFilter());
WebTarget target = client
  .target("http://localhost:8001/rest/TestAbortClientRequest");
target.register(new TestAbortClientRequestFilter());
Copy to Clipboard Toggle word wrap

61.5. 클라이언트 응답 필터

61.5.1. 개요

이 섹션에서는 클라이언트 측에서 들어오는 응답 메시지를 가로채는 데 사용되는 클라이언트 응답 필터 를 구현하고 등록하는 방법을 설명합니다. 클라이언트 응답 필터는 클라이언트 측의 모든 종류의 일반 응답 처리에 사용할 수 있습니다.

61.5.2. ClientResponseFilter 인터페이스

javax.ws.rs.client.ClientResponseFilter 인터페이스는 다음과 같이 정의됩니다.

// Java
package javax.ws.rs.client;
...
import java.io.IOException;

public interface ClientResponseFilter {
    void filter(ClientRequestContext requestContext, ClientResponseContext responseContext)
            throws IOException;
}
Copy to Clipboard Toggle word wrap

ClientResponseFilter 를 구현하면 클라이언트 측의 ClientResponse 확장 지점에 대한 필터를 생성하여 서버에서 받은 후 응답 메시지를 필터링할 수 있습니다.

61.5.3. ClientResponseContext 인터페이스

ClientResponseFilter필터 방법은 두 가지 인수를 수신합니다. javax.ws.rs.client.ClientRequestContext 유형( “ClientRequestContext 인터페이스”참조)과 발신 응답 메시지 및 관련 메타데이터에 액세스하는 데 사용할 수 있는 javax.ws.rs.client.ClientResponseContext 인수입니다.

ClientResponseContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.client;

import java.io.InputStream;
import java.net.URI;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;

public interface ClientResponseContext {

    public int getStatus();

    public void setStatus(int code);

    public Response.StatusType getStatusInfo();

    public void setStatusInfo(Response.StatusType statusInfo);

    public MultivaluedMap<String, String> getHeaders();

    public String getHeaderString(String name);

    public Set<String> getAllowedMethods();

    public Date getDate();

    public Locale getLanguage();

    public int getLength();

    public MediaType getMediaType();

    public Map<String, NewCookie> getCookies();

    public EntityTag getEntityTag();

    public Date getLastModified();

    public URI getLocation();

    public Set<Link> getLinks();

    boolean hasLink(String relation);

    public Link getLink(String relation);

    public Link.Builder getLinkBuilder(String relation);

    public boolean hasEntity();

    public InputStream getEntityStream();

    public void setEntityStream(InputStream input);
}
Copy to Clipboard Toggle word wrap

61.5.4. 샘플 구현

ClientResponse 확장 지점(즉, 서버에서 응답 메시지를 수신한 후 필터가 실행되는 경우)에 대한 클라이언트 응답 필터를 구현하려면 ClientResponseFilter 인터페이스를 구현하는 클래스를 정의합니다.

예를 들어 다음 코드는 우선 순위가 20인 ClientResponse 확장 지점에 설치되는 간단한 클라이언트 응답 필터의 예를 보여줍니다.

// Java
package org.jboss.fuse.example;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.annotation.Priority;

@Priority(value = 20)
public class SampleClientResponseFilter implements ClientResponseFilter {

  public SampleClientResponseFilter() {
    System.out.println("SampleClientResponseFilter starting up");
  }

  @Override
  public void filter(
      ClientRequestContext requestContext,
      ClientResponseContext responseContext
  )
  {
    // Add an extra header on the response
    responseContext.getHeaders().putSingle("MyCustomHeader", "my custom data");
  }
}
Copy to Clipboard Toggle word wrap

61.5.5. 클라이언트 응답 필터 등록

Cryostat-RS 2.0 클라이언트 API를 사용하여 javax.ws.rs.client.client .Client 개체 또는 javax.ws.rs.client.WebTarget 오브젝트에 직접 클라이언트 응답 필터를 등록할 수 있습니다. 효과적으로, 클라이언트 요청 필터를 선택적으로 다른 범위에 적용할 수 있으므로 특정 URI 경로만 필터의 영향을 받습니다.

예를 들어 다음 코드는 클라이언트 개체를 사용하여 수행한 모든 호출에 적용되도록 SampleClientResponseFilter 필터를 등록하는 방법을 보여줍니다.

// Java
...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
client.register(new SampleClientResponseFilter());
Copy to Clipboard Toggle word wrap

61.6. 엔터티 리더 인터셉터

61.6.1. 개요

이 섹션에서는 클라이언트 측 또는 서버 측에서 메시지 본문을 읽을 때 입력 스트림을 가로챌 수 있는 엔터티 리더 인터셉터 를 구현하고 등록하는 방법을 설명합니다. 이는 일반적으로 암호화 및 암호 해독과 같은 요청 본문의 일반적인 변환 또는 압축 및 압축 해제에 유용합니다.

61.6.2. readerInterceptor 인터페이스

javax.ws.rs.ext. CryostatInterceptor 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.ext;

public interface ReaderInterceptor {
    public Object aroundReadFrom(ReaderInterceptorContext context)
            throws java.io.IOException, javax.ws.rs.WebApplicationException;
}
Copy to Clipboard Toggle word wrap

ReaderInterceptor 인터페이스를 구현하면 서버 측 또는 클라이언트 측에서 읽을 수 있으므로 메시지 본문(Entity 개체)을 가로챌 수 있습니다. 다음 컨텍스트 중 하나에서 엔터티 리더 인터셉터를 사용할 수 있습니다.

  • 서버 측인터셉터로 바인딩된 경우 엔터티 리더 인터셉터는 애플리케이션 코드(일치 일치하는 리소스에서)에서 액세스할 때 요청 메시지 본문을 가로챌 수 있습니다. REST 요청의 의미 체계에 따라 메시지 본문은 일치하는 리소스에서 액세스하지 못할 수 있습니다. 이 경우 리더 인터셉터가 호출되지 않습니다.
  • 클라이언트 측인터셉터로 바인딩된 경우 엔터티 리더 인터셉터는 클라이언트 코드에서 액세스할 때 응답 메시지 본문을 가로챌 수 있습니다. 클라이언트 코드가 응답 메시지에 명시적으로 액세스하지 않는 경우(예: Response.getEntity 메서드를 호출하여), 리더 인터셉터는 호출되지 않습니다.

61.6.3. ReaderInterceptorContext 인터페이스

ReaderInterceptoraroundReadFrom 메서드는 메시지 본문(Entity 개체) 및 메시지 메타데이터 모두에 액세스하는 데 사용할 수 있는 javax.ws.rs.ext. CryostatInterceptorContext 유형의 하나의 인수를 수신합니다.

ReaderInterceptorContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.ext;

import java.io.IOException;
import java.io.InputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;

public interface ReaderInterceptorContext extends InterceptorContext {

    public Object proceed() throws IOException, WebApplicationException;

    public InputStream getInputStream();

    public void setInputStream(InputStream is);

    public MultivaluedMap<String, String> getHeaders();
}
Copy to Clipboard Toggle word wrap

61.6.4. InterceptorContext 인터페이스

ReaderInterceptorContext 인터페이스는 기본 InterceptorContext 인터페이스에서 상속된 메서드도 지원합니다.

InterceptorContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.ext;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collection;

import javax.ws.rs.core.MediaType;

public interface InterceptorContext {

    public Object getProperty(String name);

    public Collection<String> getPropertyNames();

    public void setProperty(String name, Object object);

    public void removeProperty(String name);

    public Annotation[] getAnnotations();

    public void setAnnotations(Annotation[] annotations);

    Class<?> getType();

    public void setType(Class<?> type);

    Type getGenericType();

    public void setGenericType(Type genericType);

    public MediaType getMediaType();

    public void setMediaType(MediaType mediaType);
}
Copy to Clipboard Toggle word wrap

61.6.5. 클라이언트 측의 샘플 구현

클라이언트 측에 대한 엔터티 리더 인터셉터를 구현하려면 ReaderInterceptor 인터페이스를 구현하는 클래스를 정의합니다.

예를 들어 다음 코드는 클라이언트 측에 대한 엔터티 리더 인터셉터의 예를 보여줍니다(우선 순위 10으로 사용).이 예제에서는 들어오는 응답의 메시지 본문에서 knative _NAME 의 모든 인스턴스를 Red Hat 으로 대체합니다.

// Java
package org.jboss.fuse.example;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.annotation.Priority;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;

@Priority(value = 10)
public class SampleClientReaderInterceptor implements ReaderInterceptor {

  @Override
  public Object aroundReadFrom(ReaderInterceptorContext interceptorContext)
          throws IOException, WebApplicationException
  {
    InputStream inputStream = interceptorContext.getInputStream();
    byte[] bytes = new byte[inputStream.available()];
    inputStream.read(bytes);
    String responseContent = new String(bytes);
    responseContent = responseContent.replaceAll("COMPANY_NAME", "Red Hat");
    interceptorContext.setInputStream(new ByteArrayInputStream(responseContent.getBytes()));

    return interceptorContext.proceed();
  }
}
Copy to Clipboard Toggle word wrap

61.6.6. 서버 측의 샘플 구현

서버 측에 대한 엔터티 리더 인터셉터를 구현하려면 ReaderInterceptor 인터페이스를 구현하고 @Provider 주석으로 주석을 추가하는 클래스를 정의합니다.

예를 들어 다음 코드는 서버 측에 대한 엔터티 리더 인터셉터의 예를 보여줍니다(우선 순위 10으로 사용).이 예제에서는 들어오는 요청의 메시지 본문에서 knative _NAME 의 모든 인스턴스를 Red Hat 으로 대체합니다.

// Java
package org.jboss.fuse.example;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.annotation.Priority;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;

@Priority(value = 10)
@Provider
public class SampleServerReaderInterceptor implements ReaderInterceptor {

  @Override
  public Object aroundReadFrom(ReaderInterceptorContext interceptorContext)
          throws IOException, WebApplicationException {
    InputStream inputStream = interceptorContext.getInputStream();
    byte[] bytes = new byte[inputStream.available()];
    inputStream.read(bytes);
    String requestContent = new String(bytes);
    requestContent = requestContent.replaceAll("COMPANY_NAME", "Red Hat");
    interceptorContext.setInputStream(new ByteArrayInputStream(requestContent.getBytes()));

    return interceptorContext.proceed();
  }
}
Copy to Clipboard Toggle word wrap

61.6.7. 클라이언트 측에서 리더 인터셉터 바인딩

Cryostat-RS 2.0 클라이언트 API를 사용하여 javax.ws.rs.client.Client 개체 또는 javax.ws.rs.client.client .WebTarget 오브젝트에 직접 엔터티 리더 인터셉터를 등록할 수 있습니다. 효과적으로, 이는 독자 인터셉터가 선택적으로 다른 범위에 적용되어 특정 URI 경로만 인터셉터의 영향을 받을 수 있음을 의미합니다.

예를 들어 다음 코드는 클라이언트 개체를 사용하여 만든 모든 호출에 적용되도록 SampleClient CryostatInterceptor 인터셉터를 등록하는 방법을 보여줍니다.

// Java
...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
client.register(SampleClientReaderInterceptor.class);
Copy to Clipboard Toggle word wrap

Cryostat-RS 2.0 클라이언트에 인터셉터 등록에 대한 자세한 내용은 49.5절. “클라이언트 끝점 구성” 에서 참조하십시오.

61.6.8. 서버 측에서 리더 인터셉터 바인딩

서버 측에서 리더 인터셉터를 바인딩 하려면(즉, Apache CXF 런타임에 설치하려면 다음 단계를 수행합니다.

  1. 다음 코드 조각에 표시된 것처럼 reader interceptor 클래스에 @Provider 주석을 추가합니다.

    // Java
    package org.jboss.fuse.example;
    ...
    import javax.annotation.Priority;
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.ext.Provider;
    import javax.ws.rs.ext.ReaderInterceptor;
    import javax.ws.rs.ext.ReaderInterceptorContext;
    
    @Priority(value = 10)
    @Provider
    public class SampleServerReaderInterceptor implements ReaderInterceptor {
      ...
    }
    Copy to Clipboard Toggle word wrap

    리더 인터셉터 구현이 Apache CXF 런타임에 로드되면 REST 구현에서 로드된 클래스를 자동으로 검색하여 @Provider 주석( 검사 단계)으로 표시된 클래스를 검색합니다.

  2. XML에서 Cryostat-RS 서버 끝점을 정의할 때(예: 18.1절. “Cryostat-RS 서버 끝점 구성”참조) jaxrs:providers 요소의 공급자 목록에 reader interceptor를 추가합니다.

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
        xmlns:cxf="http://cxf.apache.org/blueprint/core"
        ...
    >
        ...
        <jaxrs:server id="customerService" address="/customers">
          ...
          <jaxrs:providers>
            <ref bean="interceptorProvider" />
          </jaxrs:providers>
          <bean id="interceptorProvider" class="org.jboss.fuse.example.SampleServerReaderInterceptor"/>
    
        </jaxrs:server>
    
    </blueprint>
    Copy to Clipboard Toggle word wrap
    참고

    이 단계는 Apache CXF의 비표준 요구 사항입니다. Cryostat-RS 표준에 따라 @Provider 주석은 인터셉터를 바인딩하는 데 필요한 모든 주석이어야 합니다. 그러나 실제로 표준 접근 방식은 다소 유연하지 않으며 많은 라이브러리가 대규모 프로젝트에 포함될 때 충돌하는 공급자로 이어질 수 있습니다.

61.7. 엔터티 작성자 인터셉터

61.7.1. 개요

이 섹션에서는 클라이언트 측 또는 서버 측에 메시지 본문을 작성할 때 출력 스트림을 가로챌 수 있는 엔터티 작성자 인터셉터 를 구현하고 등록하는 방법을 설명합니다. 이는 일반적으로 암호화 및 암호 해독과 같은 요청 본문의 일반적인 변환 또는 압축 및 압축 해제에 유용합니다.

61.7.2. WriterInterceptor 인터페이스

javax.ws.rs.ext.WriterInterceptor 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.ext;

public interface WriterInterceptor {
    void aroundWriteTo(WriterInterceptorContext context)
            throws java.io.IOException, javax.ws.rs.WebApplicationException;
}
Copy to Clipboard Toggle word wrap

WriterInterceptor 인터페이스를 구현하면 서버 측 또는 클라이언트 측에 작성되므로 메시지 본문(Entity 개체)을 가로챌 수 있습니다. 다음 컨텍스트 중 하나에서 엔터티 작성자 인터셉터를 사용할 수 있습니다.

  • 서버 측인터셉터로 바인딩된 경우 엔터티 작성자 인터셉터는 마샬링되어 클라이언트로 다시 전송되기 직전에 응답 메시지 본문을 가로챌 수 있습니다.
  • 클라이언트 측인터셉터로 바인딩된 클라이언트 측에서는 엔터티 작성자 인터셉터가 마샬링되어 서버로 전송되기 직전에 요청 메시지 본문을 가로챌 수 있습니다.

61.7.3. WriterInterceptorContext 인터페이스

WriterInterceptoraroundWriteTo 메서드는 메시지 본문(Entity 오브젝트) 및 메시지 메타데이터 모두에 액세스하는 데 사용할 수 있는 javax.ws.rs.ext.WriterInterceptorContext 유형의 하나의 인수를 수신합니다.

WriterInterceptorContext 인터페이스는 다음과 같이 정의됩니다.

// Java
...
package javax.ws.rs.ext;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;

public interface WriterInterceptorContext extends InterceptorContext {

    void proceed() throws IOException, WebApplicationException;

    Object getEntity();

    void setEntity(Object entity);

    OutputStream getOutputStream();

    public void setOutputStream(OutputStream os);

    MultivaluedMap<String, Object> getHeaders();
}
Copy to Clipboard Toggle word wrap

61.7.4. InterceptorContext 인터페이스

WriterInterceptorContext 인터페이스는 기본 InterceptorContext 인터페이스에서 상속된 메서드도 지원합니다. InterceptorContext 의 정의는 “InterceptorContext 인터페이스” 를 참조하십시오.

61.7.5. 클라이언트 측의 샘플 구현

클라이언트 측에 대한 엔터티 작성자 인터셉터를 구현하려면 WriterInterceptor 인터페이스를 구현하는 클래스를 정의합니다.

예를 들어 다음 코드는 클라이언트 측에 대한 엔터티 작성자 인터셉터의 예를 보여줍니다(우선 순위 10의 경우) 발신 요청의 메시지 본문에 텍스트 행을 추가합니다.

// Java
package org.jboss.fuse.example;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import javax.annotation.Priority;

@Priority(value = 10)
public class SampleClientWriterInterceptor implements WriterInterceptor {

  @Override
  public void aroundWriteTo(WriterInterceptorContext interceptorContext)
          throws IOException, WebApplicationException {
    OutputStream outputStream = interceptorContext.getOutputStream();
    String appendedContent = "\nInterceptors always get the last word in.";
    outputStream.write(appendedContent.getBytes());
    interceptorContext.setOutputStream(outputStream);

    interceptorContext.proceed();
  }
}
Copy to Clipboard Toggle word wrap

61.7.6. 서버 측의 샘플 구현

서버 측에 대한 엔터티 작성자 인터셉터를 구현하려면 WriterInterceptor 인터페이스를 구현하고 @Provider 주석으로 주석을 추가하는 클래스를 정의합니다.

예를 들어 다음 코드는 발신 요청의 메시지 본문에 텍스트 행을 추가하는 서버 측에 대한 엔터티 작성자 인터셉터의 예제를 보여줍니다.

// Java
package org.jboss.fuse.example;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import javax.annotation.Priority;

@Priority(value = 10)
@Provider
public class SampleServerWriterInterceptor implements WriterInterceptor {

  @Override
  public void aroundWriteTo(WriterInterceptorContext interceptorContext)
          throws IOException, WebApplicationException {
    OutputStream outputStream = interceptorContext.getOutputStream();
    String appendedContent = "\nInterceptors always get the last word in.";
    outputStream.write(appendedContent.getBytes());
    interceptorContext.setOutputStream(outputStream);

    interceptorContext.proceed();
  }
}
Copy to Clipboard Toggle word wrap

61.7.7. 클라이언트 측에 작성자 인터셉터 바인딩

Cryostat-RS 2.0 클라이언트 API를 사용하여 javax.ws.rs.client.Client 개체 또는 javax.ws.rs.client.WebTarget 오브젝트에 직접 엔터티 작성자 인터셉터를 등록할 수 있습니다. 효과적으로, 이는 작성자 인터셉터가 선택적으로 다른 범위에 적용할 수 있으므로 특정 URI 경로만 인터셉터의 영향을 받습니다.

예를 들어 다음 코드는 클라이언트 개체를 사용하여 만든 모든 호출에 적용되도록 SampleClient CryostatInterceptor 인터셉터를 등록하는 방법을 보여줍니다.

// Java
...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
client.register(SampleClientReaderInterceptor.class);
Copy to Clipboard Toggle word wrap

Cryostat-RS 2.0 클라이언트에 인터셉터 등록에 대한 자세한 내용은 49.5절. “클라이언트 끝점 구성” 에서 참조하십시오.

61.7.8. 서버 측에 작성자 인터셉터 바인딩

서버 측에 작성자 인터셉터를 바인딩 하려면(즉, Apache CXF 런타임에 설치하려면 다음 단계를 수행합니다.

  1. 다음 코드 조각에 표시된 것처럼 writer 인터셉터 클래스에 @Provider 주석을 추가합니다.

    // Java
    package org.jboss.fuse.example;
    ...
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.ext.Provider;
    import javax.ws.rs.ext.WriterInterceptor;
    import javax.ws.rs.ext.WriterInterceptorContext;
    import javax.annotation.Priority;
    
    @Priority(value = 10)
    @Provider
    public class SampleServerWriterInterceptor implements WriterInterceptor {
      ...
    }
    Copy to Clipboard Toggle word wrap

    작성자 인터셉터 구현이 Apache CXF 런타임에 로드되면 REST 구현에서 로드된 클래스를 자동으로 검색하여 @Provider 주석( 검사 단계)으로 표시된 클래스를 검색합니다.

  2. XML에서 Cryostat-RS 서버 끝점을 정의할 때(예: 18.1절. “Cryostat-RS 서버 끝점 구성”참조) jaxrs:providers 요소의 공급자 목록에 작성자 인터셉터를 추가합니다.

    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
        xmlns:cxf="http://cxf.apache.org/blueprint/core"
        ...
    >
        ...
        <jaxrs:server id="customerService" address="/customers">
          ...
          <jaxrs:providers>
            <ref bean="interceptorProvider" />
          </jaxrs:providers>
          <bean id="interceptorProvider" class="org.jboss.fuse.example.SampleServerWriterInterceptor"/>
    
        </jaxrs:server>
    
    </blueprint>
    Copy to Clipboard Toggle word wrap
    참고

    이 단계는 Apache CXF의 비표준 요구 사항입니다. Cryostat-RS 표준에 따라 @Provider 주석은 인터셉터를 바인딩하는 데 필요한 모든 주석이어야 합니다. 그러나 실제로 표준 접근 방식은 다소 유연하지 않으며 많은 라이브러리가 대규모 프로젝트에 포함될 때 충돌하는 공급자로 이어질 수 있습니다.

61.8. 동적 바인딩

61.8.1. 개요

컨테이너 필터 및 컨테이너 인터셉터를 리소스에 바인딩하는 표준 방법은 @Provider 주석을 사용하여 필터 및 인터셉터에 주석을 추가하는 것입니다. 이렇게 하면 바인딩이 global: 즉, 필터 및 인터셉터가 서버 측의 모든 리소스 클래스 및 리소스 메서드에 바인딩됩니다.

동적 바인딩은 서버 측에서 바인딩하는 대체 방법이므로 인터셉터 및 필터가 적용되는 리소스 방법을 선택하고 선택할 수 있습니다. 필터 및 인터셉터에 대한 동적 바인딩을 활성화하려면 여기에 설명된 대로 사용자 지정 DynamicFeature 인터페이스를 구현해야 합니다.

61.8.2. DynamicFeature 인터페이스

DynamicFeature 인터페이스는 다음과 같이 javax.ws.rx.container 패키지에 정의되어 있습니다.

// Java
package javax.ws.rs.container;

import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.WriterInterceptor;

public interface DynamicFeature {
    public void configure(ResourceInfo resourceInfo, FeatureContext context);
}
Copy to Clipboard Toggle word wrap

61.8.3. 동적 기능 구현

다음과 같이 동적 기능을 구현합니다.

  1. 이전에 설명한 대로 하나 이상의 컨테이너 필터 또는 컨테이너 인터셉터를 구현합니다. 그러나 @Provider 주석으로 주석을 넣지 마십시오(다른 방법으로는 전역적으로 바인딩되어 동적 기능을 효과적으로 관련 없음).
  2. DynamicFeature 클래스를 구현하여 configure 메서드를 재정의하여 고유한 동적 기능을 만듭니다.
  3. configure 메서드에서는 resourceInfo 인수를 사용하여 어떤 리소스 클래스와 이 기능을 호출하는 리소스 메서드를 검색할 수 있습니다.In the configure method, you can use the resourceInfo argument to discover which resource class and which resource method is being called for. 이 정보는 일부 필터 또는 인터셉터를 등록할지 여부를 결정하는 기반으로 사용할 수 있습니다.
  4. 현재 리소스 메서드에 필터 또는 인터셉터를 등록하려면 context.register 메서드 중 하나를 호출하여 이를 수행할 수 있습니다.
  5. 배포 단계 중에 선택되도록 동적 기능 클래스에 @Provider 주석에 주석을 답니다.

61.8.4. 동적 기능 예

다음 예제에서는 @GET: 주석이 달린 MyResource 클래스(또는 하위 클래스)의 모든 메서드에 LoggingFilter 필터를 등록하는 동적 기능을 정의하는 방법을 보여줍니다.

// Java
...
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;

@Provider
public class DynamicLoggingFilterFeature implements DynamicFeature {
  @Override
  void configure(ResourceInfo resourceInfo, FeatureContext context) {
    if (MyResource.class.isAssignableFrom(resourceInfo.getResourceClass())
      && resourceInfo.getResourceMethod().isAnnotationPresent(GET.class)) {
      context.register(new LoggingFilter());
  }
}
Copy to Clipboard Toggle word wrap

61.8.5. 동적 바인딩 프로세스

Cryostat-RS 표준을 사용하려면 DynamicFeature.configure 메서드를 각 리소스 메서드에 대해 정확히 한 번만 호출해야 합니다. 즉, 모든 리소스 방법에는 동적 기능에 의해 설치된 필터 또는 인터셉터가 잠재적으로 있을 수 있지만 각 경우에 필터 또는 인터셉터를 등록할지 여부를 결정하는 동적 기능입니다. 즉, 동적 기능에서 지원하는 바인딩 단위는 개별 리소스 메서드 수준에 있습니다.

61.8.6. FeatureContext 인터페이스

FeatureContext 인터페이스( 구성 메서드에서 필터 및 인터셉터를 등록할 수 있음)는 다음과 같이 Configurable <>의 하위 인터페이스로 정의됩니다.

// Java
package javax.ws.rs.core;

public interface FeatureContext extends Configurable<FeatureContext> {
}
Copy to Clipboard Toggle word wrap

Configurable&lt;> 인터페이스는 다음과 같이 단일 리소스 메서드에 필터 및 인터셉터를 등록하는 다양한 방법을 정의합니다.

// Java
...
package javax.ws.rs.core;

import java.util.Map;

public interface Configurable<C extends Configurable> {
    public Configuration getConfiguration();
    public C property(String name, Object value);
    public C register(Class<?> componentClass);
    public C register(Class<?> componentClass, int priority);
    public C register(Class<?> componentClass, Class<?>... contracts);
    public C register(Class<?> componentClass, Map<Class<?>, Integer> contracts);
    public C register(Object component);
    public C register(Object component, int priority);
    public C register(Object component, Class<?>... contracts);
    public C register(Object component, Map<Class<?>, Integer> contracts);
}
Copy to Clipboard Toggle word wrap

62장. Apache CXF 메시지 처리 단계

62.1. 인바운드 단계

표 62.1. “인바운드 메시지 처리 단계” 인바운드 인터셉터 체인에서 사용할 수 있는 단계를 나열합니다.

Expand
표 62.1. 인바운드 메시지 처리 단계
단계설명

수신

바이너리 첨부 파일에 대한 MIME 경계를 결정하는 것과 같은 전송 특정 처리를 수행합니다.

PRE_STREAM

전송에서 수신한 원시 데이터 스트림을 처리합니다.

USER_STREAM

POST_STREAM

READ

요청이 Cryostat 또는 XML 메시지인지 여부를 확인하고 빌드에서는 적절한 인터셉터를 추가합니다. 이 단계에서 Cryostat 메시지 헤더도 처리됩니다.

PRE_PROTOCOL

프로토콜 수준 처리를 수행합니다. 여기에는 WS-* 헤더 처리 및 Cryostat 메시지 속성 처리가 포함됩니다.

USER_PROTOCOL

POST_PROTOCOL

UNMARSHAL

메시지 데이터를 애플리케이션 수준 코드에서 사용하는 개체에 요약합니다.

PRE_LOGICAL

요약되지 않은 메시지 데이터를 처리합니다.

USER_LOGICAL

POST_LOGICAL

PRE_INVOKE

INVOKE

메시지를 애플리케이션 코드에 전달합니다. 이 단계에서는 서버 측에서 서비스 구현이 호출됩니다. 클라이언트 측에서 응답이 애플리케이션에 다시 전달됩니다.

POST_INVOKE

아웃바운드 인터셉터 체인을 호출합니다.

62.2. 아웃바운드 단계

표 62.2. “인바운드 메시지 처리 단계” 인바운드 인터셉터 체인에서 사용할 수 있는 단계를 나열합니다.

Expand
표 62.2. 인바운드 메시지 처리 단계
단계설명

SETUP

체인의 이후 단계에서 필요한 모든 설정을 수행합니다.

PRE_LOGICAL

애플리케이션 수준에서 전달된 unmarshalled 데이터에 대한 처리를 수행합니다.

USER_LOGICAL

POST_LOGICAL

PREPARE_SEND

유선에 메시지를 쓰기 위한 연결을 엽니다.

PRE_STREAM

데이터 스트림 입력을 위한 메시지를 준비하는 데 필요한 처리를 수행합니다.

PRE_PROTOCOL

프로토콜 특정 정보 처리를 시작합니다.

WRITE

프로토콜 메시지를 작성합니다.

PRE_MARSHAL

메시지를 마샬링합니다.

MARSHAL

POST_MARSHAL

USER_PROTOCOL

프로토콜 메시지를 처리합니다.

POST_PROTOCOL

USER_STREAM

바이트 수준 메시지를 처리합니다.

POST_STREAM

전송

메시지를 보내고 전송 스트림을 닫습니다.

중요

아웃바운드 인터셉터 체인에는 이름이 _ENDING 으로 추가되는 미러 단계가 있습니다. 종료 단계는 데이터가 유선에 기록되기 전에 일부 터미널 작업을 수행해야 하는 인터셉터가 사용됩니다.

63장. Apache CXF 제공 인터셉터

63.1. 핵심 Apache CXF 인터셉터

63.1.1. 인바운드

표 63.1. “핵심 인바운드 인터셉터” 모든 Apache CXF 엔드포인트에 추가된 코어 인바운드 인터셉터를 나열합니다.

Expand
표 63.1. 핵심 인바운드 인터셉터
클래스단계설명

ServiceInvokerInterceptor

호출

서비스에서 적절한 메서드를 호출합니다.

63.1.2. 아웃바운드

Apache CXF는 기본적으로 아웃바운드 인터셉터 체인에 코어 인터셉터를 추가하지 않습니다. 엔드 포인트의 아웃 바운드 인터셉터 체인의 내용은 사용 중인 기능에 따라 다릅니다.

63.2. 프론트 엔드

63.2.1. JAX-WS

표 63.2. “인바운드 Cryostat-WS 인터셉터” Cryostat-WS 엔드포인트의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.2. 인바운드 Cryostat-WS 인터셉터
클래스단계설명

HolderInInterceptor

PRE_INVOKE

메시지의 외부 또는 아웃 매개 변수에 대한 홀더 개체를 만듭니다.Creates holder objects for any out or in/out parameters in the message.

WrapperClassInInterceptor

POST_LOGICAL

래핑된 doc/literal 메시지의 부분을 적절한 오브젝트 배열로 래핑합니다.

LogicalHandlerInInterceptor

PRE_PROTOCOL

메시지 처리를 엔드포인트에서 사용하는 Cryostat-WS 논리 처리기에 전달합니다. Cryostat-WS 핸들러가 완료되면 인바운드 체인의 다음 인터셉터로 메시지가 전달됩니다.

SOAPHandlerInterceptor

PRE_PROTOCOL

메시지 처리를 엔드포인트에서 사용하는 Cryostat-WS Cryostat 처리기에 전달합니다. Cryostat 처리기가 메시지와 함께 완료되면 메시지는 체인의 다음 인터셉터로 전달됩니다.

표 63.3. “아웃바운드 Cryostat-WS 인터셉터” Cryostat-WS 끝점의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.3. 아웃바운드 Cryostat-WS 인터셉터
클래스단계설명

HolderOutInterceptor

PRE_LOGICAL

홀더 오브젝트에서 임의의 out 및 in/out 매개변수 값을 제거하고 메시지의 매개 변수 목록에 해당 값을 추가합니다.

WebFaultOutInterceptor

PRE_PROTOCOL

아웃바운드 오류 메시지를 처리합니다.

WrapperClassOutInterceptor

PRE_LOGICAL

메시지에 추가되기 전에 doc/literal 메시지와 rpc/literal 메시지가 올바르게 래핑되었는지 확인합니다.

LogicalHandlerOutInterceptor

PRE_MARSHAL

메시지 처리를 엔드포인트에서 사용하는 Cryostat-WS 논리 처리기에 전달합니다. Cryostat-WS 핸들러가 완료되면 아웃바운드 체인의 다음 인터셉터로 메시지가 전달됩니다.

SOAPHandlerInterceptor

PRE_PROTOCOL

메시지 처리를 엔드포인트에서 사용하는 Cryostat-WS Cryostat 처리기에 전달합니다. Cryostat 처리기가 메시지 처리를 완료하면 체인의 다음 인터셉터로 전달됩니다.

MessageSenderInterceptor

PREPARE_SEND

대상 개체로 다시 호출하여 출력 스트림, 헤더 등을 설정하여 발신 전송을 준비합니다.

63.2.2. JAX-RS

표 63.4. “인바운드 Cryostat-RS 인터셉터” Cryostat-RS 끝점의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.4. 인바운드 Cryostat-RS 인터셉터
클래스단계설명

JAXRSInInterceptor

PRE_STREAM

루트 리소스 클래스를 선택하고 구성된 Cryostat-RS 요청 필터를 호출하고 루트 리소스에서 호출할 메서드를 결정합니다.

중요

Cryostat-RS 엔드포인트의 인바운드 체인은 ServiceInvokerInInterceptor 인터셉터로 바로 건너뜁니다. Cryostat RSInterceptor 이후 다른 인터셉터는 호출되지 않습니다.

표 63.5. “아웃바운드 Cryostat-RS 인터셉터” Cryostat-RS 끝점의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.5. 아웃바운드 Cryostat-RS 인터셉터
클래스단계설명

JAXRSOutInterceptor

MARSHAL

응답을 전송을 위한 적절한 형식으로 마샬링합니다.

63.3. 메시지 바인딩

63.3.1. SOAP

표 63.6. “인바운드 Cryostat 인터셉터” Cryostat 바인딩을 사용할 때 엔드포인트의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.6. 인바운드 Cryostat 인터셉터
클래스단계설명

CheckFaultInterceptor

POST_PROTOCOL

메시지가 오류 메시지인지 확인합니다. 메시지가 오류 메시지이면 일반 처리가 중단되고 오류 처리가 시작됩니다.

MustUnderstandInterceptor

PRE_PROTOCOL

헤더를 이해해야 하는 프로세스를 처리합니다.

RPCInInterceptor

UNMARSHAL

unmarshals rpc/literal 메시지 메시지가 베어이면 메시지가 BareInInterceptor 개체에 전달되어 메시지 부분을 역직렬화합니다.

ReadsHeadersInterceptor

READ

Cryostat 헤더를 구문 분석하고 message 오브젝트에 저장합니다.

SoapActionInInterceptor

READ

Cryostat 작업 헤더를 구문 분석하고 해당 작업에 대한 고유 작업을 찾습니다.

SoapHeaderInterceptor

UNMARSHAL

작업 매개변수에 매핑되는 Cryostat 헤더를 적절한 개체에 바인딩합니다.

AttachmentInInterceptor

수신

mime 경계의 mime 헤더를 구문 분석하고, 루트 부분을 찾아 입력 스트림을 재설정하고, 다른 부분을 Attachment 오브젝트 컬렉션에 저장합니다.

DocLiteralInInterceptor

UNMARSHAL

Cryostat 본문의 첫 번째 요소를 검사하여 적절한 작업을 결정하고 데이터를 읽을 데이터 바인딩을 호출합니다.

StaxInInterceptor

POST_STREAM

메시지에서 XMLStream Cryostat 개체를 만듭니다.Creates an XMLStream Cryostat object from the message.

URIMappingInterceptor

UNMARSHAL

HTTP GET 메서드의 처리를 처리합니다.

SwAInInterceptor

PRE_INVOKE

바이너리 Cryostat 첨부 파일에 필요한 MIME 처리기를 만들고 해당 데이터를 매개 변수 목록에 추가합니다.

표 63.7. “아웃바운드 Cryostat 인터셉터” Cryostat 바인딩을 사용할 때 엔드포인트의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.7. 아웃바운드 Cryostat 인터셉터
클래스단계설명

RPCOutInterceptor

MARSHAL

전송을 위해 rpc 스타일 메시지를 마샬링합니다.

SoapHeaderOutFilterInterceptor

PRE_LOGICAL

인바운드로 표시된 모든 Cryostat 헤더를 제거합니다.

SoapPreProtocolOutInterceptor

POST_LOGICAL

Cryostat 버전과 Cryostat 작업 헤더를 설정합니다.

AttachmentOutInterceptor

PRE_STREAM

메시지에 있을 수 있는 첨부 파일을 처리하는 데 필요한 첨부 파일 마샬러와 mime 항목을 설정합니다.

BareOutInterceptor

MARSHAL

메시지 부분을 작성합니다.

StaxOutInterceptor

PRE_STREAM

메시지에서 XMLStreamWriter 개체를 만듭니다.Creates an XMLStreamWriter object from the message.

WrappedOutInterceptor

MARSHAL

아웃바운드 메시지 매개변수를 래핑합니다.

SoapOutInterceptor

WRITE

soap:envelope 요소와 메시지 헤더 블록의 요소를 씁니다. 또한 나머지 인터셉터가 채울 수 있도록 빈 soap:body 요소를 작성합니다.

SwAOutInterceptor

PRE_LOGICAL

Cryostat 첨부 파일로 패키징할 바이너리 데이터를 모두 제거하고 나중에 처리할 바이너리 데이터를 저장합니다.

63.3.2. XML

표 63.8. “인바운드 XML 인터셉터” XML 바인딩을 사용할 때 엔드포인트의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.8. 인바운드 XML 인터셉터
클래스단계설명

AttachmentInInterceptor

수신

mime 경계의 mime 헤더를 구문 분석하고, 루트 부분을 찾아 입력 스트림을 재설정한 다음, 다른 부분을 Attachment 오브젝트 컬렉션에 저장합니다.

DocLiteralInInterceptor

UNMARSHAL

메시지 본문의 첫 번째 요소를 검사하여 적절한 작업을 확인한 다음 데이터 바인딩을 호출합니다.

StaxInInterceptor

POST_STREAM

메시지에서 XMLStream Cryostat 개체를 만듭니다.Creates an XMLStream Cryostat object from the message.

URIMappingInterceptor

UNMARSHAL

HTTP GET 메서드의 처리를 처리합니다.

XMLMessageInInterceptor

UNMARSHAL

XML 메시지를 분리합니다.

표 63.9. “아웃바운드 XML 인터셉터” XML 바인딩을 사용할 때 엔드포인트의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.9. 아웃바운드 XML 인터셉터
클래스단계설명

StaxOutInterceptor

PRE_STREAM

메시지에서 XMLStreamWriter 개체를 만듭니다.Creates an XMLStreamWriter objects from the message.

WrappedOutInterceptor

MARSHAL

아웃바운드 메시지 매개변수를 래핑합니다.

XMLMessageOutInterceptor

MARSHAL

전송을 위해 메시지를 마샬링합니다.

63.3.3. CORBA

표 63.10. “인바운드 CORBA 인터셉터” CORBA 바인딩을 사용할 때 엔드포인트의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.10. 인바운드 CORBA 인터셉터
클래스단계설명

CorbaStreamInInterceptor

PRE_STREAM

CORBA 메시지를 역직렬화합니다.

BareInInterceptor

UNMARSHAL

메시지 부분을 역직렬화합니다.

표 63.11. “아웃바운드 CORBA 인터셉터” CORBA 바인딩을 사용할 때 엔드포인트의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.11. 아웃바운드 CORBA 인터셉터
클래스단계설명

CorbaStreamOutInterceptor

PRE_STREAM

메시지를 직렬화합니다.

BareOutInterceptor

MARSHAL

메시지 부분을 작성합니다.

CorbaStreamOutEndingInterceptor

USER_STREAM

메시지에 대해 스트림 가능한 오브젝트를 생성하여 메시지 컨텍스트에 저장합니다.

63.4. 기타 기능

63.4.1. 로깅

표 63.12. “인바운드 로깅 인터셉터” 로깅을 지원하기 위해 끝점의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.12. 인바운드 로깅 인터셉터
클래스단계설명

LoggingInInterceptor

수신

원시 메시지 데이터를 로깅 시스템에 씁니다.

표 63.13. “아웃바운드 로깅 인터셉터” 로깅을 지원하기 위해 엔드포인트의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.13. 아웃바운드 로깅 인터셉터
클래스단계설명

LoggingOutInterceptor

PRE_STREAM

로깅 시스템에 아웃바운드 메시지를 씁니다.

로깅에 대한 자세한 내용은 19장. Apache CXF Logging 을 참조하십시오.

63.4.2. WS-Addressing

표 63.14. “인바운드 WS-Addressing interceptors” WS-Addressing을 사용할 때 엔드포인트의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.14. 인바운드 WS-Addressing interceptors
클래스단계설명

MAPCodec

PRE_PROTOCOL

메시지 주소 지정 속성을 디코딩합니다.

표 63.15. “아웃바운드 WS-Addressing interceptors” WS-Addressing을 사용할 때 엔드포인트의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.15. 아웃바운드 WS-Addressing interceptors
클래스단계설명

MAPAggregator

PRE_LOGICAL

메시지의 메시지 주소 지정 속성을 집계합니다.

MAPCodec

PRE_PROTOCOL

메시지 주소 지정 속성을 인코딩합니다.

WS-Addressing에 대한 자세한 내용은 20장. WS-Addressing 배포 을 참조하십시오.

63.4.3. WS-RM

중요

WS-RM은 WS-Addressing을 사용하므로 모든 WS-Addressing 인터셉터도 인터셉터 체인에 추가됩니다.

표 63.16. “인바운드 WS-RM 인터셉터” WS-RM을 사용할 때 엔드포인트의 인바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.16. 인바운드 WS-RM 인터셉터
클래스단계설명

RMInInterceptor

PRE_LOGICAL

메시지 부분 및 승인 메시지의 집계를 처리합니다.

RMSoapInterceptor

PRE_PROTOCOL

WS-RM 속성을 메시지에서 인코딩하고 디코딩합니다.

표 63.17. “아웃바운드 WS-RM 인터셉터” WS-RM을 사용할 때 엔드포인트의 아웃바운드 메시지 체인에 추가된 인터셉터를 나열합니다.

Expand
표 63.17. 아웃바운드 WS-RM 인터셉터
클래스단계설명

RMOutInterceptor

PRE_LOGICAL

메시지 청크 및 청크 전송을 처리합니다. 또한 승인 및 재전송 요청의 처리를 처리합니다.

RMSoapInterceptor

PRE_PROTOCOL

WS-RM 속성을 메시지에서 인코딩하고 디코딩합니다.

WS-RM에 대한 자세한 내용은 21장. 신뢰할 수 있는 메시징 활성화 을 참조하십시오.

64장. 인터셉터 공급자

64.1. 개요

인터셉터 공급자는 Apache CXF 런타임의 인터셉터 체인이 연결된 오브젝트입니다. 모두 org.apache.cxf.interceptor.InterceptorProvider 인터페이스를 구현합니다. 개발자는 고유한 인터셉터를 모든 인터셉터 공급자에 연결할 수 있습니다.

64.2. 공급자 목록

다음 오브젝트는 인터셉터 공급자입니다.

  • AddressingPolicyInterceptorProvider
  • ClientFactoryBean
  • ClientImpl
  • ClientProxyFactoryBean
  • CorbaBinding
  • CXFBusImpl
  • org.apache.cxf.jaxws.EndpointImpl
  • org.apache.cxf.endpoint.EndpointImpl
  • ExtensionManagerBus
  • JAXRSClientFactoryBean
  • JAXRSServerFactoryBean
  • JAXRSServiceImpl
  • JaxWsClientEndpointImpl
  • JaxWsClientFactoryBean
  • JaxWsEndpointImpl
  • JaxWsProxyFactoryBean
  • JaxWsServerFactoryBean
  • JaxwsServiceBuilder
  • MTOMPolicyInterceptorProvider
  • NoOpPolicyInterceptorProvider
  • ObjectBinding
  • RMPolicyInterceptorProvider
  • ServerFactoryBean
  • ServiceImpl
  • SimpleServiceBuilder
  • SoapBinding
  • WrappedEndpoint
  • WrappedService
  • XMLBinding

VIII 부. Apache CXF 기능

이 가이드에서는 Apache CXF의 다양한 고급 기능을 활성화하는 방법을 설명합니다.

65장. Cryostat 유효성 검사

초록

Cryostat 유효성 검사는 서비스 클래스 또는 인터페이스에 Java 주석을 추가하여 런타임 제약 조건을 정의할 수 있는 Java 표준입니다. Apache CXF는 인터셉터를 사용하여 이 기능을 웹 서비스 메서드 호출과 통합합니다.

65.1. 소개

65.1.1. 개요

Cryostat 유효성 검사 1.1(#159-349) - 원래의 Cryostat 유효성 검사 1.0(JSR-303) 표준의 진화로, Java 주석을 사용하여 런타임에 확인할 수 있는 제약 조건을 선언할 수 있습니다.https://jcp.org/en/jsr/detail?id=349 주석을 사용하여 Java 코드의 다음 부분에 제약 조건을 정의할 수 있습니다.

  • 8080 클래스의 필드입니다.
  • 메서드 및 생성자 매개변수입니다.
  • 메서드 반환 값을 반환합니다.

65.1.2. 주석이 달린 클래스의 예

다음 예제에서는 몇 가지 표준VLAN 검증 제약 조건을 사용하여 주석이 달린 Java 클래스를 보여줍니다.

// Java
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Max;
import javax.validation.Valid;
...
public class Person {
    @NotNull private String firstName;
    @NotNull private String lastName;
    @Valid @NotNull private Person boss;

    public @NotNull String saveItem( @Valid @NotNull Person person, @Max( 23 ) BigDecimal age ) {
        // ...
    }
}
Copy to Clipboard Toggle word wrap

65.1.3. Cryostat 검증 또는 스키마 검증?

빈 유효성 검사 및 스키마 유효성 검사는 매우 유사합니다. XML 스키마를 사용하여 끝점을 구성하는 것은 웹 서비스 끝점에서 런타임에 메시지의 유효성을 검사하는 잘 설정된 방법입니다. XML 스키마는 들어오고 나가는 메시지에 대한VLAN 검증과 동일한 제약 조건의 많은 부분을 확인할 수 있습니다. 그러나 polkit 유효성 검사는 다음 이유 중 하나 이상에 유용한 대체 방법이 될 수 있습니다.

  • Cryostat 유효성 검사를 사용하면 XML 스키마(예: 코드 우선 서비스 개발의 경우)와 독립적으로 제약 조건을 정의할 수 있습니다.
  • 현재 XML 스키마가 너무 lax인 경우 Cryostat 유효성 검사를 사용하여 더 엄격한 제약 조건을 정의할 수 있습니다.
  • Cryostat 유효성 검사를 사용하면 사용자 지정 제약 조건을 정의할 수 있으며 XML 스키마 언어를 사용하여 정의할 수 없습니다.

65.1.4. 종속 항목

Cryostat Validation 1.1(JSR-349) 표준은 구현이 아닌 API만 정의합니다. 따라서 종속성은 다음 두 부분으로 제공되어야 합니다.

  • 핵심 종속성-VLAN 검증 1.1 API, Java 통합 표현식 언어 API 및 구현을 제공합니다.
  • Hibernate Validator 종속 항목-VLAN 검증 1.1 구현을 제공합니다.

65.1.5. 핵심 종속 항목

Cryostat 검증을 사용하려면 프로젝트의 Maven pom.xml 파일에 다음 코어 종속 항목을 추가해야 합니다.

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <!-- use 3.0-b02 version for Java 6 -->
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <!-- use 3.0-b01 version for Java 6 -->
    <version>3.0.0</version>
</dependency>
Copy to Clipboard Toggle word wrap
참고

javax.el/javax.el-apiorg.glassfish/javax.el 종속 항목은 Java 통합 표현식 언어의 API 및 구현을 제공합니다. 이 표현식 언어는 8080 유효성 검사에 의해 내부적으로 사용되지만 애플리케이션 프로그래밍 수준에서는 중요하지 않습니다.

65.1.6. Hibernate Validator 종속 항목

8080 검증의 Hibernate Validator 구현을 사용하려면 프로젝트의 Maven pom.xml 파일에 다음과 같은 종속 항목을 추가해야 합니다.

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.0.3.Final</version>
</dependency>
Copy to Clipboard Toggle word wrap

65.1.7. OSGi 환경에서 검증 공급자 해결

검증 공급자를 해결하기 위한 기본 메커니즘에는 공급자 리소스를 찾기 위해 classpath를 스캔해야 합니다. 그러나 OSGi(Apache Karaf) 환경의 경우 유효성 검사 공급자(예: Hibernate 유효성 검사기)가 별도의 번들로 패키지되어 애플리케이션 classpath에서 자동으로 제공되지 않기 때문에 이 메커니즘은 작동하지 않습니다. OSGi의 컨텍스트에서 Hibernate 검증기를 애플리케이션 번들에 연결해야 하며 OSGi는 이를 성공적으로 수행하려면 약간의 도움이 필요합니다.

65.1.8. OSGi에서 명시적으로 검증 공급자 구성

OSGi의 컨텍스트에서 자동 검색을 사용하는 대신 검증 공급자를 명시적으로 구성해야 합니다. 예를 들어 공통 검증 기능( “Cryostat 검증 기능”참조)을 사용하여 빈 유효성 검사를 활성화하는 경우 다음과 같이 검증 공급자를 사용하여 구성해야 합니다.

<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature">
    <property name="provider" ref="beanValidationProvider"/>
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

여기서 HibernateValidationProviderResolver 는 Hibernate 검증 공급자를 래핑하는 사용자 지정 클래스입니다.

65.1.9. HibernateValidationProviderResolver 클래스의 예

다음 코드 예제에서는 Hibernate 유효성 검사기를 확인하는 사용자 정의 HibernateValidationProviderResolver 를 정의하는 방법을 보여줍니다.

// Java
package org.example;

import static java.util.Collections.singletonList;
import org.hibernate.validator.HibernateValidator;
import javax.validation.ValidationProviderResolver;
import java.util.List;

/**
 * OSGi-friendly implementation of {@code javax.validation.ValidationProviderResolver} returning
 * {@code org.hibernate.validator.HibernateValidator} instance.
 *
 */
public class HibernateValidationProviderResolver implements ValidationProviderResolver {

    @Override
    public List getValidationProviders() {
        return singletonList(new HibernateValidator());
    }
}
Copy to Clipboard Toggle word wrap

Maven 번들 플러그인을 사용하도록 구성된 Maven 빌드 시스템에서 이전 클래스를 빌드하면 애플리케이션이 배포 시 Hibernate 유효성 검사기 번들에 연결됩니다( 이미 Hibernate 검증기 번들을 OSGi 컨테이너에 배포했다고 가정).

65.2. Cryostat 유효성 검사를 사용하여 서비스 개발

65.2.1. 서비스 주석 처리

65.2.1.1. 개요

Quarkus 유효성 검사를 사용하여 서비스를 개발하는 첫 번째 단계는 관련 검증 주석을 서비스를 나타내는 Java 클래스 또는 인터페이스에 적용하는 것입니다. 검증 주석을 사용하면 서비스가 호출될 때마다 런타임 시 확인되는 메서드 매개변수, 반환 값 및 클래스 필드에 제약 조건을 적용할 수 있습니다.

65.2.1.2. 간단한 입력 매개변수 검증

매개 변수가 간단한 Java 유형인 서비스 메서드의 매개 변수의 유효성을 검사하려면 빈 유효성 검사 API(javax.validation.constraints 패키지)의 제약 조건 주석을 적용할 수 있습니다. 예를 들어 다음 코드 예제에서는 null 속성에 대한 두 매개변수(@NotNull 주석), id 문자열이 \\d+ 정규식(@Pattern 주석)과 일치하는지 여부와 이름 문자열의 길이가 1에서 50 사이의 범위에 있는지 여부를 테스트합니다.

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
...
@POST
@Path("/books")
public Response addBook(
        @NotNull @Pattern(regexp = "\\d+") @FormParam("id") String id,
        @NotNull @Size(min = 1, max = 50) @FormParam("name") String name) {
    // do some work
    return Response.created().build();
}
Copy to Clipboard Toggle word wrap
65.2.1.3. 복잡한 입력 매개변수 검증

복잡한 입력 매개변수(오브젝트 인스턴스)를 검증하려면 다음 예와 같이 @Valid 주석을 매개변수에 적용합니다.

import javax.validation.Valid;
...
@POST
@Path("/books")
public Response addBook( @Valid Book book ) {
    // do some work
    return Response.created().build();
}
Copy to Clipboard Toggle word wrap

@Valid 주석은 자체적으로 제약 조건을 지정하지 않습니다. @Valid 를 사용하여 Book 매개 변수에 주석을 달 때 유효성 검사 엔진에서 Book 클래스의 정의 내에서 확인하도록 효과적으로 지시하여 유효성 검사 제약 조건을 찾도록 지시합니다. 이 예제에서 Book 클래스는 다음과 같이 idname 필드에 대한 검증 제약 조건으로 정의됩니다.

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
...
public class Book {
    @NotNull @Pattern(regexp = "\\d+") private String id;
    @NotNull @Size(min = 1, max = 50) private String name;

    // ...
}
Copy to Clipboard Toggle word wrap
65.2.1.4. 반환 값 검증 (non-Response)

일반 메서드 반환 값(non-Response)에 검증을 적용하려면 메서드 서명 앞에 주석을 추가합니다. 예를 들어 반환 값(@NotNull 주석)을 테스트하고 검증 제약 조건을 재귀적으로 테스트하려면 다음과 같이 get RoleBinding 메서드에 주석을 답니다.

import javax.validation.constraints.NotNull;
import javax.validation.Valid;
...
@GET
@Path("/books/{bookId}")
@Override
@NotNull @Valid
public Book getBook(@PathParam("bookId") String id) {
    return new Book( id );
}
Copy to Clipboard Toggle word wrap
65.2.1.5. 반환 값 검증(응답)

javax.ws.rs.core.Response 오브젝트를 반환하는 메서드에 검증을 적용하려면 응답하지 않는 경우와 동일한 주석을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

import javax.validation.constraints.NotNull;
import javax.validation.Valid;
import javax.ws.rs.core.Response;
...
@GET
@Path("/books/{bookId}")
@Valid @NotNull
public Response getBookResponse(@PathParam("bookId") String id) {
    return Response.ok( new Book( id ) ).build();
}
Copy to Clipboard Toggle word wrap

65.2.2. 표준 주석

65.2.2.1. Cryostat 검증 제약 조건

표 65.1. “Cryostat 유효성 검사를 위한 표준 주석” 은 fields 및 method return values 및 parameters에 대한 제약 조건을 정의하는 데 사용할 수 있는 Cryostat Validation 사양에 정의된 표준 주석을 표시합니다(클래스 수준에서 표준 주석 중 하나가 적용될 수 있음).

Expand
표 65.1. Cryostat 유효성 검사를 위한 표준 주석
주석적용 가능설명

@AssertFalse

부울,부울

주석이 달린 요소가 false 인지 확인합니다.

@AssertTrue

부울,부울

주석이 달린 요소가 true 인지 확인합니다.

@DecimalMax(value=, inclusive=)

BigDecimal,BigInteger,CharSequence,byte,short,int,long 및 primitive type 래퍼s

inclusive=false 인 경우 주석이 달린 값이 지정된 최대값보다 작은지 확인합니다. 그렇지 않으면 값이 지정된 최대값보다 작거나 같은지 확인합니다. value 매개변수는 BigDecimal 문자열 형식의 최대값을 지정합니다.

@DecimalMin(value=, inclusive=)

BigDecimal,BigInteger,CharSequence,byte,short,int,long 및 primitive type 래퍼s

inclusive=false 인 경우 주석이 달린 값이 지정된 최소값보다 큰지 확인합니다. 그렇지 않으면 값이 지정된 최소값보다 크거나 같은지 확인합니다. value 매개변수는 BigDecimal 문자열 형식의 최소값을 지정합니다.

@Digits(integer=, fraction=)

BigDecimal,BigInteger,CharSequence,byte,short,int,long 및 primitive type 래퍼s

주석이 있는 값이 정수 숫자와 분수 소수가 있는 숫자인지 확인합니다.

@Future

java.util.Date, java.util.Calendar

주석이 달린 날짜가 나중에 있는지 확인합니다.

@Max(value=)

BigDecimal,BigInteger,CharSequence,byte,short,int,long 및 primitive type 래퍼s

주석이 지정된 최대값보다 작거나 같은지 확인합니다.

@Min(value=)

BigDecimal,BigInteger,CharSequence,byte,short,int,long 및 primitive type 래퍼s

주석이 지정된 최소값보다 크거나 같은지 확인합니다.

@NotNull

모든 유형

주석이 달린 값이 null 이 아닌지 확인합니다.

@Null

모든 유형

주석이 달린 값이 null 인지 확인합니다.

@Past

java.util.Date, java.util.Calendar

주석이 지정된 날짜가 과거인지 확인합니다.

@Pattern(regex=, flag=)

CharSequence

지정된 플래그가 일치하도록 주석이 달린 문자열이 정규식 regex 와 일치하는지 확인합니다.

@Size(min=, max=)

CharSequence,컬렉션, 및 배열

주석이 있는 컬렉션, 맵 또는 배열의 크기가 minmax (포함) 사이에 있는지 확인합니다.

@Valid

primitive가 아닌 유형

주석이 있는 오브젝트에서 재귀적으로 검증을 수행합니다. 개체가 컬렉션 또는 배열인 경우 요소를 재귀적으로 검증합니다. 오브젝트가 맵이면 값 요소의 유효성이 재귀적으로 검증됩니다.

65.2.3. 사용자 정의 주석

65.2.3.1. Hibernate에서 사용자 정의 제약 조건 정의

8080 검증 API를 사용하여 고유한 사용자 지정 제한 조건 주석을 정의할 수 있습니다. Hibernate 검증기 구현에서 이 작업을 수행하는 방법에 대한 자세한 내용은 Hibernate Validator 참조 가이드의 사용자 지정 제한 조건 생성 장을 참조하십시오.

65.3. Cryostat 유효성 검사 구성

65.3.1. Cryostat-WS 구성

65.3.1.1. 개요

이 섹션에서는 블루프린트 XML 또는 Spring XML에서 정의된 Cryostat-WS 서비스 엔드포인트에서 Cryostat 유효성 검사를 활성화하는 방법을 설명합니다. Cryostat 유효성 검사를 수행하는 데 사용되는 인터셉터는 Cryostat-WS 끝점 및 Cryostat-RS 1.1 엔드 포인트(JAX-RS 2.0 끝점 모두 서로 다른 인터셉터 클래스를 사용)에 공통적으로 사용됩니다.

65.3.1.2. 네임스페이스

이 섹션에 표시된 XML 예제에서는 다음 표에 표시된 것과 같이 블루프린트 또는 Spring에 대해 jaxws 네임스페이스 접두사를 적절한 네임스페이스에 매핑해야 합니다.

Expand
XML 언어네임스페이스

Blueprint

http://cxf.apache.org/blueprint/jaxws

Spring

http://cxf.apache.org/jaxws

65.3.1.3. Cryostat 검증 기능

Cryostat-WS 엔드포인트에서 8080 검증을 활성화하는 가장 간단한 방법은 endpoint에 8080 검증 기능을 추가하는 것입니다. Cryostat 검증 기능은 다음 클래스에 의해 구현됩니다.

org.apache.cxf.validation.BeanValidationFeature
이 기능 클래스의 인스턴스를 Cryostat-WS 끝점(Java API 또는 jaxws:features 하위 요소 jaxws:endpoint in XML)에 추가하면 엔드포인트에서 Cryostat 유효성 검사를 활성화할 수 있습니다. 이 기능은 두 개의 인터셉터를 설치합니다. 들어오는 메시지 데이터의 유효성을 검사하는 인터셉터와 반환 값의 유효성을 검사하는 아웃 인터셉터(기본 구성 매개 변수를 사용하여 인터셉터가 생성되는 위치)를 설치합니다.
65.3.1.4. Cryostat 검증 기능을 사용한 샘플 Cryostat-WS 구성

다음 XML 예제에서는 commonValidationFeature ctlplane을 엔드포인트에 add-WS-WS 기능으로 추가하여 Cryostat-WS 엔드포인트에서 8080 검증 기능을 활성화하는 방법을 보여줍니다.

<jaxws:endpoint xmlns:s="http://bookworld.com"
                serviceName="s:BookWorld"
                endpointName="s:BookWorldPort"
                implementor="#bookWorldValidation"
                address="/bwsoap">
    <jaxws:features>
        <ref bean="commonValidationFeature" />
    </jaxws:features>
</jaxws:endpoint>

<bean id="bookWorldValidation" class="org.apache.cxf.systest.jaxrs.validation.spring.BookWorldImpl"/>

<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature">
    <property name="provider" ref="beanValidationProvider"/>
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

HibernateValidationProviderResolver 클래스의 샘플 구현은 “HibernateValidationProviderResolver 클래스의 예” 에서 참조하십시오. OSGi 환경(Apache Karaf)의 컨텍스트에서 8080 ValidationProvider 만 구성해야 합니다.

참고

컨텍스트에 따라 블루프린트 또는 Spring에 적합한 XML 네임스페이스에 jaxws 접두사를 매핑해야 합니다.

65.3.1.5. 일반적인 Cryostat 검증 1.1 인터셉터

8080 유효성 검사의 구성을 보다 세밀하게 제어하려면 Cryostat 검증 기능을 사용하는 대신 인터셉터를 개별적으로 설치할 수 있습니다. Quarkus 검증 기능 대신 다음 인터셉터 중 하나 또는 둘 다를 구성할 수 있습니다.

org.apache.cxf.validation.BeanValidationInInterceptor
Cryostat-WS(또는 Cryostat-RS 1.1) 엔드포인트에 설치하는 경우 검증 제약 조건에 대해 리소스 메서드 매개 변수의 유효성을 검사합니다. 유효성 검사가 실패하면 javax.validation.ConstraintViolationException 예외를 발생시킵니다. 이 인터셉터를 설치하려면 XML의 jaxws:inInterceptors 하위 요소(또는 XML의 jaxrs: interceptors 하위 요소)를 통해 엔드포인트에 추가합니다.
org.apache.cxf.validation.BeanValidationOutInterceptor
Cryostat-WS(또는 Cryostat-RS 1.1) 엔드포인트에 설치하는 경우 검증 제약 조건에 대해 응답 값을 검증합니다. 유효성 검사가 실패하면 javax.validation.ConstraintViolationException 예외를 발생시킵니다. 이 인터셉터를 설치하려면 XML의 jaxws:outInterceptors 하위 요소(또는 XML의 jaxrs:outInterceptors 하위 요소)를 통해 엔드포인트에 추가합니다.
65.3.1.6. polkit 검증 인터셉터를 사용한 샘플 Cryostat-WS 구성

다음 XML 예제에서는 관련 In interceptor Cryostat 및 Out interceptorctlplane을 엔드포인트에 명시적으로 추가하여 Cryostat-WS 엔드포인트에서 Cryostat 유효성 검사 기능을 활성화하는 방법을 보여줍니다.

<jaxws:endpoint xmlns:s="http://bookworld.com"
                serviceName="s:BookWorld"
                endpointName="s:BookWorldPort"
                implementor="#bookWorldValidation"
                address="/bwsoap">
    <jaxws:inInterceptors>
        <ref bean="validationInInterceptor" />
    </jaxws:inInterceptors>

    <jaxws:outInterceptors>
        <ref bean="validationOutInterceptor" />
    </jaxws:outInterceptors>
</jaxws:endpoint>

<bean id="bookWorldValidation" class="org.apache.cxf.systest.jaxrs.validation.spring.BookWorldImpl"/>

<bean id="validationInInterceptor" class="org.apache.cxf.validation.BeanValidationInInterceptor">
    <property name="provider" ref="beanValidationProvider"/>
</bean>
<bean id="validationOutInterceptor" class="org.apache.cxf.validation.BeanValidationOutInterceptor">
    <property name="provider" ref="beanValidationProvider"/>
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

HibernateValidationProviderResolver 클래스의 샘플 구현은 “HibernateValidationProviderResolver 클래스의 예” 에서 참조하십시오. OSGi 환경(Apache Karaf)의 컨텍스트에서 8080 ValidationProvider 만 구성해야 합니다.

65.3.1.7. CryostatValidationProvider 구성

org.apache.cxf.validation.BeanValidationProvider 는 8080 검증 구현( 검증공급자)을 래핑하는 간단한 래퍼 클래스입니다. 기본 Cryostat ValidationProvider 클래스를 재정의하면 8080 검증 구현을 사용자 지정할 수 있습니다. Cryo statValidationProvider Quarkus를 사용하면 다음 공급자 클래스 중 하나 이상을 덮어쓸 수 있습니다.

javax.validation.ParameterNameProvider
메서드 및 생성자 매개 변수의 이름을 제공합니다. Java reflect API는 메서드 매개 변수 또는 생성자 매개 변수의 이름에 대한 액세스 권한을 부여하지 않으므로 이 클래스가 필요합니다.
javax.validation.spi.ValidationProvider<T>
지정된 유형인 T 에 대한 빈 유효성 검사 구현을 제공합니다. 자체 ValidationProvider 클래스를 구현하면 자체 클래스에 대한 사용자 정의 유효성 검사 규칙을 정의할 수 있습니다.By implementing your own ValidationProvider class, you can define custom validation rules for your own classes. 이 메커니즘을 사용하면 metrics 검증 프레임워크를 효과적으로 확장할 수 있습니다.
javax.validation.ValidationProviderResolver
ValidationProvider 클래스를 검색하고 검색된 클래스 목록을 반환하는 메커니즘을 구현합니다.Implements a mechanism for discovering ValidationProvider classes and returns a list of the discovered classes. 기본 확인자는 classpath에서 ValidationProvider 클래스 목록을 포함해야 하는 META-INF/services/javax.validation.spi. ValidationProvider 파일을 찾습니다.
javax.validation.ValidatorFactory
javax.validation.Validator 인스턴스를 반환하는 팩토리입니다.
org.apache.cxf.validation.ValidationConfiguration
유효성 검사 공급자 계층에서 더 많은 클래스를 재정의할 수 있는 CXF 래퍼 클래스입니다.

Cryostat ValidationProvider 를 사용자 지정하려면 사용자 지정 Cryostat ValidationProvider 인스턴스를 검증 In interceptor의 생성자와 검증 아웃 인터셉터의 생성자에 전달합니다. 예를 들면 다음과 같습니다.

<bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider" />

<bean id="validationInInterceptor" class="org.apache.cxf.validation.BeanValidationInInterceptor">
    <property name="provider" ref="validationProvider" />
</bean>

<bean id="validationOutInterceptor" class="org.apache.cxf.validation.BeanValidationOutInterceptor">
    <property name="provider" ref="validationProvider" />
</bean>
Copy to Clipboard Toggle word wrap

65.3.2. Cryostat-RS 구성

65.3.2.1. 개요

이 섹션에서는 블루프린트 XML 또는 Spring XML에서 정의된 Cryostat-RS 서비스 엔드포인트에서 Cryostat 유효성 검사를 활성화하는 방법을 설명합니다. Cryostat 유효성 검사를 수행하는 데 사용되는 인터셉터는 Cryostat-WS 끝점 및 Cryostat-RS 1.1 엔드 포인트(JAX-RS 2.0 끝점 모두 서로 다른 인터셉터 클래스를 사용)에 공통적으로 사용됩니다.

65.3.2.2. 네임스페이스

이 섹션에 표시된 XML 예제에서는 다음 표에 표시된 것과 같이 블루프린트 또는 Spring에 대해 jaxws 네임스페이스 접두사를 적절한 네임스페이스에 매핑해야 합니다.

Expand
XML 언어네임스페이스

Blueprint

http://cxf.apache.org/blueprint/jaxws

Spring

http://cxf.apache.org/jaxws

65.3.2.3. Cryostat 검증 기능

Cryostat-RS 엔드포인트에서 8080 검증을 활성화하는 가장 간단한 방법은 endpoint에 8080 검증 기능을 추가하는 것입니다. Cryostat 검증 기능은 다음 클래스에 의해 구현됩니다.

org.apache.cxf.validation.BeanValidationFeature
이 기능 클래스의 인스턴스를 XML에서 jaxrs:server 의 jaxrs:features 하위 요소를 통해 (Java API를 통해 또는 jaxrs:features 하위 요소를 통해) 엔드포인트에서 Cryostat 유효성 검사를 활성화할 수 있습니다. 이 기능은 두 개의 인터셉터를 설치합니다. 들어오는 메시지 데이터의 유효성을 검사하는 인터셉터와 반환 값의 유효성을 검사하는 아웃 인터셉터(기본 구성 매개 변수를 사용하여 인터셉터가 생성되는 위치)를 설치합니다.
65.3.2.4. 검증 예외 매퍼

또한 Cryostat-RS 끝점을 사용하려면 유효성 검사 예외를 HTTP 오류 응답에 매핑해야 하는 검증 예외 매퍼 를 구성해야 합니다. 다음 클래스는 Cryostat-RS에 대한 검증 예외 매핑을 구현합니다.

org.apache.cxf.jaxrs.validation.ValidationExceptionMapper
Cryostat-RS 2.0 사양에 따라 검증 예외 매핑 구현: 모든 입력 매개변수 유효성 검사 위반은 HTTP 상태 코드 400 Bad Request 에 매핑되고, 모든 반환 값 검증 위반(또는 내부 유효성 검사 위반)은 HTTP 상태 코드 500 Internal Server Error 에 매핑됩니다.
65.3.2.5. 샘플 Cryostat-RS 구성

다음 XML 예제에서는 commonValidationFeature Cryostat를 Cryostat-RS 기능으로 추가하고 exceptionMapper Cryostat를 Cryostat-RS 공급자로 추가하여 Cryostat-RS 끝점에서 oscap 유효성 검사 기능을 활성화하는 방법을 보여줍니다.

<jaxrs:server address="/bwrest">
    <jaxrs:serviceBeans>
        <ref bean="bookWorldValidation"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <ref bean="exceptionMapper"/>
    </jaxrs:providers>
    <jaxrs:features>
        <ref bean="commonValidationFeature" />
    </jaxrs:features>
</jaxrs:server>

<bean id="bookWorldValidation" class="org.apache.cxf.systest.jaxrs.validation.spring.BookWorldImpl"/>
<beanid="exceptionMapper"class="org.apache.cxf.jaxrs.validation.ValidationExceptionMapper"/>

<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature">
    <property name="provider" ref="beanValidationProvider"/>
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

HibernateValidationProviderResolver 클래스의 샘플 구현은 “HibernateValidationProviderResolver 클래스의 예” 에서 참조하십시오. OSGi 환경(Apache Karaf)의 컨텍스트에서 8080 ValidationProvider 만 구성해야 합니다.

참고

컨텍스트에 따라 블루프린트 또는 Spring에 적합한 XML 네임스페이스에 jaxrs 접두사를 매핑해야 합니다.

65.3.2.6. 일반적인 Cryostat 검증 1.1 인터셉터

RHHI 검증 기능을 사용하는 대신, 선택 옵션으로 useful 검증 인터셉터를 설치하여 검증 구현을 보다 세밀하게 제어할 수 있습니다. Cryostat-RS는 이 목적을 위해 Cryostat-WS와 동일한 인터셉터를 사용합니다. “일반적인 Cryostat 검증 1.1 인터셉터”

65.3.2.7. polkit 검증 인터셉터를 사용한 샘플 Cryostat-RS 구성

다음 XML 예제에서는 관련 In interceptor Cryostat 및 Out interceptorctlplane을 서버 엔드포인트에 명시적으로 추가하여 Cryostat-RS 엔드포인트에서 Cryostat 유효성 검사 기능을 활성화하는 방법을 보여줍니다.

<jaxrs:server address="/">
    <jaxrs:inInterceptors>
        <ref bean="validationInInterceptor" />
    </jaxrs:inInterceptors>

    <jaxrs:outInterceptors>
        <ref bean="validationOutInterceptor" />
    </jaxrs:outInterceptors>

    <jaxrs:serviceBeans>
    ...
    </jaxrs:serviceBeans>

    <jaxrs:providers>
        <ref bean="exceptionMapper"/>
    </jaxrs:providers>
</jaxrs:server>

<bean id="exceptionMapper" class="org.apache.cxf.jaxrs.validation.ValidationExceptionMapper"/>

<bean id="validationInInterceptor" class="org.apache.cxf.validation.BeanValidationInInterceptor">
    <property name="provider" ref="beanValidationProvider" />
</bean>

<bean id="validationOutInterceptor" class="org.apache.cxf.validation.BeanValidationOutInterceptor">
    <property name="provider" ref="beanValidationProvider" />
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

HibernateValidationProviderResolver 클래스의 샘플 구현은 “HibernateValidationProviderResolver 클래스의 예” 에서 참조하십시오. OSGi 환경(Apache Karaf)의 컨텍스트에서 8080 ValidationProvider 만 구성해야 합니다.

65.3.2.8. CryostatValidationProvider 구성

“CryostatValidationProvider 구성” 에 설명된 대로 사용자 정의 CryostatValidationProvider 인스턴스를 검증 인터셉터에 삽입할 수 있습니다.

65.3.3. Cryostat-RS 2.0 구성

65.3.3.1. 개요

Cryostat-RS 1.1과는 달리, Cryostat-WS와 공통 유효성 검사 인터셉터를 공유하는), Cryostat-RS 2.0은 Cryostat-RS 2.0 고유의 전용 검증 인터셉터 클래스에 의존합니다.

65.3.3.2. Cryostat 검증 기능

Cryostat-RS 2.0의 경우 다음 클래스에 의해 구현되는 전용 Cryostat 검증 기능이 있습니다.

org.apache.cxf.validation.JAXRSBeanValidationFeature
이 기능 클래스의 인스턴스를 XML에서 jaxrs:server 의 jaxrs:features 하위 요소(Java API를 통해 또는 jaxrs:features 하위 요소 통해)에 추가하여 Cryostat-RS 2.0 서버 끝점에서 Cryostat 유효성 검사를 활성화할 수 있습니다. 이 기능은 두 개의 인터셉터를 설치합니다. 들어오는 메시지 데이터의 유효성을 검사하는 인터셉터와 반환 값의 유효성을 검사하는 아웃 인터셉터(기본 구성 매개 변수를 사용하여 인터셉터가 생성되는 위치)를 설치합니다.
65.3.3.3. 검증 예외 매퍼

Cryostat-RS 2.0은 Cryostat-RS 1.x와 동일한 검증 예외 매퍼 클래스를 사용합니다.

org.apache.cxf.jaxrs.validation.ValidationExceptionMapper
Cryostat-RS 2.0 사양에 따라 검증 예외 매핑 구현: 모든 입력 매개변수 유효성 검사 위반은 HTTP 상태 코드 400 Bad Request 에 매핑되고, 모든 반환 값 검증 위반(또는 내부 유효성 검사 위반)은 HTTP 상태 코드 500 Internal Server Error 에 매핑됩니다.
65.3.3.4. Cryostat 검증 호출기

기본이 아닌 라이프사이클 정책(예: Spring 라이프사이클 관리 사용)으로 Cryostat-RS 서비스를 구성하는 경우, 엔드포인트 구성에서 jaxrs:invoker 요소를 사용하여 서비스 엔드포인트에서 jaxrs:invoker 요소를 사용하여 org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInvoker 인스턴스를 등록해야 합니다.

Cryostat-RS 서비스 라이프사이클 관리에 대한 자세한 내용은 “Spring XML의 라이프사이클 관리” 을 참조하십시오.

65.3.3.5. Cryostat 검증 기능을 사용한 샘플 Cryostat-RS 2.0 구성

다음 XML 예제에서는 jaxrsValidationFeature Ignition을 Cryostat-RS 기능으로 추가하고 exceptionMapper Cryostat를 a Cryostat-RS 공급자로 추가하여 Cryostat-RS 끝점에서 8080 검증 기능을 활성화하는 방법을 보여줍니다.

<jaxrs:server address="/">
    <jaxrs:serviceBeans>
    ...
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <ref bean="exceptionMapper"/>
    </jaxrs:providers>
    <jaxrs:features>
        <ref bean="jaxrsValidationFeature" />
    </jaxrs:features>
</jaxrs:server>

<bean id="exceptionMapper" class="org.apache.cxf.jaxrs.validation.ValidationExceptionMapper"/>
<bean id="jaxrsValidationFeature" class="org.apache.cxf.validation.JAXRSBeanValidationFeature">
    <property name="provider" ref="beanValidationProvider"/>
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

HibernateValidationProviderResolver 클래스의 샘플 구현은 “HibernateValidationProviderResolver 클래스의 예” 에서 참조하십시오. OSGi 환경(Apache Karaf)의 컨텍스트에서 8080 ValidationProvider 만 구성해야 합니다.

참고

컨텍스트에 따라 블루프린트 또는 Spring에 적합한 XML 네임스페이스에 jaxrs 접두사를 매핑해야 합니다.

65.3.3.6. 일반적인 Cryostat 검증 1.1 인터셉터

8080 유효성 검사의 구성을 보다 세밀하게 제어하려면 polkit 검증 기능을 사용하는 대신 Cryostat-RS 인터셉터를 개별적으로 설치할 수 있습니다. 다음 Cryostat-RS 인터셉터 중 하나 또는 둘 다를 구성합니다.

org.apache.cxf.validation.JAXRSBeanValidationInInterceptor
Cryostat-RS 2.0 서버 끝점에 설치하는 경우 유효성 검사 제약 조건에 대해 리소스 메서드 매개 변수의 유효성을 검사합니다. 유효성 검사가 실패하면 javax.validation.ConstraintViolationException 예외를 발생시킵니다. 이 인터셉터를 설치하려면 XML의 jaxrs:inInterceptors 하위 요소를 통해 엔드포인트에 추가합니다.
org.apache.cxf.validation.JAXRSBeanValidationOutInterceptor
Cryostat-RS 2.0 엔드포인트에 설치하는 경우 검증 제약 조건에 대해 응답 값의 유효성을 검사합니다. 유효성 검사가 실패하면 javax.validation.ConstraintViolationException 예외를 발생시킵니다. 이 인터셉터를 설치하려면 XML의 jaxrs:inInterceptors 하위 요소를 통해 엔드포인트에 추가합니다.
65.3.3.7. polkit 검증 인터셉터를 사용한 샘플 Cryostat-RS 2.0 구성

다음 XML 예제에서는 관련 In interceptor Cryostat 및 Out interceptorctlplane을 서버 엔드포인트에 명시적으로 추가하여 Cryostat-RS 2.0 끝점에서 8080 검증 기능을 활성화하는 방법을 보여줍니다.

<jaxrs:server address="/">
    <jaxrs:inInterceptors>
        <ref bean="validationInInterceptor" />
    </jaxrs:inInterceptors>

    <jaxrs:outInterceptors>
        <ref bean="validationOutInterceptor" />
    </jaxrs:outInterceptors>

    <jaxrs:serviceBeans>
    ...
    </jaxrs:serviceBeans>

    <jaxrs:providers>
        <ref bean="exceptionMapper"/>
    </jaxrs:providers>
</jaxrs:server>

<bean id="exceptionMapper" class="org.apache.cxf.jaxrs.validation.ValidationExceptionMapper"/>

<bean id="validationInInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">
    <property name="provider" ref="beanValidationProvider" />
</bean>

<bean id="validationOutInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor">
    <property name="provider" ref="beanValidationProvider" />
</bean>

<bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider">
    <constructor-arg ref="validationProviderResolver"/>
</bean>

<bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
Copy to Clipboard Toggle word wrap

HibernateValidationProviderResolver 클래스의 샘플 구현은 “HibernateValidationProviderResolver 클래스의 예” 에서 참조하십시오. OSGi 환경(Apache Karaf)의 컨텍스트에서 8080 ValidationProvider 만 구성해야 합니다.

65.3.3.8. CryostatValidationProvider 구성

“CryostatValidationProvider 구성” 에 설명된 대로 사용자 정의 CryostatValidationProvider 인스턴스를 검증 인터셉터에 삽입할 수 있습니다.

65.3.3.9. CryostatRSParameterNameProvider 구성

org.apache.cxf.jaxrs.validation.JAXRSParameterNameProvider 클래스는 javax.validation.ParameterNameProvider 인터페이스의 구현이며, 이 인터페이스는 Cryostat-RS 2.0 끝점 컨텍스트에서 메서드 및 생성자 매개변수 매개변수에 대한 이름을 제공하는 데 사용할 수 있습니다.

법적 공지

Copyright © 2024 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다. 최신 업데이트를 확인하세요.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

Theme

© 2026 Red Hat
맨 위로 이동