Resume Parse Solution(2)SOAP - wsimport

本文介绍如何利用JAX-WS工具中的wsimport命令来生成客户端代码,并通过示例展示了如何调用一个Web服务来解析简历文件。该过程包括处理文件读取、压缩以及与Web服务交互等步骤。
Resume Parse Solution(2)SOAP - wsimport

That is really amazing, that JAX-WS tool is really in $JDK/bin.

After I install ORACLE JDK 1.8 on my MAC OX, I really have wsimport
> which wsimport
/usr/bin/wsimport

Help information
> wsimport -help
Usage: wsimport [options] <WSDL_URI>

How SOAP Works
Usually, we will have a WSDL file which will describe all the services for us.

Let rock and roll to use wsimport to generate that.
> wsimport -keep -verbose -B-XautoNameResolution -s src/main/java/ -p com.sillycat.resumeparse.sovren.ws http://services.resumeparsing.com/ParsingService.asmx?wsdl

Error Message:
[ERROR] A class/interface with the same name "com.resumeparsing.services.ParseJobOrderResponse" is already in use. Use a class customization to resolve this conflict.
line 130 of http://services.resumeparsing.com/ParsingService.asmx?wsdl

Solution:
Add this in the command line
wsimport -keep -verbose -B-XautoNameResolution http://services.resumeparsing.com/ParsingService.asmx?wsdl
That is the solution -B-XautoNameResolution

All the codes will be generated under this directory ws. Then we can write a class to call that.
package com.sillycat.resumeparse.sovren;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPOutputStream;

import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sillycat.resumeparse.ParsingServiceClient;
import com.sillycat.resumeparse.sovren.ws.ParseResumeRequest;
import com.sillycat.resumeparse.sovren.ws.ParseResumeResponse2;
import com.sillycat.resumeparse.sovren.ws.ParsingService;
import com.sillycat.resumeparse.sovren.ws.ParsingServiceSoap;

public class ParsingServiceSovrenJaxWSClient implements ParsingServiceClient {

protected final static Log log = LogFactory
.getLog(ParsingServiceSovrenJaxWSClient.class);

private String accountId;

private String serviceKey;

private String filePath;

private String soapServer;

public void parseResume(String fileName) {

long read_file_start = System.currentTimeMillis();
byte[] bytes = null;
try {
bytes = getBytesFromFile(new File(filePath + fileName));
} catch (IOException e) {
log.error(e,e);
}
long read_file_end = System.currentTimeMillis();

// Optionally, compress the bytes to reduce network transfer time
long gzip_file_start = System.currentTimeMillis();
try {
bytes = gzip(bytes);
} catch (IOException e) {
log.error(e,e);
}
long gzip_file_end = System.currentTimeMillis();
// Get a client proxy for the web service

ParsingService service = null;
try {
service = new ParsingService(new URL(
"https://services.resumeparsing.com/ParsingService.asmx?wsdl"),
new QName("http://services.resumeparsing.com/",
"ParsingService"));
} catch (MalformedURLException e) {
log.error(e,e);
}
ParsingServiceSoap soap = service.getParsingServiceSoap();

// Required parameters

ParseResumeRequest parseRequest = new ParseResumeRequest();
parseRequest.setAccountId(this.getAccountId());
parseRequest.setServiceKey(this.getServiceKey());
parseRequest.setFileBytes(bytes);

long call_api_start = System.currentTimeMillis();
ParseResumeResponse2 parseResult = soap.parseResume(parseRequest);
long call_api_end = System.currentTimeMillis();

log.info("Load the file to Memory, using "
+ (read_file_end - read_file_start) + " ms");
log.info("Zip the file, using " + (gzip_file_end - gzip_file_start)
+ " ms");
log.info("Call the API, using "
+ (call_api_end - call_api_start) + " ms");

log.debug("Code=" + parseResult.getCode());
log.debug("SubCode=" + parseResult.getSubCode());
log.debug("Message=" + parseResult.getMessage());
log.debug("TextCode=" + parseResult.getTextCode());
log.debug("CreditsRemaining="
+ parseResult.getCreditsRemaining());
log.debug("-----");
log.debug(parseResult.getXml());
}

private byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
try {

// Get the size of the file
long length = file.length();

if (length > Integer.MAX_VALUE) {
// File is too large
}

// Create the byte array to hold the data
byte[] bytes = new byte[(int) length];

// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
offset += numRead;
}

// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}

// Return the file content
return bytes;
} finally {
// Close the input stream
is.close();
}
}

private byte[] gzip(byte[] bytes) throws IOException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(
bytes.length / 2);
try {
GZIPOutputStream zipStream = new GZIPOutputStream(byteStream);
try {
zipStream.write(bytes);
} finally {
zipStream.close();
}
return byteStream.toByteArray();
} finally {
byteStream.close();
}
}
…snip...
}


Reference:
http://www.mkyong.com/webservices/jax-ws/jax-ws-hello-world-example/
http://www.mkyong.com/webservices/jax-ws/jax-ws-wsimport-tool-example/
### **关于 `http_parse` 和 `http_parse_header` 的区别** 在 gSOAP 中,`http_parse` 和 `http_parse_header` 是两个不同的回调函数,分别用于处理 **HTTP 消息体(Body)** 和 **HTTP 头部(Header)** 的解析逻辑。以下是它们的核心区别和用途: --- ### **1. `http_parse` (`soap->fparse`)** #### **功能** - **解析 HTTP 消息体(Body)**,例如: - SOAP/XML 消息体。 - JSON 或其他格式的请求/响应数据。 - **触发时机**:在 HTTP 头部解析完成后,处理消息体时调用。 #### **典型场景** - 自定义非标准数据格式的解析(如二进制协议)。 - 修改默认的 SOAP/XML 解析逻辑。 #### **示例** ```c int custom_http_parse(struct soap *soap) { // 读取 HTTP Body 数据(例如自定义二进制协议) char buffer[1024]; if (soap->recv(buffer, sizeof(buffer)) <= 0) { return SOAP_EOF; // 处理错误 } // 解析逻辑... return SOAP_OK; } // 设置自定义 Body 解析器 soap->fparse = custom_http_parse; ``` --- ### **2. `http_parse_header` (`soap->fparsehdr`)** #### **功能** - **解析 HTTP 头部(Header)**,例如: - 标准头(如 `Content-Type`、`Authorization`)。 - 自定义头(如 `X-SessionCookie`)。 - **触发时机**:在接收到 HTTP 请求/响应时,优先解析头部。 #### **典型场景** - 验证或修改 HTTP 头。 - 拦截非法请求(如缺失认证头)。 #### **示例** ```c int custom_http_parse_header(struct soap *soap) { // 检查必须的头部字段 const char *auth = soap->http_header("Authorization"); if (!auth || !validate_token(auth)) { soap->error = 401; // 返回 401 Unauthorized return SOAP_ERR; } return SOAP_OK; // 继续默认头部解析 } // 设置自定义 Header 解析器 soap->fparsehdr = custom_http_parse_header; ``` --- ### **3. 关键区别总结** | **特性** | **`http_parse` (`fparse`)** | **`http_parse_header` (`fparsehdr`)** | |------------------------|------------------------------------------|---------------------------------------------| | **解析目标** | HTTP Body(消息体) | HTTP Header(头部) | | **调用顺序** | 在头部解析完成后调用 | 在接收 HTTP 数据时优先调用 | | **常见用途** | 处理 SOAP/XML/JSON 数据 | 验证/修改头部(如认证、缓存控制) | | **返回值影响** | 决定 Body 是否有效 | 决定是否继续处理请求(如拦截非法请求) | | **默认行为** | gSOAP 内置 SOAP/XML 解析 | gSOAP 内置头部解析(存储到 `soap->http_header`) | --- ### **4. 协作关系** 1. **HTTP 请求到达时**: - 先调用 `fparsehdr` 解析头部(若设置)。 - 再调用 `fparse` 解析 Body(若设置)。 2. **错误处理**: - 若 `fparsehdr` 返回错误(如 `SOAP_ERR`),直接终止请求,**不进入 `fparse`**。 - 若 `fparse` 返回错误,Body 解析失败,但头部仍有效。 --- ### **5. 注意事项** - **性能影响**:覆盖默认解析器可能增加开销,需谨慎实现。 - **协议合规性**:修改解析逻辑时需确保符合 HTTP/SOAP 标准。 - **调试建议**:通过 `soap->fformat` 和 `soap->fparsehdr` 日志辅助排查问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值