从Servlet返回数据给Java客户端

8
你好,我遇到了一个问题:如何从Servlet返回数据给Java客户端。这是我第一次使用servlet。我在网上看到的所有示例都是将数据返回到HTML页面,但我想制作一个服务器-客户端软件,其中服务器执行操作并返回一个字符串列表。
我该如何从GET/POST方法中返回一个数组给客户端?在setContentType中应该设置什么?我不明白如何将我想要的信息(例如int,数组,String)放入响应中并返回给客户端。
如果有人能提供一个示例,其中Java客户端发起POST请求,Servlet将一个数组或ArrayList返回给他,我会非常高兴。
5个回答

7
你遇到了序列化问题。序列化是将数据转换为可传输格式的过程。有几种方法可以实现这一点,其中一些在其他答案中提到。
我建议使用JSON作为你的格式。你可以从json.org获取一个不错的Java JSON库。然后你可以使用该库创建一个JSON数组,并将其写入Servlet的OutputStream。
public void service(ServletRequest req, ServletResponse res) {
    final JSONArray arr=new JSONArray();
    for (String s : this.myListOfStrings){
        arr.put(s);
    }
    //Here we serialize the stream to a String.
    final String output = arr.toString();
    res.setContentLength(output.length());
    //And write the string to output.
    res.getOutputStream().write(output.getBytes());
    res.getOutputStream().flush();
    res.getOutputStream().close();
}

现在你可以从客户端发出请求,并像这样获取你的ArrayList:
public ArrayList<String> contactServer(){
    final URL url = new URL(serverURL);
    final URLConnection connection=url.openConnection();
    connection.setDoOutput(true);
    /*
     * ...
     * write your POST data to the connection.
     * ...
     */
    final BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    final char[] buffer=new char[Integer.parseInt(connection.getHeaderField("Content-Length"))];
    int bytesRead=0;
    while (bytesRead < buffer.length){
        bytesRead += br.read(buffer, bytesRead, buffer.length - bytesRead + 1);
    }
    final JSONArray arr = new JSONArray(new String(buffer));
    final ArrayList<String> ret = new ArrayList<String>(arr.length());
    for (int i=0; i<arr.length(); i++) {
        ret.add(arr.get(i));
    }
    return ret;
}

非常感谢!我会尝试。 - Strom

1

看起来你需要一个 RESTful 服务通过 http。你应该选择你想要序列化对象的方式。典型的选择是 JSON - 你将对象序列化为 JSON 并将其写入响应中(使用 Content-Type 设置为 application/json

有一些框架可以做到这一点 - 看看 Spring MVC 或 Jersey/Resteasy

如果你想要更低级别的东西,你可以直接使用 RMI 或 sockets,而不使用 servlet。Servlets 的目的是响应 HTTP 请求,这只能传输文本数据。


我会使用我比较熟悉的RMI,但是我不能这样做,因为那个免费的服务器只有Tomcat的启动、重新加载和停止功能,而对于RMiregistry没有任何支持。 - Strom

0

我认为你最好返回XML或JSON格式的数据,这样客户端生成会更容易。不过,如果不知道你的客户端是什么,就很难提供帮助了。


0

传送本地对象并不容易实现,但JSON是一个便宜的选择。

使用像GSON这样的库来将数据序列化/反序列化为JSON格式。


你可以将servlet响应输出流包装在ObjectOutputStream中并写入对象。这很容易,不是吗? - JB Nizet
@JBNizet 可以将其添加为答案。到目前为止,所有现有的答案都建议使用JSON。 - Sean Patrick Floyd

0

您可以将响应输出流包装在ObjectOutputStream中,并将您的Java对象(必须是可序列化的)写入ObjectOutputStream。在客户端,将输入流包装在ObjectInputStream中,使用readObject,并将结果强制转换为预期的对象类型。

当然,这使得Servlet仅可由使用Java编写且与服务器共享相同类的客户端使用。通常,提供HTTP接口的服务旨在供任何类型的客户端使用,并选择更开放的格式,例如XML或JSON。但如果这正是您所需要的,为什么不使用本地序列化呢?顺便说一下,这就是Spring HttpInvoker所做的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接