resteasy 是java体系中比较成熟的rest框架,也是jax-rs规范的实现之一,dubbox的REST服务框架,就是采用的resteasy实现,近日在实际项目中遇到了几个问题,记录于此:
 
一、如何用fastjson替换默认的jackson
 
默认情况下,resteasy使用jacksonjaxb来实现json及xml格式的序列化。应用启动时,会自动扫描带@Provider的包,找到最合适的provider。fastjson也提供了jax-rs的Provider实现,如果希望使用fastjson来替换默认的jackson,可以按如下步骤操作:
 
1.1、去掉默认的jackson-provider以及jaxb-provider依赖
即:
//    compile 'org.jboss.resteasy:resteasy-jackson-provider:3.0.14.Final'
// compile 'org.jboss.resteasy:resteasy-jaxb-provider:3.0.16.Final'
把这二个依赖jar包去掉,同时记得添加最新的fastjson依赖(1.2.9+版本)
 
1.2、修改web.xml
 <web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name> <context-param>
<param-name>resteasy.resources</param-name>
<param-value>com.cnblogs.yjmyzz.ProductService</param-value>
</context-param> <context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>false</param-value>
</context-param> <context-param>
<param-name>resteasy.providers</param-name>
<param-value>com.alibaba.fastjson.support.jaxrs.FastJsonProvider</param-value>
</context-param> <listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener> <servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping> </web-app>

解释一下:

resteasy.scan.providers:false 是为了防止resteasy自动扫描@Provider的类

resteasy.providers:com.alibaba.fastjson.support.jaxrs.FastJsonProvider 这里指定了使用fastjson来解析json.

 
二、输出非UTF-8编码格式的问题
默认情况下,fastjson是采用UTF-8的,详情见 com.alibaba.fastjson.support.config.FastJsonConfig#FastJsonConfig 源码
     public FastJsonConfig() {

         this.charset = Charset.forName("UTF-8");

         this.serializeConfig = SerializeConfig.getGlobalInstance();
this.parserConfig = new ParserConfig(); this.serializerFeatures = new SerializerFeature[0];
this.serializeFilters = new SerializeFilter[0];
this.features = new Feature[0];
}

所以,就算在REST服务的Procuces里指定了其它编码也没用

@Path("/product")
@Produces({"application/json; charset=GBK"})
public class ProductService {
//...
}

解决办法:又到了我大OOP出场的时候

package com.cnblogs.yjmyzz;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig; import java.nio.charset.Charset; /**
* Created by 菩提树下的杨过(http://yjmyzz.cnblogs.com/) on 2017/4/24.
*/
public class FastJsonConfigGBK extends FastJsonConfig { public FastJsonConfigGBK() {
super();
setCharset(Charset.forName("GBK"));
setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
}
}

从FastJsonConfig派生出一个默认编码为GBK的子类FastJsonConfigGBK,然后再来一个

package com.cnblogs.yjmyzz;

import com.alibaba.fastjson.support.jaxrs.FastJsonProvider;

/**
* Created by 菩提树下的杨过(http://yjmyzz.cnblogs.com/) on 2017/4/24.
*/
public class FastJsonProviderGBK extends FastJsonProvider { public FastJsonProviderGBK() {
super();
setFastJsonConfig(new FastJsonConfigGBK());
}
}

最后在web.xml中,参考下面调整:

    <context-param>
<param-name>resteasy.providers</param-name>
<param-value>com.cnblogs.yjmyzz.FastJsonProviderGBK</param-value>
</context-param>

大功告成。

 
三、405 Method Not Allowed无响应信息的处理
resteasy有一套默认的异常处理机制,但默认情况下并未处理405状态的异常,见下表:
Exception HTTP Code Description
ReaderException 400 All exceptions thrown from MessageBodyReaders are wrapped within this exception. If there is no ExceptionMapper for the wrapped exception or if the exception isn't a WebApplicationException, then resteasy will return a 400 code by default.
WriterException 500 All exceptions thrown from MessageBodyWriters are wrapped within this exception. If there is no ExceptionMapper for the wrapped exception or if the exception isn't a WebApplicationException, then resteasy will return a 400 code by default.
o.j.r.plugins.providers.jaxb.JAXBUnmarshalException 400 The JAXB providers (XML and Jettison) throw this exception on reads. They may be wrapping JAXBExceptions. This class extends ReaderException
o.j.r.plugins.providers.jaxb.JAXBMarshalException 500 The JAXB providers (XML and Jettison) throw this exception on writes. They may be wrapping JAXBExceptions. This class extends WriterException
ApplicationException N/A This exception wraps all exceptions thrown from application code. It functions much in the same way as InvocationTargetException. If there is an ExceptionMapper for wrapped exception, then that is used to handle the request.
Failure N/A Internal Resteasy. Not logged
LoggableFailure N/A Internal Resteasy error. Logged
DefaultOptionsMethodException N/A If the user invokes HTTP OPTIONS and no JAX-RS method for it, Resteasy provides a default behavior by throwing this exception

所以,如果有一个方法,仅允许POST提交,但是用GET请求来访问时,没有任何响应,包括错误码,大多数情况下这不是问题,但是如何用一些url监管系统来检测url是否可访问时,由于没有任何响应,会认为该url无效。

解决办法:自己定义异常处理ExceptionHandler,参考以下代码:
 package com.cnblogs.yjmyzz;

 import javax.ws.rs.NotAllowedException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider; /**
* Created by yangjunming on 2017/4/26.
*/
@Provider
public class RestExceptionHandler implements ExceptionMapper<NotAllowedException> { @Override
public Response toResponse(NotAllowedException e) {
Response response = Response.status(Response.Status.METHOD_NOT_ALLOWED).entity(e.getMessage()).build();
response.getHeaders().add("Content-Type", "text/plain");
return response;
}
}

然后在web.xml把这个加上

     <context-param>
<param-name>resteasy.providers</param-name>
<param-value>com.cnblogs.yjmyzz.FastJsonProviderGBK,com.cnblogs.yjmyzz.RestExceptionHandler</param-value>
</context-param>
参考文章:
http://docs.jboss.org/resteasy/docs/3.1.2.Final/userguide/html_single/#builtinException

resteasy经验谈的更多相关文章

  1. Android App的设计架构:MVC,MVP,MVVM与架构经验谈

    相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...

  2. 【转】App架构设计经验谈:接口的设计

    App架构设计经验谈:接口的设计 App与服务器的通信接口如何设计得好,需要考虑的地方挺多的,在此根据我的一些经验做一些总结分享,旨在抛砖引玉. 安全机制的设计 现在,大部分App的接口都采用REST ...

  3. RestEasy 3.x 系列之四:使用Hibernate_Validator进行数据校验

    使用Hibernate_Validator进行数据校验,好处不言而喻:规范统一,低耦合度. 1.pom.xml <dependency> <groupId>org.hibern ...

  4. RestEasy 3.x 系列之三:jsonp

    跨域请求解决方法(JSONP, CORS)提到解决跨域可以使用jsonp,RestEasy自带jsonp的拦截器 一.RestEasy的文档如下: If you're using Jackson, R ...

  5. RestEasy 3.x 系列之一:Hello world

    RestEasy 3.x改了不少,走了好多弯路才终于搞出来,做做笔记,陆续发布…… tomcat-7.0.50 java version "1.7.0_51" myeclipse ...

  6. Django实际站点项目开发经验谈

    开发了两个月的Django站点正式上线了,看着网站从无到有,从前端到后台,从本地开发到环境部署,一点一滴的堆砌成型,着实带给我不小的乐趣. Django站点介绍: 开发环境:阿里云服务器centos6 ...

  7. 开发者经验谈:如何一天时间搞定iOS游戏开发?

    开发者经验谈:如何一天时间搞定iOS游戏开发? 在一天时间里将完成iPhone游戏开发由梦想变为现实? 本文作者给出了从创意转变成现实的详细答案.使用苹果原生游戏引擎SpriteKit,遵循一定的原则 ...

  8. 使用 RestEasy 和 Apache Tomcat 构建 RESTful Web 服务

    第一次,用这个RestEasy框架,用的时候,总是提示,404的错误,郁闷,呵呵,不过经过努力,终于解决问题,特别留个标记. 关于404的错误,上网找了一大堆,也还不行. 我感觉应该是lib下面架包的 ...

  9. RestEasy简介

    RestEasy简介 RestEasy技术说明 简介 RESTEasy RESTEasy是JBoss的一个开源项目,提供各种框架帮助你构建RESTful Web Services和RESTful Ja ...

随机推荐

  1. OnContextMenu事件(转)

    用oncontextmenu事件单禁用右键菜单 一个页面中,BODY中用oncontextmenu='return false'来取消鼠标右键:在JS中设置oncontextmenu='return ...

  2. CSS的力量:用一个DIV画图

    这些图片都是用一个DIV绘制出来的,其实原理并不复杂. 这些图片都是由CSS绘制出来的,通过background-image叠加实现, 如蘑菇头的实现,通过 radial-gradient 径向渐变  ...

  3. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

  4. Servlet笔记9--转发与重定向

    关于Web中资源跳转的问题: 转发和重定向基本代码: package com.bjpowernode.javaweb; import java.io.IOException; import javax ...

  5. 用《舌尖2》去理解C#中的多态和开闭原则

    昨天晚上看了<舌尖上的中国2>第一集,特别的感人,尤其是看到帮别人割麦子的麦客,一亩地开价200,雇主只肯给100,脸上的那种纠结和无可奈何.还有长着大眼睛的跳跳鱼,很可爱,不过最终还是被 ...

  6. python3之模块io使用流的核心工具

    1.io概叙 io模块提供了python用于处理各种类型I/O的主要工具,主要有三种类型的I/O:文本I/O,二进制I/O和原始I/O:这些都是通用类型,各种后备存储可使用其中的每一种类型,所以这些类 ...

  7. easyui tree:根据属性格式化树节点名称

    $('#resourceTree').tree({ method : 'post', animate : true, onContextMenu : function(e, node) { e.pre ...

  8. 二、vue中组件的使用

    1.组件拆分 1.组件实质上也是一个vue实例,因此组件中也可以使用vue的对象属性,反过来每一个vue实例也是一个vue组件(注:1.唯一不同的是el是根实例的特有选项,2.组件中的data必须是一 ...

  9. XShell 使用方法

    XShell是一款Windows下非常优秀的远程连接Linux主机的工具,是平常使用不可缺少的工具.复制和粘贴由于在linux的Shell下,Ctrl+c是中断当前指令,这个快捷键和win系统下的复制 ...

  10. 【转】如何使用MAT分析内存泄漏

    原文链接:http://www.lightskystreet.com/2015/09/01/mat_usage/ MAT - Memory Analyzer Tool 使用进阶 Sep 1, 2015 ...