文章出處
文章列表
上一節講解了resteasy如何使用fastjson來替換默認的jackson,雖然dubbox內部采用的就是resteasy,但是大多數情況下,dubbox服務是一個獨立的app,并不需要以war包形式部署在外置容器中,也就沒有web.xml。好在dubbox擴展性不錯,很容易擴展,有此類需求的可以參考下面的做法:
一、rest協議指定fastjson做為序列化
<dubbo:protocol name="rest" port="8080" server="tomcat" contextpath="/" serialization="fastjson" charset="GBK"/>
注意這里的:serialization="fastjson" charset="GBK" 這里指定了采用fastjson作為json序列化的框架,同時字符編碼格式為GBK。
二、修改BaseRestServer源碼
dubbo采用了"URL總線"設計思想,所有服務的信息,最終都拼成一個URL注冊到zk中, com.alibaba.dubbo.rpc.protocol.rest.BaseRestServer的start方法里,可以拿到這些URL的信息,參考以下代碼:
public void start(URL url) { getDeployment().getMediaTypeMappings().put("json", "application/json"); getDeployment().getMediaTypeMappings().put("xml", "text/xml"); getDeployment().getProviderClasses().add(RpcContextFilter.class.getName()); //增加對serialization、charset的解析 楊俊明 2017-04-26 String serialization = url.getParameter("serialization"); if (StringUtils.isNotEmpty(serialization)) { String charset = url.getParameter("charset", "UTF-8"); if (serialization.equals("fastjson")) { getDeployment().setRegisterBuiltin(false); getDeployment().getScannedProviderClasses().clear(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); fastJsonConfig.setCharset(Charset.forName(charset)); FastJsonProvider jsonProvider = new FastJsonProvider(); jsonProvider.setCharset(Charset.forName(charset)); jsonProvider.setFastJsonConfig(fastJsonConfig); ResteasyProviderFactory.getInstance().register(jsonProvider); getDeployment().setProviderFactory(ResteasyProviderFactory.getInstance()); } } getDeployment().getProviderClasses().add(RpcExceptionMapper.class.getName()); loadProviders(url.getParameter(Constants.EXTENSION_KEY, "")); doStart(url); }
上述代碼7-22行,解釋下,如果URL里指定了serialization而且是fastjson,就把默認的其它已經掃描到的provider清空,同時注冊一個FastJsonProvider。為了滿足各種編碼格式的要求,對charset也一并做了解析,并傳遞到FastJsonConfig中。
注:上述代碼已經提交到github的個人dubbox分支,需要的朋友們直接down最新源碼即可。
三、405 Method Not Allowed 等狀態碼的處理
與上一節的處理方式類似,自己擴展一個ExceptionHandler即可,然后在dubbox中參考以下配置:
<dubbo:protocol name="rest" ... extension="xxx.xxx.NotAllowedExceptionHandler,xxx.xxx.NotSupportedExceptionHandler" serialization="fastjson" />
extension這里可以隨意擴展,多個擴展之間用英文逗號分隔即可,讀取extensions的源代碼見com.alibaba.dubbo.rpc.protocol.rest.BaseRestServer#loadProviders
protected void loadProviders(String value) { for (String clazz : Constants.COMMA_SPLIT_PATTERN.split(value)) { if (!StringUtils.isEmpty(clazz)) { getDeployment().getProviderClasses().add(clazz.trim()); } } }
文章列表
全站熱搜