java pass string web request to non string #RequestParam - javascript

I am working on a react application that has a java backend. The react frontend sends a URL request to a java web service controller, and within that webservice controller, the variable types are defined. Since a URL request is a string I’m having trouble dealing with non-string values. And since Javascript is not a strongly-typed language like Java I cannot definie variable types on the front end.
Web Request Example:
localhost:8080/filteredCSV.json?status=UNDER_ACTIVE_REVIEW,AUTHORIZED_BY_DWB,UNDER_CONSTRUCTION,CONSTRUCTION_COMPLETED&engineerEmail=null&issues=null&date=null
Web Service Controller:
#RequestMapping(value = "/filteredCSV.json")
#ResponseBody
public WebserviceResponse<?>filteredCSV(
#RequestParam(value="status") ArrayList status,
#RequestParam(value="engineerEmail") ArrayList engineerEmail,
#RequestParam(value="issues", required=false) Boolean issues,
#RequestParam(value="date", required=false) Local Date date){
return service.filteredCSV(status, engineerEmail, issues, date);
}
If the Boolean or Date values are null, then null is getting passed as a string which causes a TypeMismatch Error and the program stops. I do not appear to have a way to change the string to to a non-string null value once it hits the web service controller. I understand why this is occurring, but I am not sure if there is a way to work around it so that I can pass null as a value and not null as a string. Am I just screwed? Is there not a way to deal with this?

You're not sending null as a value, you're sending a string that contains the word 'null.
Send no value "" instead of the string value 'null'. This is what the #RequestParameter is expecting when it should be ignoring a parameter.
#RequestParameter docs
If you can't edit the javascript you still have some options ... what spring is really doing there is data binding values from the http request to instances of Java variables. You can override or bypass this as you need. (This sort of approach is the 'old' way of doing this and the very problem spring annotations hope to solve).
#RequestMapping(value = "/filteredCSV.json")
#ResponseBody
public WebserviceResponse<?>filteredCSV(HttpRequest request){
String date = request.getParameter('date');
// Convert date if not 'null' here, and so on
}

I like the suggestion posted by #zmf, However If want find other work arounds. Please refer some of the approaches I think will work:
Solution 1: You can introduce a filter, and parse all the request parameters as string. When you encounter null as string do not send the param further, it will be considered as null at controller level.
Solution 2: Replace RequestParam type like Date, Boolean with String. You can then process accordingly.

Related

Getting string index value from Javascript to MVC C# Controller using string[] array as a parameter

I am new in this environment and i just want to ask somebody if it is possible to get the string value not the index value using string[] array as a parameter?
Below are those images: ajax pass this data into controller
I am using ajax to pass my data in to the url controller in c# mvc.
By the way, here's my sample array data: prepared data..
the highlighted one is my array and in my parameter in mvc # is declared as string [] methodParam: highlighted parameter,
Those not highlighted parameter are working. all i want to do is getting one by one string in methodParam. i tried to use this
GetMethodParam.IndexOf("Date").ToString() but the output is -1 which probably not available in context.
i just want to get each string and its value because i send it to the email outlook..
like this. enter image description here.
Any Suggestions, clarification or comments is highly appreciated. Thank you ;) .
You don't need the individual input in data on ajax call, just use the last one UserHeader
and in Acton(C#) use a model as argument with containing all attributes of UserHeader.
Or, remove UserHeader from data and Use each attributes as individual argument in C# Action with same name.

NewtonSoft JSON converter serializes but does it weirdly. How to fix?

Given the following object
Friend Class GetLocationsResult
Public Property X1 As String
Public Property X2 As String
Public Property X3 As String
Public Property X4 As String
Public Property X5 As String
Public Property X6 As Double
Public Property X7 As Double
End Class
And it is declared and instantiated thusly:
Dim objList as List(of GetLocationsResults) = new List(of GetLocationsResults)
And objList is populated via an iterator that churns through a collection of objects/aggregate classes. The iterator just shoves values into a new GetLocationsResult object and then adds it to the list.
And given the NewtonSoft JSONConvert.SerializeObject(objList) results:
{"d":"[{\"X1\":\"Store Name\",\"X2\":\"Address\",\"X3\":\"City\",\"X4\":\"State\",\"X5\":\"Zip\",\"X6\":Coord1,\"X7\":Coord2}]"}
This point has been addressed and is no longer an issue
There are several issues with this result set. First, for whatever odd
reason, the object being named "d" is not acceptable.
How can I specify something other than "d" for the "name" of the json array?
When I attempt to JSON.parse the response, it needs to be in the following format in order to actually get to the data:
resultSet = JSON.parse(data.d);
console.warn(resultSet[0].X1);
Having to say resultSet[0] is, of course, not acceptable.
How do I cause the 'JSONConvert.Serialize' method to not wrap the response in such a way that I have to refer to the first index of the
resulting JSON data so that I can say resultSet.X1 instead of
resultSet[0].X1?
As requested, here is some more detailed information that may be relevant to the issue at hand.
The data is being returned from a WCF service. The exposed method is decorated thusly:
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json)>
and returns type String. The service is being consumed by a desktop application and a mobile platform. The desktop website can have its own method and, in fact, does because we don't want to deal with X1, X2, etc while the mobile platform devs have declared that as necessary. As noted, the method returns a number of results in the form of a custom, aggregate class which is then shoved into a class object which is only a collection of properties. The return statement is thus:
Return JsonConvert.SerializeObject(retVal)
where retVal is a List(of GetLocationsResult)
So while having to access the data via index may be fine for the website, it is not acceptable for the mobile platform. Because each will run their own methods, it is possible to have a unique solution for both if needed.
Three things.
It sounds like you're returning that back through an ASP.NET ASMX
ScriptService or ASPX [WebMethod]. When using one of those
endpoints, you don't need to (and shouldn't) manually serialize the
object into JSON. ASP.NET will do that for you automatically. You don't need to use JSONConvert at all; just return your object as the result. That's why you're seeing all that escaped data after the .d. It's JSON serialized twice.
As WhiteHat mentioned, the .d is a good thing in some situations. It's introduced by default in these ASP.NET JSON services and can't easily be removed on the server-side, but is easy to account for when you parse the response on the client-side.
You are returning a List(of GetLocationResults), which maps to a JavaScript array. That's why you need to use resultSet[0].X1 to access a value in the result. If you want to access that value via resultSet.X1, you need to be sure to return only a single GetLocationResults object instead of a List of them.
Does that help? If you could update your question with a more complete example of your server-side and client-side code, I could give you an example of how to address the preceding three issues.

Can an HTML encoded string be converted to JSON?

I'm getting encoded data from the server, which is encoded using .NETs WebUtility.HtmlEncode.
This data is then displayed and needs to be sent back to the server for some operations. During this time, it is converted to JSON before being sent over using JSON.stringify. All works fine so far.
However, once this reaches the server, it is rejected due to being potentially dangerous. The object that is converted to JSON can have strings with special chars such as -
"This is John&#39s account" originally "This is John's account"
Or "John earns in &#165" originally "John earns in ¥"
My belief is that these encoded string values are interfering with the JSON being properly formed.
Is there any way in Javascript that I can JSONify HTML encoded strings?
EDIT: In case it's not clear, the data is already encoded when i do JSON.stringify(data).
An example of my data -
row[0] = {column1, column2, column3}
Where each column is an HTML encoded string such as "This is John&#39s account"
Considering that a JSON object with a string would look like this
{ 'member1' : 'some string with &#165' }
I don't believe it's the JSON at fault. It is far more likely that you are passing the JSON object to a method via GET instead of POST.
As a particular example, the Microsoft MVC3 framework will throw an error about it being unsafe if you submit JSON via a GET method and don't specify to allow GET behavior.
The reason for this can be seen in this answer.
I think you can achieve this functionality in three steps:
Create a partial view.
Call this partial view by passing your string values in it and perform action there.
Return your partial view via JSON and replace it with old one.
But returning the partial view via JSON is bit tricky, I mean you cannot just return the partial view via JSON. First you need to convert the partial view in string and the return this string. Below method will you how to achieve this:
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
This method will convert the partial view in string and return it back to server via JSON. You need to pass to parameter in it, first is the partial view name and second is model. Hope you will get solution of your problem by this.
The solution in the end, was more of a hack, I added an annotation -
[ValidateInput(false)]
to my function on the back-end, so that it wouldn't try to validate my JSON string.

Best Practice for using Form Data in a http request

We have a previous implementation whereby we send one key value pair in the form data to the server
ie. message=something_blah
Is there any point in actually having this in form data? Should form data only be used if we are building an object or array of object?
If we only have one key value pair would it not be better to insert it as part of the query request parameter?
Form parameters and query parameters are accessed, more or less, from the same place from within a servlet.
For example, in doGet() (doPost() would've gone the same way, so would all the other http methods)
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String message = request.getParameter("message"); // would return something_blah or null if no parameter
...
}
To answer your question in the OP comments, parameters coming from request.getParameter() are Strings. You can then convert them to other types (parse to numerical value) or use them to initialize Class instances. Their use is up to you.
This parameter could have come from
<form method="get">
<input name="message" type="text" value="something_blah"/>
</form>
or from the url
http://www.yourdns.com/myapp?message=something_blah
To answer Should form data only be used if we are building an object or array of object?, some frameworks like Spring use parameters coming from html forms (and query string) to automatically instantiate objects for you using reflection and some naming conventions. This is not necessary, it's just useful. So review your requirements and see if you need it.

Spring MVC - Deserialize JSON array

I'm trying to pass data to my controller using Ajax and JSON.
I've got an HTML table and I've got to send multiple coordinates of that table to my controller. So I made a Javascript array containing anonymous objects of this kind :
{
DAY: someIndex,
HOUR: someOtherIndex
}
and let this array be called coordinates, I serialized it like this:
JSON.stringify(coordinates)
so then in an ajax call (type: POST) I used data: JSON.stringify(coordinates).
In my document ready I used :
$.ajaxSetup({
headers : {
Accept : "application/json; charset=utf-8"
}
});
And my controller looks like this:
#RequestMapping(value = "/{id}", method = RequestMethod.POST)
public #ResponseBody
String update(#PathVariable int id, #RequestBody String coordinates, HttpServletResponse response) {
// Do something here to convert it in my complex structure
}
However I don't know what the type should be for the parameter coordinates.
I'm using GSON. And I wasn't able to deserialize it easily. I tried using this solution, but it wouldn't work. (Kept asking to cast types for some reason.)
Since I didn't think it'd be possible to deserialize this correctly, I tried to serialize the coordinates as another format (just a JSON array of strings where the coordinates are split by a token (;) here
So my array the javascript objects are created like this in a foreach:
coordinates.push( someIndex.toString() + ";" + someOtherIndex.toString() );
And I kept the stringify part.
So now when I POST the data to my controller, I output the value with System.out.println(coordinates) and the output looks weird.
%5B%220%3B8%22%5D=
for this object in the Javascript console : ["0;8"].
So my questions :
Is this a good approach?
Is it possible to deserialize a JSON array into some java types? Such as List<Coordinate> ? ( I've tried using this type instead of String in my controller, but it would give me an error 415 - Unsupported media type)
If I'm using the String approach, is there a way to translate that gibberish into something I want?
You get %5B%220%3B8%22%5D= on server side, cause jQuery by default serializes data to query string.
You need to set the content type of the request to application/json using contentType jQuery option.
Then you'll probably want to take a look at some implementation of GsonHttpMessageConverter for simpler RequestBody conversion. Here is one and it looks like there's one in spring for android so maybe you can use that.

Categories

Resources