无法使用 Resttemplate 和 json 从 Android 客户端获取字符编码

发布于 2025-01-01 22:44:24 字数 2247 浏览 1 评论 0原文

好吧,所以我尝试了一切,但在 stackoverflow 上询问...

我正在尝试使用一些 http 参数从 Android 使用 httpclient 和 Resttemplate 到服务器端 Spring 控制器执行 REST 调用。我所有的瑞典字符最终在服务器上作为“\u001A”...

设置httpclient和resttemplate代码:

HttpClient httpClient = new HttpClient();

Credentials defaultcreds = new UsernamePasswordCredentials(msisdn, password);
httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM), defaultcreds);

//httpClient.getParams().setContentCharset(prefs.());
httpClient.getParams().setCredentialCharset(prefs.getCredentialsEncoding());

CommonsClientHttpRequestFactory requestFactory = new CommonsClientHttpRequestFactory(httpClient);

RestTemplate restTemplate = new RestTemplate(requestFactory);

// Add message converters
List<HttpMessageConverter<?>> mc = restTemplate.getMessageConverters();
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();

List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
json.setSupportedMediaTypes(supportedMediaTypes);
mc.add(json);
restTemplate.setMessageConverters(mc);

return restTemplate;

然后我用我的参数准备一个httpentity:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("myparam", "" + "å");
HttpEntity<String> entity = new HttpEntity<String>(headers);

我最后进行其余调用:

ResponseEntity<UserStatusTO> response = rest.exchange(url, HttpMethod.GET, entity,
            MyResponseClass.class);

在服务器上,我有一个杰克逊反序列化器和我的弹簧控制器方法如下所示:

@RequestMapping(method = RequestMethod.GET, value = "/event/out", headers = "Accept=application/json", produces = {"application/xml;charset=UTF-8", "application/json;charset=UTF-8"})
public
@ResponseBody
UserStatusTO out(Authentication auth, @RequestHeader(value="myparam", required =  false) String myparam) {

所有特殊字符最终都为 \u001a !我已经尝试了很多东西,手动重新编码客户端和服务器端的字符串,但没有任何效果。我试过摆弄 httpClient.getParams().setContentCharset(); httpClient.getParams().setUriCharset();

据我所知,没有一个有效。

我没主意了!如果有人有任何意见,我将非常感激。谢谢!

Ok, so ive tried everything but asking at stackoverflow...

I'm trying to perform a REST call with some http params from an Android using httpclient and resttemplate to a server-side Spring controller. All my Swedish chars end up on the server as '\u001A'...

setting up httpclient and resttemplate code:

HttpClient httpClient = new HttpClient();

Credentials defaultcreds = new UsernamePasswordCredentials(msisdn, password);
httpClient.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM), defaultcreds);

//httpClient.getParams().setContentCharset(prefs.());
httpClient.getParams().setCredentialCharset(prefs.getCredentialsEncoding());

CommonsClientHttpRequestFactory requestFactory = new CommonsClientHttpRequestFactory(httpClient);

RestTemplate restTemplate = new RestTemplate(requestFactory);

// Add message converters
List<HttpMessageConverter<?>> mc = restTemplate.getMessageConverters();
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();

List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
json.setSupportedMediaTypes(supportedMediaTypes);
mc.add(json);
restTemplate.setMessageConverters(mc);

return restTemplate;

I then prepare a httpentity with my parameter:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("myparam", "" + "å");
HttpEntity<String> entity = new HttpEntity<String>(headers);

I finally make the rest call:

ResponseEntity<UserStatusTO> response = rest.exchange(url, HttpMethod.GET, entity,
            MyResponseClass.class);

On the server, i have a jackson deserializer and my spring controller method looks like:

@RequestMapping(method = RequestMethod.GET, value = "/event/out", headers = "Accept=application/json", produces = {"application/xml;charset=UTF-8", "application/json;charset=UTF-8"})
public
@ResponseBody
UserStatusTO out(Authentication auth, @RequestHeader(value="myparam", required =  false) String myparam) {

All the special chars end up as \u001a ! I've tried tons of stuff, re-encoding the strings manually client AND server side, none worked. I've tried fiddling with the
httpClient.getParams().setContentCharset();
httpClient.getParams().setUriCharset();

None worked as far as i could tell.

I'm out of ideas! If anybody has any input, i'd be much obliged. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南冥有猫 2025-01-08 22:44:24

我遇到了类似的问题,我通过手动设置正确的内容类型和字符集而不是使用 MediaType.APPLICATION_JSON 来修复它:

HttpHeaders headers = new HttpHeaders();
Charset utf8 = Charset.forName("UTF-8");
MediaType mediaType = new MediaType("application", "json", utf8);
headers.setContentType(mediaType);

I had a similar issue and I fixed it by setting the proper content-type AND character set manually instead of using MediaType.APPLICATION_JSON:

HttpHeaders headers = new HttpHeaders();
Charset utf8 = Charset.forName("UTF-8");
MediaType mediaType = new MediaType("application", "json", utf8);
headers.setContentType(mediaType);
梦晓ヶ微光ヅ倾城 2025-01-08 22:44:24

这听起来像是服务器端的一个问题,因为 Apache HTTP 客户端很乐意在标头中输出 Latin-1 字符,您可以使用这个简单的测试进行测试:

HttpGet get = new HttpGet("http://www.riksdagen.se");
get.addHeader("SwedishHeader", "Mona Sahlin är ett nötdjur");

ByteArrayOutputStream out = new ByteArrayOutputStream();
SessionOutputBufferImpl buffer = new SessionOutputBufferImpl(out, get.getParams());
HttpRequestWriter writer = new HttpRequestWriter(buffer, BasicLineFormatter.DEFAULT, get.getParams());

writer.write(get);
buffer.flush();
System.out.println(out.toString("ISO-8859-1"));

SessionOutputBufferImpl 是使用 AbstractSessionOutputBuffer 的一个小技巧

class SessionOutputBufferImpl extends AbstractSessionOutputBuffer {
    SessionOutputBufferImpl(OutputStream out, HttpParams params) {
        init(out, 1024, params);
    }
}

您可能应该专注于您的服务器后端- 你用什么?如果它是“固定的” - 您应该考虑尝试根据 RFC 2407 格式化您的标头 -一些服务器支持,另一些则惨败。

This sounds like an issue on the server side since the Apache HTTP client will gladly output Latin-1 characters in headers, as you can test with this simple test:

HttpGet get = new HttpGet("http://www.riksdagen.se");
get.addHeader("SwedishHeader", "Mona Sahlin är ett nötdjur");

ByteArrayOutputStream out = new ByteArrayOutputStream();
SessionOutputBufferImpl buffer = new SessionOutputBufferImpl(out, get.getParams());
HttpRequestWriter writer = new HttpRequestWriter(buffer, BasicLineFormatter.DEFAULT, get.getParams());

writer.write(get);
buffer.flush();
System.out.println(out.toString("ISO-8859-1"));

SessionOutputBufferImpl is a little hack to use the AbstractSessionOutputBuffer

class SessionOutputBufferImpl extends AbstractSessionOutputBuffer {
    SessionOutputBufferImpl(OutputStream out, HttpParams params) {
        init(out, 1024, params);
    }
}

You should probably concentrate on your server backend - what are you using? If it's "fixed" - you should consider trying to format your header according to RFC 2407 - some servers support, others fail miserably.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文