Spring MVC - RequestBody not working (JSON) - json

I'm having a simple controller method:
#RequestMapping(value = "/test", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(value = HttpStatus.OK)
#ResponseBody
public void postCheck(#RequestBody TestDTO testDTO, HttpServletRequest request) {
System.out.println(testDTO);
}
the DTO is:
public class TestDTO {
private String hello;
public TestDTO() {
}
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
}
When i try to post a request to that url i get an ERROR 400 Message response "The request sent by the client was syntactically incorrect." (the controller method is not being invoked at all)
I tried posting from Chrome's poster plugin AND from jquery's ajax:
$.ajax({
type : "POST",
url : "http://localhost:8080/NG_Admin/test",
contentType : "application/json",
dataType : "json",
data : JSON.stringify(eval({"hello" : "world"})),
error : function(data) {
alert('Error');
},
success : function(data) {
alert('Success!');
}
});
}
Any ideas? (btw I use both 'jackson-mapper-asl', version:'1.9.12', 'jackson-core-asl', version:'1.9.12')
Thanks

OK,I fixed the problem,
Had to add a filter for all request that handles CORS access.

Related

Returning result as JSON instead of HTML

I am calling and displaying a java web service using ASP.NET Web API. How do i make it such that when i run my ASP.NET Web API, the page shows JSON data instead of HTML?
Here are my codes:
DemoRestfulClient.cs
public class DemoRestfulClient
{
private string BASE_URL = "http://localhost:8080/";
public Task<string> AdditionJava2()
{
{
try
{
var client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("AdditionJava2").Result;
return response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
HttpContext.Current.Server.Transfer("ErrorPage.html");
}
return null;
}
}
}
DemoController.cs
public class DemoController : Controller
{
private DemoRestfulClient demoRestfulClient = new DemoRestfulClient();
public ActionResult Index()
{
var Result1 = demoRestfulClient.AdditionJava2().Result;
return Content(Result1);
}
}
Someone please help me. Thank you so much in advance.
public class DemoController : Controller
{
private DemoRestfulClient demoRestfulClient = new DemoRestfulClient();
public ActionResult Index()
{
var Result1 = demoRestfulClient.AdditionJava2().Result;
return Json(Result1);
}
}
The above method will return a json object .
You have wanted to get the json object, right? :)
You have to parse the Json object in order to separately view the content in json.
By using ajax, you can get the content of the json object separately.
For an example,
$.ajax({
url: $("#head").val() + "/Template/updatedTmpltView",
dataType: "html",
data: {},
type: "POST",
success: function (msg) {
data = $.parseJSON(msg)
var name = data.FieldName;
var type = data.FieldType;
var id = data.FieldId;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
In the success (msg), you get the json object as **msg**.
data will include the parsed json object and you can obtain necessary data by data.yourFieldName
Hope this helped you! :)

returning json object from controller to jsp

I want to send all the data from the DB as a json array to jsp to be fetched by ajax.
EmployeeController
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#RequestMapping(value = "/index", method = RequestMethod.GET)
public #ResponseBody List<Employee> listAllUsers() {
return employeeService.listEmployeess();
}
and the jsp
ajaxCall = function() {
$.ajax({
url : 'EmployeeController',
type : 'GET',
dataType : 'json',
error : function(that, e) {
alert(e);
},
success : function(data) {
alert(data);
}
});
}
so how to make this?
By Default your REST Controller converts java objects into JSON object out-of-the Box. But you can also use #Produces("application/json") above the controller method.
Please try to run the ajax response data in a loop data[i], if it doesn't work then use the dot invocation method to reach the data.

How to test the error output of a Spring Boot Controller?

I have implemented a simple controller with a simple request / response.
Controller
#RestController
#RequestMapping("/")
public class HelloWorldController extends AbstractRestController {
#RequestMapping(value = "/hello", method = RequestMethod.POST)
public HelloWorldResponse sayHello(#Valid #RequestBody HelloWorldRequest request) {
String message = String.format("Hello %s!", request.getSayHelloTo());
return new HelloWorldResponse(message);
}
}
Request
public class HelloWorldRequest {
#NotEmpty
#NotNull
private String sayHelloTo;
protected HelloWorldRequest() {
}
public HelloWorldRequest(String sayHelloTo) {
this.sayHelloTo = sayHelloTo;
}
public String getSayHelloTo() {
return sayHelloTo;
}
#Override
public String toString() {
return "HelloWorldRequest{" +
"sayHelloTo='" + sayHelloTo + '\'' +
'}';
}
}
When i want to test the correct output for the default error handling i seem to be unable to check the output of the default json format using a unit test. The response always seems to be empty. When i fire the request via a normal curl command is see a correct response. I assume this is because the returned JSON cannot be mapped on the HelloWorldResponse. Is there any way of checking if the returned output is valid on the response body?
Test
class TestSpec extends Specification {
MockMvc mockMvc
def setup() {
mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build()
}
def "Test simple action"() {
when:
def response = mockMvc.perform(post("/hello")
.contentType(MediaType.APPLICATION_JSON)
.content('{"sayHelloTo": ""}')
)
then:
response.andExpect(status().isOk())
}
}
Json Response
{
"timestamp" : 1426615606,
"exception" : "org.springframework.web.bind.MissingServletRequestParameterException",
"status" : 400,
"error" : "Bad Request",
"path" : "/welcome",
"message" : "Required String parameter 'name' is not present"
}
try to debug with print() method, may be exception is thrown during execution.
MvcResult andReturn = mockMvc.perform(get("/api")
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andReturn();
The #Controller class you posted and the Test case (and response) don't seem to match (you're calling /hello in your test case and your #RequestMapping says /welcome ... Can we see the correct code? It looks like you have a #RequestParam("name") set, but you're not passing it.

JSON posted to MVC Controller is null

Here is my jQuery which looks at an HTML table and gets an id from the tr and an input field value and puts them in an object to be json stringified and posted to an MVC controller. I am using jQuery 1.8.2
var rowdata = [];
$('table').find('tr').each(function () {
myjson = [];
item = {}
item["id"] = $(this).attr('id');
item["reason"] = $(this).find('input').val();
myjson.push(item);
rowdata.push(myjson);
});
jsonstring = JSON.stringify(rowdata);
$.ajax({
url: '#Url.Action("AbsentReason", "Attendance")',
data: jsonstring,
type: 'POST',
traditional: true,
contentType: 'json',
success: function (data) {
$('#message').html("Reason was updated");
}
});
This is the resulting JSON which checks valid.
[[{}],[{"id":"6","reason":""}],[{"id":"7","reason":""}],[{"id":"15","reason":""}],[{"id":"23","reason":""}],[{"id":"29","reason":""}],[{"id":"30","reason":""}],[{"id":"31","reason":""}],[{"id":"35","reason":""}],[{"id":"40","reason":""}],[{"id":"41","reason":""}],[{"id":"42","reason":""}],[{"id":"48","reason":""}],[{"id":"49","reason":""}],[{"id":"50","reason":""}],[{"id":"51","reason":""}],[{"id":"52","reason":""}],[{"id":"53","reason":""}],[{"id":"54","reason":""}],[{"id":"55","reason":""}],[{"id":"56","reason":""}],[{"id":"57","reason":""}],[{"id":"58","reason":""}],[{"id":"59","reason":""}],[{"id":"60","reason":""}],[{"id":"61","reason":""}],[{"id":"62","reason":""}],[{"id":"63","reason":""}],[{"id":"74","reason":""}],[{"id":"75","reason":""}],[{"id":"80","reason":""}],[{"id":"81","reason":""}],[{"id":"87","reason":""}],[{"id":"88","reason":""}],[{"id":"90","reason":""}],[{"id":"91","reason":""}],[{"id":"105","reason":""}],[{"id":"106","reason":""}],[{"id":"107","reason":""}],[{"id":"108","reason":""}],[{"id":"110","reason":""}],[{"id":"111","reason":""}],[{"id":"119","reason":""}]]:
This is the start of my controller.
[HttpPost]
public ActionResult AbsentReason(string jsonstring)
{
return View("Index");
}
The jsonstring parameter is always null. Can anyone see what is wrong?
UPDATE
This is my new controller based on the comments to use a model and allow MVC to do the work for me.
[HttpPost]
public ActionResult AbsentReason(IEnumerable<VMAttendance> jsonstring)
{
return View("Index");
}
and my viewmodel
public class VMAttendance
{
public int PersonID
{
get;
set;
}
public string Reason
{
get;
set;
}
}
The parameter is still null. I also update my jQuery in an attempt to send the correct json.
var data = $('table').find('tr').map(function () {
var id = $(this).attr('id');
var reason = $(this).find('input').val();
var rowdata = { "PersonID": id, "Reason": reason };
return rowdata;
}).get();
$.ajax({
url: '#Url.Action("AbsentReason", "Attendance")',
data: data,
type: 'POST',
traditional: true,
contentType: 'json',
success: function (data) {
$('#message').html("Reason was updated");
}
});
I tried to send some test json to the controller but the parameter is still null.
var data = '{"PersonID":"6","Reason":""},{"PersonID":"7","Reason":""}'
assuming you have an MVC model as follow
public class MyModel
{
public int ID {get;set;}
public string Reason {get;set;}
}
if you modify your action method signature to
public ActionResult AbsentReason(IEnumerable<MyModel> json)
when you post back your json object, the json serializer will deserialize your json into an IEnumerable of MyModel.
I got this working by changing the contentType from 'json' to 'application/json; charset=utf-8' and removing the first empty object in my json which was created from an extra tr in the table for the header. The json looked like
[{},{"PersonID":"6","Reason":""},{"PersonID":"7","Reason":""}]
when it should look like this
[{"PersonID":"6","Reason":""},{"PersonID":"7","Reason":""}]
My controller looks like this and works nice.
[HttpPost]
public ActionResult AbsentReason(IEnumerable<VMAttendance> jsonstring)
{
return View("Index");
}
Thanks Duy for your assistance!
change the contentType in your ajax object to string.
i'm curious as to why you would want to treat your json as string and not as object. Normally I would have a C# viewmodel and let the serializer map the json object to that C# view model in my controller

jqGrid: how to pass complex javascript object as postData to ASP MVC controller method

I need to pass a JS object to my controller method jqGrid. The object is call "activeFilters" - here is the object represented as JSON:
{"family":
[{
"filterDisplayName":"Performance Status",
"filterDbName":"CurrentStatus",
"filterValueList":"On Plan"
}]
}
Having problems passing the above to my jqGrid (details further down). But I can pass the object to a controller with Ajax very simply:
$.ajax({
url: myMethodPath,
type: 'POST',
dataType: 'html',
data: JSON.stringify(activeFilters),
contentType: 'application/json; charset=utf-8',
success: function (result) {
alert("success")
},
error: function () {
alert("Error:");
}
});
My test controller method looks like:
[HttpPost]
public ActionResult DataTest(JsonFilterFamily activeFilters)
{
return PartialView();
}
Add the structure of JsonFilterFamily looks like:
public class JsonFilterFamily
{
public List<FilterFamilyMember> family { get; set; }
}
public class FilterFamilyMember
{
public string filterDisplayName { get; set; }
public string filterDbName { get; set; }
public string filterValueList { get; set; }
}
With the above Ajax, the JS object gets sent to the controller without problems. But I just can't figure out how to send the same JS object as the postData in a call to jqGrid controller. I must have the syntax wrong for post data. Here is what I am using:
$("#myJqGrid").setGridParam({ postData: { family: activeFilters.family} }).trigger("reloadGrid");
But when the controller fires, something strange happens. The debugger tells me the count of family = 1; but filterDisplayName, filterDbName, filterValueList are null. Any ideas on what is wrong?
In your controller method, try putting:
var filterFamilyMember = new FilterFamilyMember();
TryUpdateModel(filterFamilyMember);
TryUpdateModel is a MVC controller method and this will put the data in your object.