I use spring, spring restcontroller, I have an enum in Java.
public enum PaymentModeEnum {
CASH, DEBIT, CHECK, CREDITCARD;
}
How to get enum value in javascript and to to send enum value to java?
If you are trying to set/get enum value using Javascript REST call to Spring API-
Enum name can be set using path variable or query string. Below example is for query string.
//https://localhost:8444/getByEnumVal?enumVal1=CASH
#RequestMapping(value = "/getByEnumVal", method = RequestMethod.GET)
public String setEnum(
#RequestParam(value="enumVal1", required=false) String enumVal1) {
Service.methodcall(enumVal1);
...
}
Enum value can be returned as JSON directly, or by setting it in POJO
#RequestMapping(value = "/getEnumVal", method = RequestMethod.GET)
public String getEnumVal() {
return PaymentModeEnum.CASH;
}
From your question I assume you have a frontend with some javascript that calls a REST endpoint written in Java, using Spring.
I don't know how to share an enum between javascript and Java (they are different languages), but you can either send its ordinal value, or the name of the enum value. I would go with the latter.
This way you can just get it as a query parameter in your endpoint. Like so:
#RequestMapping(
path = some/path
method = GET)
public SomeTypeAsResponse method(#RequestParam(name = "payment_mode") PaymentModeEnum paymentMode) {
...
}
1.For extracting Enum in JavaScript do something like below:
var enumvar = document.inputId.Packages.com.MyClass$MyEnumYesNo.YES
2.For sending Enum from Javscript to RestController, pass it as a String directly and then map it as a Enum in the methods input parameter in Controller.
Related
I have a 2d javascript array like this
[[2,3],[13,4],[1,19]]
and I want to pass it to my .Net controller
My controller header looks like this
public async Task<ActionResult> UpdateOrder(int[,] order)
My put call looks like this
updateOrder(order: number[][]): Observable<any> {
return this.http.put(this.baseUrl + 'members/edit/set-order/' + order, {});
}
but I'm getting an error when I hit the controller saying:
'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Int32[,]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\nPath '', line 1, position 2.'
I think you might need to use List<List<int>> type instead of int[,] in c# from default c# JSON serializer
public async Task<ActionResult> UpdateOrder(List<List<int>> order)
You don't need to go through (manual) de/serialization and you don't need a List<List<int>>. I'm able to pass a 2d array of ints with a payload like [[1,2],[3,4],[5,6]] and the below API interface.
public async Task<IActionResult> Test(int [,] ints)
Isn't it your url in the request? You treat the order like a string to cat to the url and the body is empty. And when the body is empty, you see that error you're getting. I think what you need is:
return this.http.put('yourUrl', order, {});
See put. (assuming Angular)
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.
Can I pass the entire model as a parameter to Url.Action orsimilar?
Actually, I pass a parameter to the controller and I load the model, but I would like to pass entire model.
window.location.replace('#Url.Action("Search", "Search", new { idSong = Model.IDSong })');
Can you. Yes.
You can pass a simple model containing only properties which are values types or string using the overload that accepts object as the 3rd parameter
#Url.Action("Search", "Search", Model)
Would you want to? No.
Internally the method will create a Dictionary based on each properties name and .ToString() value and convert that to a query string. Not only will the resulting url be ugly, if you have a lot of properties, or the values of the properties contain long strings, you could exceed the query string limit and throw an exception. But the main issue is that any properties which are complex objects or collections will cause binding to fail because, for example, a property which is List<string> will generate ..?somePropertyName=System.Collections.Generic.List[string]&....
Pass just the model's ID as your doing now, and get the model again from the repository in your controller.
You can try passing a ViewBag instead:
Url.Action("Search", "Song", new { songId = ViewBag.SongId, songName = ViewBag.SongName})
Controller:
[HttpGet]
public PartialViewResult Search(string songId, string songName)
{
}
I am using playframework 2.4.4 and am trying to achieve the following:
In the backend I serialize a Map<Lagerplatz, Integer> to JSON (com.fasterxml.jackson) where Lagerplatz is a class inheriting from com.avaje.ebean.Model.
In the frontend I want to deserialize the map to construct a picking list, telling the picker from which place (=Lagerplatz) to pick how many items.
The JSON I get from the serialization looks like this:
{
"models.Lagerplatz#21":3,
"models.Lagerplatz#2":6,
"models.Lagerplatz#3":3,
"models.Lagerplatz#47":0,
"models.Lagerplatz#48":0,
"models.Lagerplatz#a":3,
"models.Lagerplatz#c":3,
"models.Lagerplatz#15":3,
"models.Lagerplatz#36":3,
"models.Lagerplatz#37":3,
"models.Lagerplatz#18":3,
"models.Lagerplatz#38":6,
"models.Lagerplatz#39":6,
"models.Lagerplatz#3a":6
}
...so instead of serializing the whole Lagerplatz-object - for some reason only a String representation that looks like some kind of id is sent via JSON.
My question is how to access e.g. the value "3" for the key "models.Lagerplatz#21" with Javascript when all I have is a list with real Lagerplatz objects...how do I find out which Lagerplatz object refers to which "id"?
(By the way: I also serialize a java.util.List which carries the order in which the picker is supposed to pick the items and here the Lagerplatz objects get serialized "normally" so there actually is a whole Lagerplatz object in the JSON...)
This is the class Lagerplatz:
package models;
import javax.persistence.*;
import play.data.validation.Constraints.Min;
import play.data.validation.Constraints.Required;
import com.avaje.ebean.Model;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
#Entity
public class Lagerplatz extends Model {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Required
#Min(0)
private int menge;
#Required
#Min(1)
private int kapazitaet;
#Required
#ManyToOne
#JsonManagedReference
private Material material;
#Required
#ManyToOne
#JsonBackReference
private Kommissionierlager kommissionierlager;
#OneToOne
#JsonManagedReference
private Lagerplatz vorgaenger;
#OneToOne
#JsonBackReference
private Lagerplatz nachfolger;
public static Finder<Long,Lagerplatz> find = new Finder<>(Lagerplatz.class);
}
models.Lagerplatz#21 is actually the String representation of an ebean object as indicated by wwkudu (see his comment to my question).
models is the package in which the class resides, Lagerplatz is the object's class name and since any ebean object has a unique id (so it can be persisted to a database using ebean ORM) the part after the # is that very id.
For the model Lagerplatz this id is an auto generated Long value which for some reason is converted to a hexa-decimal value for the String representation.
So I was able to solve my problem by converting the id I get from the correctly serialized List which carries the picking order to hexa-decimal and constructing that String representation (I ommitted some code that is not necessary to understand the solution here - kommissionierreihenfolge is the deserialized List<Lagerplatz> that carries properly serialized and deserialized Lagerplatz objects, kommissionierliste is the Map<Lagerplatz, Integer> that carries the strangely serialized and deserialized Lagerplatz objects as keys and the Integers as values):
function setKommissionierliste(kommissionierreihenfolge, kommissionierliste) {
var tableBodyWrapper = document.getElementById("kommissionierliste-table-body");
for (var index in kommissionierreihenfolge) {
...
var mengeNode = document.createTextNode(kommissionierliste["models.Lagerplatz##" + kommissionierreihenfolge[index].id.toString(16)]);
...
}
}
Since I really only need the Lagerplatz in the Map<Lagerplatz, Integer> as a key to retrieve the Integer value associated with it, this solution works fine for me although it is a bit of a workaround.
As indicated by wwkudu, the proper solution would be to get the server to actually send Lagerplatz objects.
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.