How can I accept JSON as string in Jersey - java

I am trying to maintain some logs of a couple of Javascript objects in my webapp. The easiest way to log them would be to stringify them and put them on a jersey path as a string.
My logger works fine with regular strings but gives Error 400: The request sent by the client was syntactically incorrect when I pass a JSON stringified object. There are two things that I can't explain and are going wrong with my code:
Everything seems to be working fine on my development server but not on the server where I am deploying it. I develop on a Mac / Homebrew / Tomcat enviroment and deploy on a CentOS server.
Even on the CentOS server, logging works fine when I pass a simple one word strings as message but passing a JSON string throws up the error.
My Logger code looks like this:
#PUT
#Path("logEvent/{fn_event}/{fn_message}")
public void logEvent(#PathParam("fn_event") String event,
#PathParam("fn_message") String message)
throws Exception {
:
:
:
}
I have tried investigating catalina logs but it doesn't tell anything. Access logs give no more information than specifying "Error 400".

This may happen if you don't escape quotes in your JSON string. Try to escape it with \"

Json String may be having "Spaces" etc etc.
So when you call http://yourserver/logEvent/oneword/onewordMessage it may work fine but when you call http://yourserver/logEvent/oneword with space and with & and so many things/or one message with " and not " etc
Then in second case, your path may be incorrectly encoded. Form Encode your json stream, and then pass it as path.
Better move to Post, and pass the stream as Body of Request. Not sure why you will prefer using "entire" json file as path of your service

Related

Linebreak in AWS SNS through Api Gateway and Java

I am triggering the AWS SNS through the API Gateway.
JSONObject requestBody = new JSONObject();
requestBody.put("phone_number", receiverNumber);
requestBody.put("sender_id", senderAlias);
requestBody.put("message_text", messageText);
This JSONObject is being sent to the api gateway as a ByteArrayInputStream throug the AWS SDK for Java v1.
There are "\n" in the text, to create line breaks. The sms however does not have a new line there, it just prints \n.
In the Api Gateway the message is extracted like this: method.request.body.message_text
How do I have to set up the messageText variable to print new lines in the SMS? I tried replacing it with \n or \\n or \\\\n.. Also tried ASCII, didn't work.
Invocation
As this is a quite complex programm I can't show all of it. It's triggered via Insomnia with a String in Json format like this:
It has to be a double backslahed n because thats just how the code needs it. The aws integration is an additional provider so it has to fit in already existing frames. The json object looks like this before being executed.
So I need to find a way to manipulate the string thats going in the object. But I don't know how.
EDIT 3:
Deleting previous edits, as they were not helpful and did not target the problem as I know now.
Finally closing down the issue. It's a problem in the API-Gateway. The object reaches the gateway just fine, with a \n. Which would work in the SNS Service. But to trigger the SNS Service, it's all going into one URL, which converts the \n into %5Cn
Before transformation:
URL:
So the problem is in the URL encoding..
Thanks to the AWS Support I now am able to send SMS with line breaks through the api gateway.
It was wrong to use URL Query Parameters. I removed all of them
I needed one HTTP Header:
Content-Type: 'application/x-www-form-urlencoded'
Then I used a Messaging Template like this, with passthrough: Never:
#set($message = $input.path('$.message_text'))
#set($phoneNumber = $input.path('$.phone_number'))
Action=Publish&PhoneNumber=$util.urlEncode($phoneNumber)&Message=$util.urlEncode($message)&MessageAttributes.entry.1.Name=AWS.SNS.SMS.SenderID&MessageAttributes.entry.1.Value.DataType=String&MessageAttributes.entry.1.Value.StringValue=Alias
Having my JSON Object in the Request like this:
{
"phone_number": "+4912345678",
"message_text": "Break\nHere",
"sender_id":"Alias"
}
Works perfectly fine with a line break in the SMS

GET parameter being received on server without quotes

I am working on a web application where on clicking a button on the UI a GET request is made to the server as below:
https://mywebapp.com?info=%5B%7B%22first%22%3A%22abcd%22%2C%22second%22%3A%22efgh%20ijkl%22%2C%22third%22%3A%22mnop%22%7D%5D
Basically the value I am passing as info is:
[{"first":"abcd","second":"efgh ijkl","third":"mnop"}]
However, when I read this passed value on server, I found it to be received as:
[{first:abcd,second:efgh ijkl,third:mnop}] i.e. all the double quotes are removed.
Now when I try to parse it into json, it fails.
Could you please suggest how could I fix the issue so that the json is received as expected.
Please note that it is an existing big application and I can't change any server level settings.
Thanks
To keep the double qoutes as is you have to send the json in single qoutes
i,e convert the json into string then send it, because the GET/POST request don't recognize json format

String getting split on '#' when passing to a RESTful Web Service in Java through GET method

I am having a RESTful Java Web Service that accepts a long string with '#' in between.
When I am trying to send the string to the method while calling, the string is getting split on '#' and I can retrieve the [0] value alone.
Before sending the message is intact, but after using this..
req.open("GET","https://localhost:8443/registername/resources/registerName/"+"My#Name", true);
req.send();
is the problem.
These are the first few lines in the Web Service...
#GET
#Path("/{message}")
public String validateName(#PathParam("message") String message) throws Exception{
System.out.println(message);
...}
And, it displays "My" alone.
Can anyone please help me on why this is happening? Thanks!
In URLs, a # sign indicates a "named anchor," something that local javascript, and it is not sent to the remote server, so when you have the URL:
https://localhost:8443/registername/resources/registerName/My#Name
Name isn't sent to the server. You need to use a different split character.
See What is it when a link has a pound "#" sign in it or http://www.hypergurl.com/anchors.html for more information.
HTTP post or get will not read anything after #,
Do a URLEncode before doing POST or GET.
I don't think the part after the # is sent up with the GET request.

Java URL Encoding additional characters

I'm having some troubles getting an HTTP Get call to work.
I concatenate the string and print it before opening the connection.
So my string is as the following:
http://example.com?Adri%E1n%20
However, the server is receiving it as:
http://example.com?Adri%EF%BF%BDn%20
I don't know if the problem is on the server side, or when making the call from Java.
Please help.
Additional info: (%E1 = á)
try
System.out.println(URLEncoder.encode("á", "UTF-8"));
prints
%C3%A1

Server side fix for receiving string containing '&'(ampersand)

We have already shipped a client (.NET WinForms) application which sends customer data to Java server. While most of the data sent by client are accepted at server side, some records are truncated because of the presence of & character in it, as client sends raw & and do not URL encode it, we have fixed it by using the below code:
string dataBefore="A & B";
string dataBefore = System.Web.HttpUtility.UrlEncode(dataBefore);
It is impossible for us to update all the client applications(which are already shipped) and we are thinking of a server side fix.
With the help of Fiddler, we have made sure the data has left client in full, but when server reads as below:
//in java
String dataReceied=request.getParameter("data");
it gets truncated if data contains &
Could someone help us suggesting a server side(java) fix for this? Is it possible to access the request stream in java(instead of request.getParameter())?
You can get access to the raw query string using HttpServletRequest.getQueryString() (javadoc), which:
returns a String containing the query string or null if the URL contains no query string. The value is not decoded by the container.
You can them perform manual decoding on that string, instead of using getParameter().
#Wesley's idea of using getParameterMap() may not be useful, because you don't know which order the parameters were supplied in.
I'd suggest implementing this logic as a servlet filter, to decouple the fixing of the broken parameters from your actual servlet logic. This would involve writing a custom subclass of HttpServletRequestWrapper which overrides getParameter() and manuyally decodes the query string. Your servlet would then be able to use the HttpServletrequest API as though everything was tickety boo.
It is cut off because & signifies a new URL parameter in a request like this:
google.com?query=java&page=2. Java converts all these parameters to a Map, so that's where it goes wrong.
Have you tried iterating through request.getParameterMap()? The remaining data is most likely in the name of the next parameter. If that does not work, check out the API of HTTPServletRequest to see if there is another way to get your data.
Good luck!
PS How angry are you guys at the intern that wrote & shipped that client? That sounds messed up!

Categories

Resources