Restlet 接受来自客户端的 JSON 输入并响应 POST

Restlet accepts JSON input from client and respond with POST

我正在编写一个程序,它接受来自客户端的具有以下格式的 JSON 输入:

{
    "campaignID": 1,
    "clientID": 1,
    "pmapID": 1,
    "ward": "1-Bedded (Private)",
    "age": 20,
    "attr1": "EXA1(A)",
    "attr2": "EO",
    "attr3": "11/02/2012",
    "attr4": "SIN",
    "attr5": "N",
    "attr6": "Y"
}

我想读取 JSON 输入,将所有属性保存到局部变量(String、int、...)中,最后用 POST("JSON") 这将 return 一个单一的 float/double 值(例如 {"PMC": 30.12} )。

public class RestletApplication extends Application
{
    @Override
    public synchronized Restlet createInboundRoot()
    {
        Router router = new Router(getContext());
        router.attach("/pmc/calculate", PMCResource.class);
        return router;
    }
}

到目前为止我已经编写了该函数,但我不知道如何读取 JSON 输入:

 public class PMCResource extends ServerResource
    {   
        @Post("JSON")
        public Representation post(Representation entity) throws ResourceException {
            try {
                if (entity.getMediaType().isCompatible(MediaType.APPLICATION_JSON))
                {
                    // Read JSON file and parse onto local variables

                    // Do processing & return a float value

                }
            } catch (Exception e) {
                getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
            }
        }
    }

2016 年 5 月 5 日 - 编辑了资源 class

// Imports

public class PMCResource extends ServerResource
{
    static Logger LOGGER = LoggerFactory.getLogger(PMCResource.class);

    @Override
    @Post("JSON")
    public Representation post(Representation entity) throws ResourceException
    {
        PMCMatrixDAO matrix = new PMCMatrixDAOImpl();
        JsonObjectBuilder response = Json.createObjectBuilder();

        try
        {
            if (entity.getMediaType().isCompatible(MediaType.APPLICATION_JSON))
            {
                InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());

                try (JsonReader reader = Json.createReader(is)) {
                    JsonObject obj = reader.readObject();
                    double result = matrix.calculatePMC(obj);
                    response.add("PMC", result);
                }
            }

        } catch (Exception e) {
            getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
        }

        return new StringRepresentation(response.build().toString());
    }
}

实施class

public class PMCMatrixDAOImpl implements PMCMatrixDAO
{       
    public double calculatePMC(JsonObject obj) 
    {   
        int campaignID = obj.getInt("campaignID");
        int clientID = obj.getInt("clientID");
        int pmapID = obj.getInt("pmapID");
        String ward = obj.getString("ward");
        int age = obj.getInt("age");
        String attr1 = obj.getString("attr1");
        String attr2 = obj.getString("attr2");
        String attr3 = obj.getString("attr3");
        String attr4 = obj.getString("attr4");
        String attr5 = obj.getString("attr5");
        String attr6 = obj.getString("attr6");

        // SQL processing
        double dPMC = sqlQueryCall(...);

        return dPMC;
    }
}

为了解析您的 JSON 文件,并且由于您使用的是 Maven,我假设您将它放在 class 路径中,您可以使用 FileInputStreamFileReader。因此,假设您的 JSON 文件名为 input.json 并且它位于 src/main/resources 的根目录中文件夹,您可以通过以下方式加载它:

  • 使用 FileInputStream:

    InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());
    
    try (JsonReader reader = Json.createReader(is)) {
        // file processing is done here
    }
    
  • 使用 FileReader:

    FileReader fr = new FileReader(getClass().getResource("/input.json").getFile());
    
    try (JsonReader reader = Json.createReader(fr)) {
        // file processing is done here
    }
    

好的,现在我们已经创建了 JsonReader,让我们检索 JSON 文件的内容:

InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());

try (JsonReader reader = Json.createReader(is)) {
    JsonObject obj = reader.readObject();

    // retrieve JSON contents
    int campaingID = obj.getInt("campaignID");
    int clientID = obj.getInt("clientID");
    int pmapID = obj.getInt("pmapID");
    String ward = obj.getString("ward");
    int age = obj.getInt("age");
    String attr1 = obj.getString("attr1");
    String attr2 = obj.getString("attr2");
    String attr3 = obj.getString("attr3");
    String attr4 = obj.getString("attr4");
    String attr5 = obj.getString("attr5");
    String attr6 = obj.getString("attr6");
}

作为在方法中使用多个变量的替代方法,您可以创建一个简单的 POJO,将这些变量作为属性,然后 populate it using Jackson:

public class MyPojo {

    private int campaingID;
    private int clientID;
    private int pmapID;
    private String ward;
    private int age;
    private String attr1;
    private String attr2;
    private String attr3;
    private String attr4;
    private String attr5;
    private String attr6;

    // getters & setters
}

最后,为了将响应发送回您的客户端,您可以这样做:

JsonObject response = Json.createObjectBuilder().add("PMC", 30.12).build();

return new StringRepresentation(response.toString());

因此,整个解决方案可能如下所示:

@Override
@Post("JSON")
public Representation post(Representation entity) throws ResourceException {
    JsonObjectBuilder response = Json.createObjectBuilder();

    try {
        if (entity.getMediaType().isCompatible(MediaType.APPLICATION_JSON)) {
            InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());

            try (JsonReader reader = Json.createReader(is)) {
                JsonObject obj = reader.readObject();

                // retrieve JSON contents
                int campaingID = obj.getInt("campaignID");
                int clientID = obj.getInt("clientID");
                int pmapID = obj.getInt("pmapID");
                String ward = obj.getString("ward");
                int age = obj.getInt("age");
                String attr1 = obj.getString("attr1");
                String attr2 = obj.getString("attr2");
                String attr3 = obj.getString("attr3");
                String attr4 = obj.getString("attr4");
                String attr5 = obj.getString("attr5");
                String attr6 = obj.getString("attr6");
            }

            // Do processing & execute your SQL query call here
            double result = sqlQueryCall(...);

            response.add("PMC", result);
        }
    } catch (Exception e) {
        getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
    }

    return new StringRepresentation(response.build().toString());
}

作为旁注,JsonReader class 属于 Java EE API,出于编译目的,它是可以的。虽然,出于 运行 目的,一个 requires 在 Maven 项目中声明 JSON-API 实现依赖项。例如:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.json</artifactId>
    <version>1.0.4</version>
</dependency>

以下是通过客户端与 REST Web 服务通信的方式:

  1. 创建一个简单的 POJO 对象,它将包含要发送的信息,如上所述 (MyPojo)。

  2. 您的 REST 服务看起来像这样:

    public class PMCResource extends ServerResource {
    
        static Logger LOGGER = Logger.getLogger(RestletMain.class.getName());
    
        @Post("JSON")
        public Representation post(MyPojo entity) throws ResourceException {
            PMCMatrixDAO matrix = new PMCMatrixDAOImpl();
            JsonObjectBuilder response = Json.createObjectBuilder();
    
            try {
                double result = matrix.calculatePMC(entity);
                response.add("PMC", result);
            } catch (Exception e) {
                getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
            }
    
            return new StringRepresentation(response.build().toString());
        }
    }
    
  3. 修改您的 PMCMatrixDAOImpl 以处理您的 POJO:

    public double calculatePMC(MyPojo pojo) {
        (...)
    }
    
  4. 创建一个允许您测试 REST 服务的客户端:

    public class PMCResourceMain {
    
        public static void main(String[] args) {
            // take into account the context-root, if exists, and path to your REST service
            ClientResource resource = new ClientResource("http://<host>:<port>");
    
            MyPojo myPojo = new MyPojo();
            myPojo.setCampaingID(1);
            myPojo.setClientID(1);
            myPojo.setPmapID(1);
            myPojo.setWard("1-Bedded (Private)");
            myPojo.setAge(20);
            myPojo.setAttr1("EXA1(A)");
            myPojo.setAttr2("EO");
            myPojo.setAttr3("11/02/2012");
            myPojo.setAttr4("SIN");
            myPojo.setAttr5("N");
            myPojo.setAttr6("Y");
    
            try {
                resource.post(myPojo, MediaType.APPLICATION_JSON).write(System.out);
            } catch (ResourceException | IOException e) {
                e.printStackTrace();
            }
        }
    }
    

可以找到完整的 Restlet 文档 here

为了那些和我遇到同样情况的人的利益,这是我的解决方案:

资源class

@Override
@Post("JSON")
public Representation post(Representation entity) throws ResourceException
{
    PMCMatrixDAO matrix = new PMCMatrixDAOImpl();
    JsonObjectBuilder response = Json.createObjectBuilder();

    try {
        String json = entity.getText(); // Get JSON input from client
        Map<String, Object> map = JsonUtils.toMap(json); // Convert input into Map
        double result = matrix.calculatePMC(map);
        response.add("PMC", result);
    } catch (IOException e) {
        LOGGER.error(this.getClass() + " - IOException - " + e);
        getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
    }

    return new StringRepresentation(response.build().toString());       
}

JSON 转换实用程序 class

public class JsonUtils {

    private static final Logger LOG = LoggerFactory.getLogger(JsonUtils.class);

    private JsonUtils() {
    }

    public static String toJson(Object object) {
        String jsonString = null;

        ObjectMapper mapper = new ObjectMapper();
        try {
            jsonString = mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            LOG.error(e.getMessage(), e);
        }

        return jsonString;
    }

    public static Map<String, Object> toMap(String jsonString) {
        Map<String, Object> map = new ConcurrentHashMap<>();

        ObjectMapper mapper = new ObjectMapper();

        try {
            map = mapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {
            });
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        }

        return map;
    }
}

以及处理所有处理的实现class

public class PMCMatrixDAOImpl implements PMCMatrixDAO
{       
    public double calculatePMC(Map<String, Object> map) 
    {   
        int campaignID  = (int) map.get("campaignID");
        int clientID    = (int) map.get("clientID");
        int pmapID      = (int) map.get("pmapID");
        String ward     = (String) map.get("ward");
        int age         = (int) map.get("age");
        String attr1 = (String) map.get("attr1");
        String attr2 = (String) map.get("attr2");
        String attr3 = (String) map.get("attr3");
        String attr4 = (String) map.get("attr4");
        String attr5 = (String) map.get("attr5");
        String attr6 = (String) map.get("attr6");

        // SQL processing
        double dPMC = sqlQueryCall(...);

        return dPMC;
    }
}