package org.apache.cxf.phase.PhaseInterceptorChain
public synchronized boolean doIntercept(Message message) {
//循环遍历执行拦截器handleMessage(message);
while (state == State.EXECUTING && iterator.hasNext()) {
try {
Interceptor currentInterceptor = (Interceptor)iterator.next();
if (isFineLogging) {
LOG.fine("Invoking handleMessage on interceptor " + currentInterceptor);
}
//System.out.println("-----------" + currentInterceptor);
currentInterceptor.handleMessage(message);
if (state == State.SUSPENDED) {
// throw the exception to make sure thread exit without interrupt
throw new SuspendedInvocationException();
}
} catch (SuspendedInvocationException ex) {
// we need to resume from the same interceptor the exception got originated from
if (iterator.hasPrevious()) {
iterator.previous();
}
pause();
throw ex;
} catch (RuntimeException ex) {
.................
}
}
return state == State.COMPLETE;
} finally {
CURRENT_MESSAGE.set(oldMessage);
}
}
package org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
public void handleMessage(Message message) {
//message=org.apache.cxf.message.XMLMessage@9c494f43
try {
processRequest(message);
} catch (RuntimeException ex) {
..
}
}
package org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
private void processRequest(Message message) {
....................
OperationResourceInfo ori = null;
...........
MultivaluedMap values = new MetadataMap();
....................
//Process parameters
try {
//解析请求方法的参数列表。
List params = JAXRSUtils.processParameters(ori, values, message);
message.setContent(List.class, params);
} catch (Exception ex) {
..............
}
//Message contains following information: PATH, HTTP_REQUEST_METHOD, CONTENT_TYPE, InputStream.
package org.apache.cxf.jaxrs.utils.JAXRSUtils;
public static List processParameters(OperationResourceInfo ori,
MultivaluedMap values,
Message message)
throws IOException, WebApplicationException {
//得到 请求处理的方法public com.ym.box.data.ReturnData //com.ym.box.LogBoxResource.mobileLog(com.ym.box.data.LogBoxRequest)
Method method = ori.getMethodToInvoke();
//得到请求方法参数类型[class com.ym.box.data.LogBoxRequest]
Class>[] parameterTypes = method.getParameterTypes();
Parameter[] paramsInfo = ori.getParameters().toArray(new Parameter[]{});
Method annotatedMethod = ori.getAnnotatedMethod();
Type[] genericParameterTypes = annotatedMethod == null ? method.getGenericParameterTypes()
: annotatedMethod.getGenericParameterTypes();
Annotation[][] anns = annotatedMethod == null ? null : annotatedMethod.getParameterAnnotations();
List params = new ArrayList(parameterTypes.length);
//循环解析请求方法参数,并得到装配完成的参数对象。
for (int i = 0; i < parameterTypes.length; i++) {
Class> param = parameterTypes[i];
Type genericParam = genericParameterTypes[i];
if (genericParam instanceof TypeVariable) {
genericParam = InjectionUtils.getSuperType(ori.getClassResourceInfo().getServiceClass(),
(TypeVariable>)genericParam);
}
if (param == Object.class) {
param = (Class>)genericParam;
} else if (genericParam == Object.class) {
genericParam = param;
}
Object paramValue = processParameter(param,
genericParam,
anns == null ? new Annotation[0] : anns[i],
paramsInfo[i],
values,
message,
ori);
params.add(paramValue);
}
return params;
}
package org.apache.cxf.jaxrs.utils.JAXRSUtils;
private static Object processParameter(Class> parameterClass,
Type parameterType,
Annotation[] parameterAnns,
Parameter parameter,
MultivaluedMap values,
Message message,
OperationResourceInfo ori)
throws IOException, WebApplicationException {
InputStream is = message.getContent(InputStream.class);
if (parameter.getType() == ParameterType.REQUEST_BODY) {
String contentType = (String)message.get(Message.CONTENT_TYPE);
if (contentType == null) {
org.apache.cxf.common.i18n.Message errorMsg =
new org.apache.cxf.common.i18n.Message("NO_CONTENT_TYPE_SPECIFIED",
BUNDLE,
ori.getHttpMethod());
LOG.fine(errorMsg.toString());
contentType = MediaType.WILDCARD;
}
return readFromMessageBody(parameterClass,
parameterType,
parameterAnns,
is,
MediaType.valueOf(contentType),
ori.getConsumeTypes(),
message);
} else if (parameter.getType() == ParameterType.CONTEXT) {
return createContextValue(message, parameterType, parameterClass);
} else {
return createHttpParameterValue(parameter,
parameterClass,
parameterType,
parameterAnns,
message,
values,
ori);
}
}
package org.apache.cxf.jaxrs.utils.JAXRSUtils;
private static T readFromMessageBody(Class targetTypeClass,
Type parameterType,
Annotation[] parameterAnnotations,
InputStream is,
MediaType contentType,
List consumeTypes,
Message m) throws IOException, WebApplicationException {
//根据请求的contentType 如application/json,application/xml
List types = JAXRSUtils.intersectMimeTypes(consumeTypes, contentType);
MessageBodyReader provider = null;
for (MediaType type : types) {
//选择相应的内容解释器,
//CXF通过JSonProvider对JSon提供支持,默认的Provider采用jettsion进行编码或解码。
//可以配置在xml文件里
provider = ProviderFactory.getInstance(m)
.createMessageBodyReader(targetTypeClass,
parameterType,
parameterAnnotations,
type,
m);
if (provider != null) {
try {
HttpHeaders headers = new HttpHeadersImpl(m);
return provider.readFrom(
targetTypeClass, parameterType, parameterAnnotations, contentType,
headers.getRequestHeaders(), is);
} catch (Exception e) {
throw e;
}
} else {
.............
throw new WebApplicationException(Response.Status.UNSUPPORTED_MEDIA_TYPE);
}
}
return null;
}
//以下是请求的contentType =application/json,我们选择JSONProvider对JSon提供支持的解析方法readFrom
package org.apache.cxf.jaxrs.provider.json.JSONProvider
public T readFrom(Class type, Type genericType, Annotation[] anns, MediaType mt,
MultivaluedMap headers, InputStream is) throws IOException {
//type是用户要解析成的类型,如type=class com.ym.box.data.LogBoxRequest
//genericType是用户要解析成的类型的泛型,没有则为本身。如 class com.ym.box.data.LogBoxRequest
//mt为contentType =application/json的封装
//header 为请求头 如{Accept=[application/json], accept-encoding=[UTF-8], cache-control=[no-cache], //connection=[keep-alive], content-encoding=[utf-8], Content-Length=[655], content-type=[application/json], //host=[localhost:8080], pragma=[no-cache], user-agent=[Apache CXF 2.6.1]}
/**is为输入流,当使用POST请求时,is封装的是请求数据部分,如{"boxId":1000,"boxMobileLogs":[{"appId":111,"createTime":"2014-01-15 15:22:20","installTime":"2014-01-15 15:22:20","packageName":"com.snda.youni"},{"appId":112,"createTime":"2014-01-15 17:22:20","installTime":"2014-01-15 16:22:20","packageName":"com.snda.youni"},{"appId":113,"createTime":"2014-01-15 18:22:20","installTime":"2014-01-15 16:22:20","packageName":"com.snda.youni"}],"ccId":22222,"channelId":10000,"city":"市","fatherChannelId":10000000,"imei":"imei","imsi":"imsi地址","mac":"mac地址","phoneModel":"model","phoneNum":"13760730495","phoneVendor":"MOTO","productCode":"BK","province":"省","statType":4,"totalCnt":3,"versionName":"v12123"}**/
try {
InputStream realStream = getInputStream(type, genericType, is);
if (Document.class.isAssignableFrom(type)) {
W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
copyReaderToWriter(createReader(type, realStream, false), writer);
return type.cast(writer.getDocument());
}
boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(type);
Class> theGenericType = isCollection ? InjectionUtils.getActualType(genericType) : type;
Class> theType = getActualType(theGenericType, genericType, anns);
////原来通过使用JSONProvider提供json支持的话,它走的流程是json-->xml-->object,如果你使用过的JSONProvider的话,
//也许你会对type=class com.ym.box.data.LogBoxRequest有过为了在XML和对象间进行映射的配置,如使用@XmlRootElement,
//网上有讨论如果使用JacksonJaxbJsonProvider对json的支持的话,效率会比JSONProvider高,后期会分析他们的原因。
Unmarshaller unmarshaller = createUnmarshaller(theType, genericType, isCollection);
XMLStreamReader xsr = createReader(type, realStream, isCollection);
Object response = null;
if (JAXBElement.class.isAssignableFrom(type)
|| unmarshalAsJaxbElement
|| jaxbElementClassMap != null && jaxbElementClassMap.containsKey(theType.getName())) {
response = unmarshaller.unmarshal(xsr, theType);
} else {
//这个时候,对象com.ym.box.data.LogBoxRequest@bf470d已经解析,装配完成。
response = unmarshaller.unmarshal(xsr);
}
if (response instanceof JAXBElement && !JAXBElement.class.isAssignableFrom(type)) {
response = ((JAXBElement>)response).getValue();
}
if (isCollection) {
response = ((CollectionWrapper)response).getCollectionOrArray(theType, type,
org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns));
} else {
response = checkAdapter(response, type, anns, false);
}
//进行类型转换object->T,然后返回
return type.cast(response);
} catch (Exception e) {
....
}
// unreachable
return null;
}
//========================================================================================
//如果使用com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider对json的支持的话,对json的解析交给了JacksonJsonProvider
/**
* Method that JAX-RS container calls to deserialize given value.
*/
public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream)
throws IOException
{
AnnotationBundleKey key = new AnnotationBundleKey(annotations);
EndpointConfig endpoint;
synchronized (_readers) {
endpoint = _readers.get(key);
}
// not yet resolved (or not cached any more)? Resolve!
if (endpoint == null) {
ObjectMapper mapper = locateMapper(type, mediaType);
endpoint = EndpointConfig.forReading(mapper, annotations);
// and cache for future reuse
synchronized (_readers) {
_readers.put(key.immutableKey(), endpoint);
}
}
ObjectReader reader = endpoint.getReader();
JsonParser jp = reader.getJsonFactory().createJsonParser(entityStream);
if (jp.nextToken() == null) {
return null;
}
//解析json,转换形式为json->object
return reader.withType(genericType).readValue(jp);
}