I have a Java RESTlet v2.1.2 method like this:
#Post("json")
public Representation doPost(Representation entity) throws UnsupportedEncodingException {
Request request = getRequest();
String entityAsText = request.getEntityAsText();
logger.info("entityAsText = " + entityAsText + " Üüÿê");
in the Cygwin console it prints:
2015-04-19 22:07:27 INFO BaseResource:46 - entityAsText = {
"Id":"xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx",
"Field1":"John?????????",
"Field2":"Johnson??????????"
} ▄³ Û
As you can see the Üüÿê is printed as ▄³ Û. The characters Üüÿê are also in the POST body of SOAP UI. But they're printed as ???. I have an implemantation which does not use RESTlet where this works. So the settings in SOAP UI are not the problem. (The POST body is in Application/JSON btw.)
How can I extract the unicode chars Üüÿê from the POST body without getting them as ??? ?
I made a test and it works for me but perhaps I don't have same configuration regarding charset / encoding. I used a standalone Restlet application (no servlet) from Postman. Can you give us more details about the version of Restlet and the different editions / extensions you use (for example, Jackson, Servlet, ...)?
Here is what I have for Java (you can have a look at this link: How to Find the Default Charset/Encoding in Java?):
Default Charset=UTF-8
file.encoding=Latin-1
Default Charset=UTF-8
Default Charset in Use=UTF8
You can also specify the charset you sent for your content at the level of the header Content-Type: application/json;charset=utf-8.
I wrote a post some years ago about such issues when using a servlet container. Perhaps could you also find out some hints to help you: https://templth.wordpress.com/2011/06/05/does-your-java-based-web-applications-really-support-utf8/.
Hope it helps you,
Thierry
Related
Recently I am working on a request with HTTPPost, and I need to set header with Content-Type: application/json, and it requires basic authentication,
Here is may way:
A:
httpPost.setHeader("Content-type","application/json");
String authenData = String.format(Locale.getDefault(), "%s:%s", "xxx#xxx.com", "xxx");
String base64EncodedCredentials = Base64.encodeToString(authenData.getBytes(), Base64.DEFAULT);
httpPost.addHeader("Authentication", "Basic " + base64EncodedCredentials);
B:
httpPost.setHeader("Content-type","application/json");
httpPost.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials("xxx#xxxx.com", "xxxx"), "UTF-8", false));
And, Guess what? With method A, the request header will be only Authentication left, yes, "Content-type" is gone
Only B works perfectly.
Has any one meet similar issue before? Please please help me out, thanks :)
Which version of httpclient are you using ?Can you upgrade to the latest and try again.Looks like a bug to me.
The java doc says :
void addHeader(String name,
String value) Adds a header to this message. The header will be appended to the end of the list.
Finally, I found my mistake in solution A:
Apparently, when use Base64 to encode the authenticationToken, I set Base64.Default, the key is here, we should not do that, we should set it as Base64.NO_WRAP.
Ref: http://developer.android.com/reference/android/util/Base64.html
Ref: http://blog.moes.as/2012/05/basic-http-authentication.html
Thank god.... didn't understand this at all.
I have simple Jersey REST webServices:
#POST
#Path("/label")
#Consumes(MediaType.TEXT_HTML)
public Response setLabels(String requestBody) {
System.out.println(requestBody);
......
}
Request passes some text with "special" non-English characters
[{"За обекта"}]
I can see in Firebug that request passed with correct UTF-8 content and charset
Content-Type text/plain; charset=UTF-8
Though on on server output does not present desirable charset:
[{"?? ??????"}]
Any Idea what and were went wrong? How can I capture text in correct charset on server side?
System.out is a PrintStream. It uses the platform default encoding, which is typically not UTF-8. So you are getting the correct data in, it's just getting mangled when you print it to the console.
I had the exact same problem a few weeks ago - drove me nuts until I figured it out. What made it worse is that I actually had an encoding-related bug in another part of the code.
I have to send some data using POST to a backend that checks the content type and forces "text/xml".
I'm using this code:
final ClientResource resource = new ClientResource(url);
String data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> ..."
StringRepresentation stringRep = new StringRepresentation(data);
stringRep.setMediaType(MediaType.TEXT_XML);
resource.post(stringRep);
It seems that Restlet uses "text/plain" as content type. Is it possible to force the content type? I'm using Restlet 2.0 on Android 2.2.
Thanks in advance
Steven
I made some tests using the code your gave with Restlet 2.0.3 and changing the content type on the representation actually changes the corresponding header in HTTP request.
You say "It seems that Restlet uses "text/plain" as content type". How do you check that? On my side, I used the Tcp Mon tool from Apache as a proxy to see the request content (http://ws.apache.org/commons/tcpmon/download.cgi). Otherwise which 2.0 version do you use? This will allow having the same environment as you...
Thanks,
Thierry
I'm using Jersey Client to access a webservice, like this:
response =
r.accept(MediaType.TEXT_PLAIN_TYPE).header("content-length", 0).post(String.class);
where r is a WebResource
However, the Webservice returns 411 - Content-Length is missing.
using tcpdump, i found out that i am able to specify custom headers, i.e. .header("myheader", 0) works fine.
So it seems that jersey is deleting the content-length header for some reasons.
Anyone has any ideas?
I actually had a requirement to use an empty POST request for a Restful webservice.
If you specify an empty string as the second parameter of post method, Jersey will create the Content-Length header with the value of 0.
e.g.
response = r.accept(MediaType.TEXT_PLAIN_TYPE).post(String.class, "");
The content length of a call is computed by Jersey Client, it cannot be set.
Paul Sandoz — a well known commiter on the project — have answered a similar question:
Q: I think that "Content-Length"
header is not being set automatically.
A: The Jersey runtime [...]
determine the length of content.
If you need further informations, please explain what result did you expect from POSTing a String to a Resource with an empty size.
I have to connect to a poorly implemented server that only understands Content-Type (capital-T) and not Content-type. How can I ask my JAX-WS client to send Content-Type?
I've tried:
Map<String, List<String>> headers = (Map<String, List<String>>)
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
But headers is null. What am I doing wrong?
I have to connect to a poorly implemented server that only understands Content-Type(capital-T) and not Content-type. How can I ask my jax-ws client to send Content-Type?
I've dug this question a bit more and, sadly, I'm afraid the answer is: you can't. Let me share my findings.
First, the code that you'll find in https://jax-ws.dev.java.net/guide/HTTP_headers.html does not give you access to the HTTP headers of the future HTTP request (that hasn't been created at this point), it allows you to set additional HTTP headers for making a request (that will be added to the HTTP request later).
So, don't expect the following code to not return null if you don't put anything before (and actually, you'll only get what you put in there):
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Then, I did a little test based on the code provided in the same link:
AddNumbersImplService service = new AddNumbersImplService();
AddNumbersImpl port = service.getAddNumbersImplPort();
((BindingProvider)port).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
Collections.singletonMap("X-Client-Version",Collections.singletonList("1.0-RC")));
port.addNumbers(3, 5);
And this is what I see in the HTTP request when running the client code:
POST /q2372336/addnumbers HTTP/1.1
Content-type: text/xml;charset="utf-8"
X-client-version: 1.0-RC
Soapaction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.6 in JDK 6
Host: localhost:8080
Connection: keep-alive
Content-Length: 249
Do you notice the difference: only the first char of the X-Client-Version header is kept upper cased, the rest is lowered!
And indeed, if you check the class c.s.x.w.t.Headers that is used to represent HTTP request (and response) headers, you'll see that it "normalizes" keys when they are added (in normalize(String)):
/* Normalize the key by converting to following form.
* First char upper case, rest lower case.
* key is presumed to be ASCII
*/
private String normalize (String key) {
...
}
So, while the c.s.x.w.t.h.c.HttpTransportPipe class (my understanding is that this is where the HTTP request is created, this is also where previously added headers will be added to the HTTP request headers) actually adds "Content-Type" as key in a c.s.x.w.t.Headers instance, the key will be modified because of the previously mentioned implementation detail.
I may be wrong but I don't see how this could be changed without patching the code. And the odd part is that I don't think that this "normalizing" stuff is really RFCs compliant (didn't check what RFCs say about headers case though). I'm surprised. Actually, you should raise an issue.
So I see three options here (since waiting for a fix might not be an option):
Patch the code yourself and rebuild JAX-WS RI (with all the drawbacks of this approach).
Try another JAX-WS implementation like CFX for your client.
Let the request go through some kind of custom proxy to modify the header on the fly.
You can modify the HTTP headers from the RequestContext. If you have access to the port object you can cast it to a javax.xml.ws.BindingProvider, which will give you access to the RequestContext.
You might also want to remove the unaccepted "Content-type" header.
This page shows how to do it in a bit more detail: https://jax-ws.dev.java.net/guide/HTTP_headers.html
Let me know if you need more code samples, or if you paste some of your code I can show you how to modify it.