应用Jersey2.x建立REST Application

 

应用Jersey2.x建立REST Application

 

背景:遗留系统升级。遗留系统是利用JSF+JaveEE在IBM Websphere上构筑的Web应用。希望改进客户体验,将JSF替换为现代的前台开发技术例如(React.js 或者 Angular或者Vue等),同时对后台提出使用REST API与前台交互。

大的前提:对于后台的升级,希望只替换Control层的部分,而保留business以及DB层的部分。

大的挑战:如何应用Jersey这种JAXRS开发框架实现改方案?

具体实施方案:

第一部分: 导入Jersey2.33框架。

  1. 导入Jersey相关包。

jersey-serverjersey-clientjersey-commonjersey-container-servlet

     2. 修改部署文件web.xml。修改Servlet配置。如下:

<servlet>

  <servlet-name>RestServlet</servlet-name>

  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

  <init-param>

     <param-name>javax.ws.rs.Application</param-name>

     <param-value>配置自定义ResourceConfig </param-value>

  </init-param>

  <load-on-startup>-1</load-on-startup>

</servlet>

 

<servlet-mapping>

  <servlet-name>RestServlet</servlet-name>

  <url-pattern>/*</url-pattern>

</servlet-mapping>

 

      3. 追加您需要的REST Root resource class。例如如下:

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

@Path("helloworld")

public class HelloWorldResource {

@GET

@Produces("text/plain")

    public String getHello() {

        return "Hello World!";

    }

}

 

 

   4. 追加JSON处理。

追加JSON相关依赖包。

jersey-media-json-jackson,jersey-media-json-processing

 

Jersey使用Jackson来处理JSON的序列化与反序列化。

  • 可以根据需要自定义处理日期字段的序列化与反序列化(Jackson默认是使用时间戳表示)
  • 可以过滤掉Null的字段
  • 处理Map(KeyObject,ValueObject)的POJO的序列化/反序列化

以上的技术实现,我们可以通过自定义Jackson ObjectMapper来实现。

//设定序列化/反序列化时日期字段的显示格式。对于JDK1.8新的LocalTime的设定需要引入类似//jackson-datatype-jsr310来支持

objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

//过滤掉Null的字段

objectMpper. setSerializationInclusion(JsonInclude.Include.NON_NULL);

 

更多的ObjectMapper的设定可以参考下以下的官网

https://github.com/FasterXML/jackson

 

关于处理Map(KeyObject,ValueObject)POJO的序列化/反序列化

     a. 针对KeyObject设定自定义序列化/反序列化类。

利用KeyObject.toString()方法,进行KeyObject的序列化。

public class KeyObjectSerializer extends JsonSerializer<PartKey> {

   private final ObjectMapper mapper = new ObjectMapper();

@Override

public void serialize(KeyObject value, JsonGenerator gen, SerializerProvider serializers)

throws IOException {

StringWriter writer = new StringWriter();

mapper.writeValue(writer, value);

gen.writeFieldName(writer.toString());

}

}

自定义反序列化类

public class KeyObjectDeserializer extends KeyDeserializer {

    @Override

    public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {

        // 利用参数Key调用KeyObject的构造函数

        return new KeyObject(key);

    }

}

   b. 在ObjectMapper中注册自定义的序列化/反序列化类。

        SimpleModule simpleModule = new SimpleModule();

        simpleModule.addKeyDeserializer(KeyObject.class, new KeyObjectDeserializer());

        simpleModule.addKeySerializer(KeyObject.class, new KeyObjectSerializer());

        objectMapper.registerModule(simpleModule);

 

5. 追加上传文件功能。

由于使用的Websphere的容器,该容器默认使用Apache CXF实现文件上传。我们很难直接使用Jersey的jersey-media-multipart来实现文件上传。

我们可以利用与Websphere友好的com.ibm.websphere.appserver.api.jaxrs20来实现文件上传。

可以参考如下的文章来实现。

https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_jaxrs_multipart_formdata_from_html.html?view=embed

 

6. 追加统一异常处理。

追加自定义的Provider,来实现统一异常处理。及在REST里抛出自定义异常,Jersey可以返回事先定义好的返回JSON串。

例如:

//自定义异常继承于RuntimeException。在自己的REST类当中可以自己Throw该异常。

public class MyCustomException extends RuntimeException {

    …

}

 

//自定义统一异常处理Provider

@Provider

public class ExceptionMapperClass implements ExceptionMapper<Exception> {

    @Override

    public Response toResponse(Exception e) {

        if (e instanceof MyCustomException) {

             //自定义异常的场合,自定义JSON串,返回  

        } else {

             //自定以异常以外的场合,定义JSON串返回。

        }

 

7. 追加认证功能。

这部分根据选择的认证方式无关,只是利用认证token与Client端交互认证。

具体的实现请参看以下的URL。

https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey

 

第二部分: 清除JSF框架。

由于遗留系统中各个模块(Web,business,Dao等)分别开发且利用web-fragment.xml等情况,需要对各个模块统一去除和测试。

 

关于利用Jersey2.33在JavaEE(EJB, CDI),Websphere(部署容器)开发Tips总结。

Tips1:可以参考jersey2.33的官方例子代码(https://github.com/eclipse-ee4j/jersey/tree/master/examples),但是,请注意这些例子代码是建立于部署在glassfish应用容器的基础上的。如果你的部署环境是glassfish以外的情况,需要自己测试这些例子的使用。这一点在Jersey官方文档中也有提到。(https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/index.html中 4.8.4. Java EE Servers)

 

Tips2:  对于部署环境是Websphere的情况下,导入jersey-media-json-jackson的时候需要在自定义的ResourceConfig类中,显示注册jackson的Provider类----JacksonJsonProvider

具体请参看以下Blog。

https://openliberty.io/blog/2020/11/11/byo-jackson.html

 

Tips3:  Websphere(Liberty18.x)中,如果在Server.xml中导入feature ‘jaxrs-2.1’的情况,

Websphere对于Jaxrs2.1的默认实现是Apach CXF。通过在ResourceConfig类中显示注册Jersey相关资源与provider,已指定应用程序使用Jersey的实现。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值