SPRING-REST和CXF-REST实现过程中的系列问题

1、mybatis 数字用$,字符用#

2、cxf 关于JSONProvider 返回单个对象数组的问题。
app-rest.xml配置

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" 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.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd">

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

<util:list id="jsonKeys">
<value>app</value>
<value>comment</value>
</util:list>

<util:list id="jsonTypes">
<value>application/json</value>
<value>application/jettison</value>
</util:list>

<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider">
<property name="arrayKeys" ref="jsonKeys" />
<property name="serializeAsArray" value="true" />
<property name="produceMediaTypes" ref="jsonTypes" />
<property name="consumeMediaTypes" ref="jsonTypes" />
</bean>

<jaxrs:server id="commonsService" address="/">
<jaxrs:extensionMappings>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
<jaxrs:serviceBeans>
<ref bean="commentsServiceImpl" />
<ref bean="userServiceImpl" />
<ref bean="postServiceImpl" />
<ref bean="contentRestImpl" />
<ref bean="collectListRestImpl" />
<ref bean="downloadListRestImpl" />
<ref bean="rankServiceRestImpl" />
<ref bean="appAddImpl" />
<ref bean="appPush" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jsonProvider" />
</jaxrs:providers>
</jaxrs:server>
</beans>

javabean代码

import java.io.Serializable;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

import sgh.comment.base.model.Comments;

//评论列表
@XmlAccessorType(XmlAccessType.FIELD)
public class CommentsResult implements Serializable {

private static final long serialVersionUID = -6304211106650057160L;

/**
* 总条数
*/
public Integer totalCount;

/**
* 总页数
*/
public Integer totalPage;

/**
* APP评论
*/
@XmlElement(name="comment")
public List<Comments> commentList;
}

相关源代码参见截图:
[img]http://dl.iteye.com/upload/attachment/0078/2768/422805b7-1f73-3ffe-9dfa-1cdb4cef82bb.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/2770/402fec4b-bc9e-3079-bb33-089d84a3f91b.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/2772/403c419f-13b0-3c32-9a73-4be52fdd0558.png[/img]
备注:
a.arrayKeys和serializeAsArray组合使用,serializeAsArray=true表示arrayKeys中提到的属性值都以数组形式返回,解决单条数据不以数组形式返回的问题。
b.arrayKeys是值需要以数组形式返回的属性名字。如上是comment而不是commentList。

4、cxf关于数字类型的字符串自动被去掉引号的问题。
具体原因参见:org.codehaus.jettison.mapped.DefaultConverter和org.codehaus.jettison.mapped.SimpleConverter
方法1:SimpleConverter的实现去重写DefaultConverter。
方法2:修改配置使其默认用SimpleConverter即可。具体怎么配置目前还不知道。

5、spring mvc rest空对象也被返回的问题。

<property name="defaultViews">
<list>
<!-- for application/json -->
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<!-- 重新设置 objectMapper -->
<property name="objectMapper">
<bean class="org.codehaus.jackson.map.ObjectMapper">
<!-- 设置objectMapper的serializationConfig的serializationInclusion属性,以忽略null对象 ,也可在vo上注解@JsonWriteNullProperties(false)-->
<property name="serializationConfig.serializationInclusion">
<value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
</property>
</bean>
</property>
</bean>

<!-- for application/jsonp -->
<bean class="org.springframework.web.servlet.view.jsonp.MappingJacksonJsonpView">
<!-- 重新设置 objectMapper -->
<property name="objectMapper">
<bean class="org.codehaus.jackson.map.ObjectMapper">
<!-- 设置objectMapper的serializationConfig的serializationInclusion属性,以忽略null对象 ,也可在vo上注解@JsonWriteNullProperties(false)-->
<property name="serializationConfig.serializationInclusion">
<value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
</property>
</bean>
</property>
</bean>

<!-- for application/xml -->
<!--
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller" ref="castorMarshaller" />
</bean>
-->
</list>
</property>


6、spring mvc rest支持jsonp的问题。

<!-- 设置为true以忽略对Accept Header的支持,默认false -->
<property name="ignoreAcceptHeader" value="false" />
<!-- 设置为true以开启对扩展名支持,默认true -->
<property name="favorPathExtension" value="true" />
<!-- 用于开启 /userinfo/123?format=json的支持,默认false -->
<property name="favorParameter" value="true" />
<!-- 在没有扩展名和参数时即: "/user/1" 时的默认展现形式 -->
<property name="defaultContentType" value="application/xml" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
<entry key="jsonp" value="application/javascript"/>
</map>
</property>

重写MappingJacksonJsonpView 类

package org.springframework.web.servlet.view.jsonp;

import org.springframework.web.servlet.view.json.MappingJacksonJsonView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class MappingJacksonJsonpView extends MappingJacksonJsonView {

/**
* Default content type. Overridable as bean property.
*/
public static final String DEFAULT_CONTENT_TYPE = "application/javascript";

@Override
public String getContentType() {
return DEFAULT_CONTENT_TYPE;
}

/**
* Prepares the view given the specified model, merging it with static
* attributes and a RequestContext attribute, if necessary. Delegates to
* renderMergedOutputModel for the actual rendering.
*
* @see #renderMergedOutputModel
*/
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
if ("GET".equals(request.getMethod().toUpperCase())) {
@SuppressWarnings("unchecked")
Map<String, String[]> params = request.getParameterMap();
if (params.containsKey("callback")) {
response.getOutputStream().write(new String(params.get("callback")[0] + "(").getBytes());
super.render(model, request, response);
response.getOutputStream().write(new String(");").getBytes());
response.setContentType("application/javascript");
} else {
super.render(model, request, response);
}
} else {
super.render(model, request, response);
}
}
}


7、cxf rest 支持jsonp的问题。
参见:[url]http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-JSONWithPadding%28JSONP%29[/url]
One option for supporting "JSON With Padding" (JSONP) is to extend the default JSONProvider and override its writeTo method as follows:

@Produces("application/javascript")
class JsonpProvider extends JSONProvider {

@Override
public void writeTo(Object obj, Class<?> cls, Type genericType, Annotation[] anns, MediaType m, MultivaluedMap<String, Object> headers,
OutputStream os) throws IOException {
String prefix = getContext().getHttpServletRequest().getParameter("_jsonp");
boolean hasPrefix = !isEmpty(prefix);
if(hasPrefix) {
os.write(prefix.getBytes(HttpUtils.getSetEncoding(m, headers, "UTF-8")));
os.write('(');
}
super.writeTo(obj, cls, genericType, anns, m, headers, os);
if(hasPrefix) {
os.write(')');
}
}
}

Similar approach can work when Jackson is used.
Alternatively, a custom servlet filter can be used to support JSONP. Please read the Supporting JSONP blog post for more information.
Starting from CXF 2.3.4 and 2.4.0, JSONP can be supported with the help of CXF in/out interceptors:

<jaxrs:server id="bookJsonp" address="/jsonp">
<jaxrs:serviceBeans>
<ref bean="serviceBean" />
</jaxrs:serviceBeans>

<jaxrs:inInterceptors>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpInInterceptor"/>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor"/>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor"/>
</jaxrs:outInterceptors>
</jaxrs:server>

JsonpInInterceptor checks if a JSONP callback query parameter is available (default is _jsonp) and if yes then it saves its value on the current exchange for out interceptors to know if they have to write the paddings or not. The name of the expected callback parameter can be customized. JsonpPreStreamInterceptor and JsonpPostStreamInterceptor ensure the actual JSON stream is 'padded' properly. JsonpPreStreamInterceptor will also set Content-Type to "application/x+javascript" by default but this can be changed:

<jaxrs:server id="bookJsonp" address="/jsonp">
<jaxrs:serviceBeans>
<ref bean="serviceBean" />
</jaxrs:serviceBeans>

<jaxrs:inInterceptors>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpInInterceptor">
<property name="callbackParam" value="myjsonp"/>
</bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor">
<property name="mediaType" value="text/x+javascript"/>
</bean>
<bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor">
<!-- default is ');' -->
<property name="paddingEnd" value=")"/>
</bean>
</jaxrs:outInterceptors>
</jaxrs:server>


8、关于ThreadLocal与线程池的问题。
Web服务器使用线程池,所以会有重用线程的问题,而ThreadLocal是根据线程ID来区分的。
http://blog.csdn.net/comliu/article/details/3186778
http://hi.baidu.com/sqxxr/item/e9946b34427c5ec02e8ec294

9、安装tomcat支持apr

cd /usr/local/apache-tomcat-6.0.18/bin/tomcat-native-1.1.14-src/jni/native/
./configure --prefix=/usr/local/apr
./configure --with-apr=/usr/local/apr
make
make install

http://blog.163.com/chhj_292/blog/static/12229472008101434124476/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值