java轻量RESTful api服务搭建(jersey+jetty)

前言

由于开始要搭建一个java + python的服务,java端提供数据库增删改查逻辑供python端调用,第一时间想到了用REST(Representational State Transfer)进行交互

最近这些年,REST已经成为web services和APIs的标准架构,很多APP的架构基本上是使用RESTful的形式了。REST的六个特性:Client-Server:服务器端与客户端分离。 Stateless(无状态):每次客户端请求必需包含完整的信息,换句话说,每一次请求都是独立的。 Cacheable(可缓存):服务器端必需指定哪些请求是可以缓存的。 Layered System(分层结构):服务器端与客户端通讯必需标准化,服务器的变更并不会影响客户端。 Uniform Interface(统一接口):客户端与服务器端的通讯方法必需是统一的。 Code on demand(按需执行代码?):服务器端可以在上下文中执行代码或者脚本?

以下就是我的简单尝试

正文

由于REST服务也是一个web服务,所以需要一个servlet容器。

因为主逻辑还是在java端,所以希望这个REST服务非常轻量,选择一个轻量级的servlet容器很有必要,神马Tomcat、Resin就太重了,所以鼎鼎大名的 jetty 容器就是非常好的选择啦

容器选好了,就再考虑用什么RESTful框架实现咯,由于在java6上已经有了一套RESTful的api,叫:JAX-RS (Java API for RESTful Web Services),但JAX-RS 的具体实现由第三方提供,例如 Sun 的参考实现 Jersey、Apache 的 CXF 以及 JBoss 的 RESTEasy。各项性能比较不错的是Jersey和RESTEasy,各种百度google一番,最后任性的选择了Jersey

工具都选好了,开始干正事了,上代码:

首先配置下maven依赖:

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.19.4</version>
        </dependency>

        <!-- 对象自动转json -->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.19.4</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.19.4</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty.aggregate</groupId>
            <artifactId>jetty-all-server</artifactId>
            <version>8.2.0.v20160908</version>
        </dependency>

再来写java代码:

/**
 * Copyright (C) 2017 The RDT of Wireless R&D in MIG. All right reversed. <p/> Created by vellhe on
 * 2017/7/7
 */

package com.tencent.awake.data.processing.service.rest;

import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.tencent.awake.data.processing.db.mybatis.dao.model.SubTaskInfoPo;
import com.tencent.awake.data.processing.db.mybatis.dao.model.TaskInfoPo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Date;

/**
 * @author vellhe@tencent.com
 * @date 2017/7/7
 * @description 提供REST接口
 */
@Path("/")
public class RestInterface {

  /**
   * 根据id查询任务信息.
   *
   * @param id 任务id
   * @return 任务信息
   */
  @Path("/getTaskInfo/{id}") // 大括号里的是参数名,在函数位置使用@PathParam注解映射
  @GET // 声明这个接口必须GET访问
  @Produces(MediaType.APPLICATION_JSON) // 声明这个接口将以json格式返回
  public TaskInfoPo getTaskInfo(@PathParam("id") int id) {
    TaskInfoPo taskInfoPo = new TaskInfoPo();
    taskInfoPo.setId(id);
    taskInfoPo.setAppId("test");
    return taskInfoPo;
  }

  /**
   * 根据taskInfo查询subTaskInfo.
   *
   * @param taskInfoPo taskInfo
   * @return subTaskInfo
   */
  @Path("/getSubTaskInfo/") // url上没有参数,参数通过body传入
  @POST
  @Consumes(MediaType.APPLICATION_JSON) // 声明传入参数是json格式
  @Produces(MediaType.APPLICATION_JSON)
  public SubTaskInfoPo getSubTaskInfo(TaskInfoPo taskInfoPo) {
    SubTaskInfoPo subTaskInfoPo = new SubTaskInfoPo();
    subTaskInfoPo.setId((int) System.currentTimeMillis());
    subTaskInfoPo.setTaskId(taskInfoPo.getId());
    subTaskInfoPo.setCreateTime(new Date());
    return subTaskInfoPo;
  }

  /**
   * 测试用的main函数.
   */
  public static void main(String[] args) throws Exception {
    Server server = new Server(8282); // 监听8282端口
    ServletHolder servlet = new ServletHolder(ServletContainer.class);
    // 设置初始化参数
    servlet.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
    servlet.setInitParameter("com.sun.jersey.config.property.packages", "com.tencent.awake.data.processing");
    servlet.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true"); // 自动将对象映射成json返回
    ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    handler.setContextPath("/");
    handler.addServlet(servlet, "/*");
    server.setHandler(handler);
    server.start();
    System.out.println("start...in 8282");
  }
}

大部分要说明的东西都在注解里可以找到了,就不一一讲解了,运行后会监听8282端口(代码里),这段demo代码提供了两个接口,所以来看看怎么请求这两个接口吧

我使用PostMan来模拟请求

getTaskInfo

getTaskInfo

getSubTaskInfo

getSubTaskInfo

DONE !!!

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发技术

spring-boot-2.0.3不一样系列之国际化

       针对spring boot,网上已有很多优质的系列教程,我就不再班门弄斧了(实际上是担心没别人写的好,哈哈哈!)。但是还是想蹭蹭spring bo...

4103
来自专栏为数不多的Android技巧

Binder学习指南

毫不夸张地说,Binder是Android系统中最重要的特性之一;正如其名“粘合剂”所喻,它是系统间各个组件的桥梁,Android系统的开放式设计也很大程度上得...

2401
来自专栏王大锤

iOS AFNetworking “Request failed: unacceptable content-type: text/html”问题

4057
来自专栏圣杰的专栏

ABP入门系列(21)——切换MySQL数据库

源码路径:Github-LearningMpaAbp 1. 引言 Abp支持MySql已经不是什么新鲜事了,但按照官方文档:Entity Framework...

2659
来自专栏Java Web

使用RESTful风格开发Java Web

REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移),REST 是一种体系结构,而 HTTP 是一种包...

2235
来自专栏编程坑太多

『高级篇』docker之开发课程EdgeService(16)

PS:微服务跟之前说的一样就是互相通过RPC的方式进行通信,之间有自己的数据库,只是RPC暴露接口的方式来获取其他的微服务之间的数据。

793
来自专栏Ryan Miao

SpringCloud学习5-如何创建一个服务提供者provider

1223
来自专栏haifeiWu与他朋友们的专栏

Netty实战之第一个应用

作为一个正在Java路上摸爬滚打的小菜鸡,之前在项目中也用过Netty,也因为Netty报名阿里的中间件大赛,但终究功力太浅,最终不了了之,最近工作中又遇到了N...

1632
来自专栏向治洪

XMPP客户端库Smack 4.0.6版开发之二

XMPP客户端库Smack 4.0.6版开发之二 三、Smack库的特征 1、极度简单易用,API功能强大 发送一条文本消息给某个用户只需几行代码: Abst...

2185
来自专栏LanceToBigData

JavaWeb(三)JSP概述

一、JSP概述 1.1、JSP简介   一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。JSP是一种Jav...

3226

扫码关注云+社区

领取腾讯云代金券