java如何解码获取url参数收到抛出BeanParam

时间:2015-10-30 15:37:39

标签: java jersey jax-rs decoding urldecode

我收到对此网络服务的 GET 响应

@GET
@Path("/nnnnnn")
public Response pfpfpfpf(@BeanParam NNNNNN n)

班级NNNNN有:

@QueryParam("parameter")
private String parameter;

对于那个parameter,有一个get和set。

我使用查询参数发送请求,并且它自动绑定到我的选项NNNNN,一切都很棒。

但是,现在我在查询网址中发送日语字符串。我在发送之前用UTF-8对参数进行编码,我必须使用UTF-8对它们进行解码。

但我的问题是哪里我应该调用URLDecoder?我试图在该参数的getter中调用它,但它没有工作,我保持像C3%98%C2%B4%C3%98%C2而不是日语字符

2 个答案:

答案 0 :(得分:4)

对我有用的解决方案是:

在servlet上,我应该这样做:

def GET(self)

然后在html页面上我必须添加:

def GET(self, *args):

答案 1 :(得分:1)

这是一个很好的问题,对于如何在系统之间处理(编码和解码)信息有很多疑问。

在我继续之前,我必须说对Charset,编码等有一个公平的理解。你可能想要阅读this answer快速抬头。

这必须从2个角度来看 - 浏览器和服务器。

编码

的浏览器透视图

每个浏览器都会呈现信息/文本,现在呈现它必须知道如何解释这些位/字节的信息/文本,以便它可以正确呈现(读取我的answer's 3rd bullet如何相同位可以表示不同编码方案中的不同字符)。

浏览器页面编码

  • 每个浏览器都有一个与之关联的默认编码。 Check this on how to see the default encoding of browser
  • 如果您未在HTML页面上指定任何编码,则浏览器的默认编码将生效,并将根据这些编码规则呈现页面。所以,如果默认编码是ASCII,你使用日语或中文或Unicode辅助平面中的字符,那么你会看到垃圾值。
  • 您可以告诉浏览器不使用您的默认编码方案,但使用此网站使用<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">进行渲染。
    • 并且这正是您所做的/找到的并且您没问题,因为此meta标记基本上覆盖了浏览器的默认编码。
    • 达到同样效果的另一种方法是不要使用此元标记,只是更改浏览器的默认编码,但您仍然可以。但不建议这样做,建议在JSP中使用Content-Type元标记。

尝试使用以下简单的HTML播放浏览器默认编码和meta标记。

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        の, は, でした <br></br>
        昨夜, 最高
    </body>        
</html>

编码的服务器透视

服务器也应该知道如何解释传入的数据流,这基本上意味着要使用哪种编码方案(服务器部分是棘手的,因为有几种可能性)。请阅读以下here

  

提交已输入HTML表单的数据时,表单   字段名称和值被编码并以HTTP格式发送到服务器   使用方法GET或POST请求消息,或者历史上通过电子邮件请求消息。   默认情况下使用的编码基于非常早期的版本   一般URI百分比编码规则,有许多修改   例如换行标准化和用&#34; +&#34;替换空格。代替   &#34;%20&#34;。以这种方式编码的数据的MIME类型是   application / x-www-form-urlencoded,目前已定义(仍然是   以非常过时的方式)在HTML和XForms规范中。在   此外,CGI规范包含有关Web服务器的规则   解码此类型的数据并使其可供应用程序使用。

这又有两个部分,说明服务器应如何解码传入请求流以及它应如何编码传出响应流。

根据用例,有几种方法可以做到这一点,例如:

  • HTTP请求和响应对象中有setCharacterEncodingsetContentType等方法,可用于设置编码。
    • 您已经告诉服务器使用UTF-8编码方案来解码请求数据,这是正是您所做的,因为我期待高级Unicode辅助平面字符。但这不是全部,请在下面阅读更多内容。
  • 使用-Dfile.encoding=utf8等JVM属性在服务器或JVM级别设置编码。请阅读this article,了解如何设置服务器编码。

在您的情况下,您从URL的查询字符串中提取日语字符,查询字符串是HTTP请求对象的一部分,因此使用request.setCharacterEncoding("UTF-8");您可以获得所需的编码结果。

但同样不适用于URL编码,这与请求编码不同(您的情况)。考虑下面的示例,在sysout中,即使使用request.setCharacterEncoding("UTF-8");,您也无法看到所需的编码效果,因为您需要进行网址编码,因为网址类似于http://localhost:7001/springapp/forms/executorTest/encodingTest/hellothere 昨夜, 最高此URL没有查询字符串。

@RequestMapping(value="/encodingTest/{quertStringValue}", method=RequestMethod.GET)
    public ModelAndView encodingTest(@PathVariable("quertStringValue") String quertStringValue, ModelMap model, HttpServletRequest request) throws UnsupportedEncodingException {
        System.out.println("############### quertStringValue " + quertStringValue);
        request.setCharacterEncoding("UTF-8");
        System.out.println("############### quertStringValue " + quertStringValue);
        return new ModelAndView("ThreadInfo", "ThreadInfo", "@@@@@@@ This is my encoded output " + quertStringValue);
    }

根据您使用的框架,您可能需要其他配置来为请求或URL指定字符编码,以便在请求尚未指定编码时应用自己的编码,或在任何情况下强制执行编码。这很有用,因为即使在HTML页面或表单中指定,当前浏览器通常也不会设置字符编码。

在Spring中,org.springframework.web.filter.CharacterEncodingFilter用于配置请求编码。请阅读基于此事实的this similar interesting question

在坚果壳

每个计算机程序,无论是应用程序服务器,Web服务器,浏览器,IDE等,只能理解位,因此需要知道如何解释这些位以使其具有预期的意义,因为根据所使用的编码,相同的位可以表示不同的人物。 那就是&#34;编码&#34;通过给出一个唯一的标识符来表示一个角色,以便所有计算机程序,各种操作系统等都知道正确的解释方式。