Java 作为URL参数值的分隔列表

Java 作为URL参数值的分隔列表,java,rest,url,servlets,Java,Rest,Url,Servlets,我有一个现有的JavaWeb应用程序,它有大约50个查询参数,类似于 http://localhost/myapp?a=1&b=2&c=3&d=4 String a = req.getParameter("a"); 我使用ServletRequest.getParameter提取servlet中的值,类似于 http://localhost/myapp?a=1&b=2&c=3&d=4 String a = req.getParameter("

我有一个现有的JavaWeb应用程序,它有大约50个查询参数,类似于

http://localhost/myapp?a=1&b=2&c=3&d=4
String a = req.getParameter("a");
我使用ServletRequest.getParameter提取servlet中的值,类似于

http://localhost/myapp?a=1&b=2&c=3&d=4
String a = req.getParameter("a");
我现有的每个参数都是单值的。我现在需要引入一个新的多值参数。关于RESTful实践和servlet规范,实现这一点的最佳实践是什么

我正在考虑以下两种选择,但如果有更好的选择,请指出

逗号删除单参数 这将被编码为

http://localhost/myapp?a=1&b=2&c=3&d=4&e=5%256%257%258
并提取为

String eStr = req.getParameter("e");
String[] e = eStr.split(",");
String[] e = req.getParameterValues("e");
多参数 它不需要任何特殊的编码,可以作为

String eStr = req.getParameter("e");
String[] e = eStr.split(",");
String[] e = req.getParameterValues("e");
根据,技术上没有定义的规范,所以从技术上讲这两种规范都是正确的,但是有三个原因我会选择
request.getParameterValues(“…”)

  • 代码重用:您编写的每段代码都有可能引入bug(即,在本例中,解析器将从CSV查询字符串中读取)。通常,引入库有一个缺点,即您可能会为一个小函数引入一个重要的依赖项,或者您可能不清楚第三方在其库中做了什么。在本例中,它本质上是一个第1方库,因为它是JavaEE实现本身提供给您的方法!它还提供

  • 意图清晰:任何人在阅读完您的代码后都会熟悉库方法,并立即知道您在做什么

  • URL结构:避免使用定界字符会使URL更易于阅读

  • 既然您提到了RESTful,我认为这里的主要问题是适当地使用查询字符串-避免使用它们在您的网站上提供静态内容页(
    page.html?id=12ndi4t!
    )-但是URL结构是,例如
    search.html?q=film&category=horror&category=comic
    对于搜索页面来说很好&清晰


    getParameterValues(…)
    方法的缺点是没有定义返回值的顺序,因此如果您不能依赖于
    e=5&e=6&e=7
    生成:

    String[] e = request.getParameterValues("e");
    e[0] //5
    e[1] //6
    e[2] //7
    

    如果这一点特别重要,您可能希望采用上述第一种方法。

    最佳做法是使用多个参数

    http://localhost/myapp?a=1&b=2&c=3&d=4&e=5&e=6&e=7&e=8
    
    我们可以以浏览器如何对待选择框和复选框为例:

    http://www.w3.org/TR/html401/interact/forms.html#successful-controls
    
    请注意,规范对排序具有重要意义-“控件名称/值按其在文档中出现的顺序列出”。因此,您可以合理地假设解析库将遵守顺序

    对于您的特定情况,在Java世界中,像SpringMVC这样的框架将理解多参数表单,并为您将其绑定到列表或数组中,这是使用多参数的另一个好处

    http://localhost/myapp?a=1&b=2&c=3&d=4&e=5&e=6&e=7&e=8
    

    在一个更加务实的世界中,答案取决于您的服务将如何使用。由于重复参数名称,使用多个参数会产生开销。如果您的服务一天要被呼叫数十亿次,那么开销就加起来了。

    谢谢您的精彩点评。当我在Tomcat中使用getParameterValues()时,我总是按照查询字符串中的顺序返回值。我不能指望这一点?@dhalsim2我不确定这是以何种方式在幕后实现的——这样做的方式可能会让您始终按顺序检索它们。不过,规范没有明确定义它,所以他们通过API文档向您提供的合同基本上不能保证将来不会更改。更新:我喜欢使用多个参数背后的推理。将我的参数分隔符烘焙到HTTP中,而不是放在HTTP之上,似乎更为优雅。不幸的是,客户端的JavaScript库不能支持同一个键的多个参数,因此我不得不使用一个带分隔符的单个参数。我确实说服了客户开发人员,为了避免编码,我们不应该使用逗号。我们最终使用了tilde~来代替。