English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Web Service 운영 원리에 대한 자세한 설명

     청명 소长假을 이용하여 Web Service 관련 내용을 되새기고, 작업 원리에 대한 간단한 요약을 수행했습니다. 필요한 친구와 자신의 미래 참고를 위해 제공합니다. 문서에 문제가 있다면, 친구들께 귀중한 의견을 부탁드립니다. 함께 성장하기를 바랍니다.

      Web 서비스에서는 먼저 관련 용어의 의미를 이해해야 합니다: WSDL, UDDI 등. 관련 용어에 대한 설명은 여기서 다루지 않으며, 원리에 중점을 둡니다.
Web 서비스에서는 세 가지 역할이 존재합니다: 서비스 제공자, 서비스 요청자, 서비스 중개자로, 이 세 가지 역할의 관계는 다음 그림과 같습니다1-1그림

    완전한 Web 서비스 구현에는 다음 단계가 포함됩니다:

   ◆ Web 서비스 제공자는 Web 서비스를 설계하고 구현한 후, 테스트 및 디버깅이 완료된 Web 서비스를 Web 서비스 중개자를 통해 발표하고, UDDI 등록 센터에 등록합니다;(발표)

   ◆ Web 서비스 요청자는 특정한 서비스를 Web 서비스 중개자에게 요청하며, 중개자는 요청을 기반으로 UDDI 등록 센터를 조사하여 요청자에게 필요한 서비스를 찾습니다;(발견)

   ◆ Web 서비스 중개자는 조건을 만족하는 Web 서비스 설명 정보를 Web 서비스 요청자에게 반환하며, 이 설명 정보는 WSDL로 작성되어, 다양한 Web 서비스를 지원하는 기계가 모두 읽을 수 있습니다;(발견)

   ◆ Web 서비스 중개자에서 반환된 설명 정보(WSDL)를 기반으로 SOAP 메시지를 생성하고, Web 서비스 제공자에게 보내어 Web 서비스 호출을 실현합니다;(바인딩)

   ◆ Web 서비스 제공자는 SOAP 메시지를 기반으로 해당 Web 서비스를 수행하고, 서비스 결과를 Web 서비스 요청자에게 반환합니다. (바인딩)

  

그림1-1 Web 서비스 아키텍처

     주의: WSDL의 역할은 Web 서비스 설명서입니다. 서비스 요청자는 이 WSDL을 기반으로 SOAP 메시지를 생성하고, 서비스 제공자는 SOAP 요청 메시지를 수신하여 서비스 바인딩을 수행합니다.

     다음은 web.xml에서 servlet 설정에 사용되는 코드입니다

  <!-- 서블릿이나 JSP 페이지에 초기화 파라미터나 정의된 URL을 설정할 때, 먼저 서블릿이나 JSP 페이지를 명명해야 합니다. Servlet 요소는 이 작업을 수행하기 위한 것입니다. -->
  <servlet>
  <servlet-name>UserService</servlet-name>
  <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
  <!-- 서버가 시작될 때 바로 이 servlet을 로드할지 여부를 설명하는 태그입니다(实例화 및 init() 메서드 호출; 정수의 값이 작을수록 servlet의 우선순위가 높고, 애플리케이션 시작 시 더 먼저 로드됩니다 -->
  <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- 서버는 일반적으로 servlet에 기본 URL을 제공합니다: http://host/webAppPrefix/servlet/ServletName을 사용합니다.
   하지만, 종종 이 URL을 변경하여 servlet이 초기화 파라미터에 접근하거나 상대 URL을 처리하기 더 쉽게 할 수 있습니다. 기본 URL을 변경할 때는 servlet-mapping 요소. -->
  <servlet-mapping>
   <servlet-name>UserService</servlet-name>
   <!-- Web 애플리케이션의 루트 디렉토리에 대한 URL을 설명합니다. url-pattern 요소의 값은 슬래시(/)로 시작해야 합니다./)시작입니다。 -->
   <url-pattern>/user</url-pattern>
  </servlet-mapping>
  빨간 코드 부분은 매우 중요하며, 웹 컨테이너가 시작될 때 해당 서블릿을 로드합니다. 녹색 부분은 이 서비스의 외부 인터페이스입니다. 이를 통해 해당 jax-ws.xml 파일(다음과 같이 표시됩니다)
  <endpoint name="UserPort" implementation="cn.ujn.service.UserService"
    url-pattern="/user">
  </endpoint>

    그리고 관련 구현 클래스 cn.ujn.service.UserService에 바인딩됩니다. 클라이언트가 보낸 SOAP 요청 메시지 본문에는 클라이언트가 요청하는 메서드 이름과 파라미터 정보가 포함됩니다.

    이하의 클라이언트가 래핑한 soap 메시지 본문(Json 방식으로 서버와 데이터 전송)(SOAP 요청 래핑)입니다:

  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ujn.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <soapenv:Body>
-  <q0:login>
     <arg0>{"username":"shq","password":"shq"}</arg0>
 </q0:login>
 </soapenv:Body>
 </soapenv:Envelope>

以下为SOAP1.1协议调用Web服务

/** 
* 通过SOAP1.1协议调用Web服务 
* 
* text/xml 这是基于soap1.1协议 
* 
* @param wsdl WSDL路径 
* @param method方法名 
* @param namespace命名空间 
* @param headerParameters 头参数 
* @param bodyParameters  体参数 
* @param isBodyParametersNS 体参数是否有命名空间 
* @return String 
* @throws Exception 
*/ 
public static String invokeBySoap11(String wsdl, String method, 
String namespace, Map<String, String> headerParameters, 
Map<String, String> bodyParameters, boolean isBodyParametersNS) 
throws Exception { 
StringBuffer soapOfResult = null; 
// 去除 ?wsdl,获取方法列表 
int length = wsdl.length(); 
wsdl = wsdl.substring(0, length - 5; 
//以字符串为参数创建URL实例 
URL url = new URL(wsdl); 
//创建连接 
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
//设置请求方式 
conn.setRequestMethod("POST"); 
//如果打算使用 URL连接进行输入,则将 DoInput 标志设置为 true 
conn.setDoInput(true); 
//如果打算使用 URL连接进行输出,则将 DoInput 标志设置为 true 
conn.setDoOutput(true); 
//主要是设置HttpURLConnection请求头里面的属性(K-V) 
conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); 
//客户端相对的输入流获取(使用的是OutputStream)} 
OutputStream out = conn.getOutputStream(); 
// SOAP 가져오기1.1버전 메시지 
StringBuilder sb = new StringBuilder(); 
sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"  
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "); 
sb.append("xmlns:ns0=\"" + 네임스페이스 + "\""); 
sb.append(>"); 
//메시지 헤더 구성 
if (headerParameters != null) { 
sb.append("<soap:Header>"); 
for (Entry<String, String> headerParameter : headerParameters 
.entrySet()) { 
sb.append("<ns0:"); 
sb.append(headerParameter.getKey()); 
sb.append(>"); 
sb.append(headerParameter.getValue()); 
sb.append("</ns0: 
sb.append(headerParameter.getKey()); 
sb.append(>"); 
} 
sb.append("</soap:Header> 
} 
//메시지 본체 구성 
sb.append("<soap:Body><ns0:"); 
sb.append(method); 
sb.append(>"); 
// 입력 매개변수 
if (bodyParameters != null) { 
for (Entry<String, String> inputParameter : bodyParameters 
.entrySet()) { 
if (isBodyParametersNS) { 
sb.append("<ns0:"); 
sb.append(inputParameter.getKey()); 
sb.append(>"); 
sb.append(inputParameter.getValue()); 
sb.append("</ns0: 
sb.append(inputParameter.getKey()); 
sb.append(>"); 
} else { 
sb.append("<"); 
sb.append(inputParameter.getKey()); 
sb.append(>"); 
sb.append(inputParameter.getValue()); 
sb.append("</"); 
sb.append(inputParameter.getKey()); 
sb.append(>"); 
} 
} 
} 
sb.append("</ns0: 
sb.append(method); 
sb.append("></soap:Body></soap:Envelope> 
//테스트용 
System.out.println(sb.toString()); 
//写入SOAP消息(相对于客户端来说,使用的是out.write()) 
out.write(sb.toString().getBytes()); 
//获取服务器端的相应 
int code = conn.getResponseCode(); 
if (code == 200) { 
InputStream is = conn.getInputStream(); 
byte[] b = new byte[1024 
int len = 0; 
soapOfResult = new StringBuffer(); 
//입력 스트림에서 특정 수의 바이트를 읽어 그를 버퍼 배열 b에 저장합니다. 실제로 읽은 바이트 수를 정수로 반환합니다 
//입력 스트림의 끝에 위치해 있어서 더 이상 사용할 수 있는 바이트가 없을 경우 반환 값 -1; 
while ((len = is.read(b)) != -1) { 
//byte 배열을 문자열로 변환하는 데 사용되는 이름이 있는 캐릭터셋을 사용합니다.  
String s = new String(b, 0, len, "UTF-8"); 
soapOfResult.append(s); 
} 
} 
conn.disconnect(); 
return soapOfResult == null ? null : soapOfResult.toString(); 
} 

    주의: 클라이언트가 SOAP 요청 메시지를 보낸 후 블록 상태가 됩니다. 서버가 상태 코드를 반환할 때까지 기다립니다.

    서버가 응답하는 내용(SOAP Response Envelope) 다음과 같습니다:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
-<S:Body>
-<ns2:loginResponse xmlns:ns2="http://ujn.cn/">
 <return>1</return>
</ns2:loginResponse>
 </S:Body>
</S:Envelope>

    클라이언트가 서버에서 보낸 Json 데이터를 수신한 후에 필요한 해석 작업을 수행합니다. 예를 들어:

// SOAP 프로토콜을 해석합니다(DOM 해석은 XML 문서 타입에만 사용가능하며, SOAP 메시지는 XML 데이터 형식을 사용합니다) 
Document doc = XmlUtil.string2Doc(result);}} 
Element ele = (Element) doc.getElementsByTagName("return").item(0); 
메서드에서 사용하는 string2Doc() 메서드 본문은 다음과 같습니다: 
public static Document string2Doc(String str) { 
//XML 문서를 DOM 트리로 파싱합니다. 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
Document document = null; 
DocumentBuilder build; 
if (str == null || str.equals("")) { 
return null; 
} 
try { 
InputStream bais = new ByteArrayInputStream(str.getBytes("UTF");-8")); 
build = factory.newDocumentBuilder(); 
//해당 InputStream의 내용을 XML 문서로 파싱하고 새로운 DOM Document 객체를 반환합니다.  
document = build.parse(bais); 
} catch (Exception e) { 
e.printStackTrace(); 
} 
return document; 
} 

    반환 결과에 따라 클라이언트가 필요한 처리를 수행합니다.

    위는 웹 서비스의 기본 작동 원리입니다.

    읽어 주셔서 감사합니다. 많은 도움이 되길 바랍니다. 여러분의 사이트 지원에 감사합니다!

추천 합니다