Spring MVC Ajax form properties name - ajax

I have a form with a list of fields:
type, name, description, height ,width
I send by ajax to my controller, my controller receive this ajax call but he said that all input fields are null.
My mapped DTO have the same fields but with distinct name, really I don't need use the same name in my call ajax that in my #RequestBody dto class.
Its possible? I am limited to use same names in the class and the ajax calls?
This aren't a problem really, but I can't found any info about this.
My DTO properties:
ResourceCreateDTO [resourceTypeId=null, resourceId=null,
resourceName=null, resourceDescription=null, folderId=null]
My JSON data:
resource-description: "asdfasdfasdfasdfsadfasdfsdfasdfasdfasdfasdfsadfasdfasdf"
resource-folder: "0"
resource-folder-type: "1000"
resource-id: "1006"
resource-name: "asdfasdfasdfasdf"
My AJAX Call:
$("#createModalSubmit").click(function(){
var data = {};
$('#createForm *').filter(':input').each(function(){
var input = $(this);
data[input.attr("name")] = input.val();
delete data["undefined"];
});
$.ajax({
contentType : "application/json; charset=utf-8",
type: "POST",
url: context + "/editor/create",
data: JSON.stringify(data),
dataType : 'json',
cache: false,
success:function(result){
},
error:function(){
}
});
});
My Controller config:
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public #ResponseBody ResourceDTO create(#RequestBody ResourceCreateDTO dto)
throws Exception {
System.out.println("dto: " + dto.toString());
This system out prints the above DTO toString.
I am searching any type of anotation or config that I can name the DTO properties:
#MyCustomName("resource-name")
private String resourceName;
Use my "resource-name" from the AJAX call.

If your DTO cannot have the same name that is being used in your ajax, you can then match it manually inside your controller.
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public #ResponseBody ResourceDTO create(#RequestBody String dto)
throws Exception {
//mapping
}
Or
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public #ResponseBody ResourceDTO create(#RequestBody Map<String,Object> dto)
throws Exception {
//mapping
}

Related

How to send JSON response from controller?

I want to pass a boolean value from my controller to javascript using json but couldnot find a way as I am new to spring mvc.
While using servlet we wrote:
response.getWriter().println(somevalue)
and the somevalue can be received using ajax.
Here my controller method is:
#RequestMapping(value = REGISTERACTION , method = RequestMethod.POST)
#ResponseBody
public boolean RegisterUser(#ModelAttribute("register") Register register,HttpServletRequest request, HttpServletResponse response)
{
boolean Registrationsuccess = userService.RegisterUser(register);
return Registrationsuccess;
}
So, here the boolean variable is Registrationsuccess which I want to send to js file and receive it using ajax.
And in my javascipt function which is called using onsubmit event-->
function AccountExists()
{
$.ajax({
type: 'POST',
url: 'registerProcess',
success: function(data){
let detail = JSON.parse(data);
if( data == true)
alert("Success");
else
alert("Not ");
}
});
}
Getting error --
The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request, and the server is unwilling to supply a default representation.
You need to use ResponseEntity and #RestController for JSON Response.
Note : #RestController includes both annotations #Controller and #ResponseBody.
Try with this :
#RestController
#RequestMapping("controller")
public class Controller {
#PostMapping("REGISTERACTION")
public ResponseEntity<Boolean> RegisterUser(#ModelAttribute("register") Register register)
{
Boolean registrationSuccess = userService.RegisterUser(register);
return new ResponseEntity<Boolean>(registrationSuccess , HttpStatus.OK);
}
}
Try to use #ResponseBody annotation in your controller's method. And change the return type of the method to Boolean, then return Registrationsuccess instead of ModelAndView.
You can achieve this using 2 approach
Approach 1: Set model attribute and using expression language you can find on jsp
model.addAttribute("test",true);
in Jsp page
${test}
Approach 2: If you are sending ajax request instead of ModelAndView create a object
set any attribute boolean and return object from method #ResponseBody annotation you will get json in Ajax Response
#RequestMapping(value = REGISTERACTION , method = RequestMethod.POST)
public #ResponseBody MyCustomObject RegisterUser(#ModelAttribute("register") Register register,HttpServletRequest request, HttpServletResponse response)
{
boolean Registrationsuccess = userService.RegisterUser(register);
MyCustomObject cusobj=new MyCustomObject();
cusobj.setStatus(true);
return cusobj;
}
Whatever code you have written it will not return json(It is basically form submission approach) so you have to go with first approach.

Error handling on controller SpringMVC

I am developing an application in jax-rs and spring mvc.
I want to notify my client each time when an default error is occured like
400, 403, 404, 405 and 415.
Controller
#Controller
#RequestMapping("/customer")
public class CustomerController {
#Autowired
CustomerService customerService;
// ........xxxxxx..............xxxxxxx................xxxxxxx.............//
#CrossOrigin
#RequestMapping(value = "/",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String fetchCustomer() throws JsonProcessingException {
return new ObjectMapper().writeValueAsString(customerService.fetchAllCustomer());
}
// ........xxxxxx..............xxxxxxx................xxxxxxx.............//
}
Client
$http({
method: "GET",
contentType: "application/json",
url: baseUrl + '/customer'
}).success(function (response) {
console.log(response);
// you can also use
console.log(JSON.stringify(response);
}).error(function (response) {
console.log(response);
});
When i request a service from client i want to send response back with status code and custom message.
Example
When i defind method = post on controller and from client i send request as get service should return message like
error:{
Status Code: 405,
Message: Invalid Method
url: error/405
}
Check this out for reference.
Define a method for handling the specific error scenario and annotate it as #ExceptionHandler. The exception in your scenario (request method not supported) is HttpRequestMethodNotSupportedException.class. You can create more generic handler methods using Throwable, Exception etc.
In order to prevent duplication of error handling across controllers, one convenient way is to define all handlers in single class and use #ControllerAdvice on that. This way, all handlers will be applied to all controllers.
Do not return a String but return a org.springframework.http.ResponseEntity.
You can add status codes to this object
ResponseEntity<String> responseEntity = new ResponseEntity<String>("This is a response", HttpStatus.INTERNAL_SERVER_ERROR);
return responseEntity;
So your method signature will also change as below
#RequestMapping(value = "/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody ResponseEntity<String> fetchCustomer() throws JsonProcessingException {
try {
String str = new ObjectMapper().writeValueAsString(customerService.fetchAllCustomer());
return new ResponseEntity<String>(str, HttpStatus.OK);
}
catch (Exception e) {
return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
If there is an error, you can either use controller advice or catch the exception and update the ResponseEntity appropriately

Spring Controller + Ajax return String

I want to return String from Spring MVC Controller to Ajax.
It is not working as expected and gives error.
My Ajax codes for this:
function ajaxRequest(item) {
$.ajax({
type: "POST",
url: "/myPage",
data: {
item: item
},
success: function (html) {
alert(html);
},
error: function(e) {
console.log("Error:" + e);
}
});
}
My Controller:
#RequestMapping(value = "/myPage", method= RequestMethod.POST, produces="text/plain")
public #ResponseBody String myController(HttpServletRequest request) {
String myItem = request.getParameter("item");
...
return myItem + "bla bla bla";
}
Chrome console result:
POST http://localhost:8080/myPage 406 (Not Acceptable) jquery.js
Error:[object XMLHttpRequest]
What am i missing here?
When you return a String from a handler method annotated with #ResponseBody, Spring will use a StringHttpMessageConverter which sets the return content-type to text/plain. However, your request does not have an Accept header for that content-type so the Server (your Spring app) deems it unacceptable to return text/plain.
Change your ajax to add the Accept header for text/plain.
I have solved it. We can return correct values with response writer.
#RequestMapping(value = "/myPage")
public void myController(HttpServletRequest request, HttpServletResponse response) throws IOException {
String myItem = request.getParameter("item");
...
response.getWriter().println(myItem + "bla bla bla");
}
Be sure that you have Jackson dependency. Spring MVC can relies on it.

Ajax pass a "Map" object to Spring MVC Controller

It seems like Spring MVC doesn't know how to map a javascript "map" to a Java map object
In the web UI, say, foo.jsp,
<script>
var myMap = {};
myMap["people"] = ["Alex","Bob","Charles","Dave"];
myMap["fruit"] = ["Apple","Orange"];
$.ajax({
type : "POST",
url : "/myURL",
data : "myMap=" + myMap, // I tried "myMap="+JSON.stringify(myMap), as well, it doesn't work neither
success : function(response) {
alert("Success! response = " + response);
},
error : function(e) {
alert("AJAX error");
}
});
</script>
On the server side, I have a data model class just to receive data from the Web UI
#Setter #Getter
class Parameters {
private Map<String, List<String>> myMap; //this is the java class I want to map the string to
}
And in the controller,
#RequestMapping(value = "/myURL", method = RequestMethod.POST)
#ResponseBody
public List<String> fooControl(Parameters parameters ) {
// do something with parameters ...
}
The error I got on the server side is like,
[tomcat:launch] Aug 14, 2013 3:12:37 PM org.apache.catalina.core.StandardWrapperValve invoke
[tomcat:launch] SEVERE: Servlet.service() for servlet dispatcher threw exception
[tomcat:launch] org.springframework.validation.BindException:
org.springframework.validation.BeanPropertyBindingResult: 1 errors
[tomcat:launch] Field error in object 'Parameters ' on field
'myMap': rejected value [{"people":["Alex","Bob","Charles","Dave"],"fruit":
["Apple","Orange"]}]; codes
[typeMismatch.repairInfomationParametersExperimental.constraints,typeMismatch.constraints,typeMismatch.java.util.Map,typeMismatch]; arguments
[org.springframework.context.support.DefaultMessageSourceResolvable: codes
[repairInfomationParametersExperimental.constraints,constraints]; arguments []; default message
[constraints]]; default message [Failed to convert property value of type 'java.lang.String' to
required type 'java.util.Map' for property 'constraints'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type
[java.util.Map] for property 'myMap': no matching editors or conversion strategy found]
I guess there is a way to tell Spring how to map that JSON format string a Java Map?
Thanks!
Modify javascript codes:
$.ajax({
type : "POST",
url : "/myURL",
contentType: "application/json",
data : JSON.stringify(myMap) // .....
Modify server side java codes:
#RequestMapping(value = "/myURL", method = RequestMethod.POST, consumes="application/json")
#ResponseBody
public List<String> fooControl(#RequestBody Map<String, List<String>> myMap) {
// do something with parameters ...
}
I have passed the Map object to Java using below code :
Javascript Code :
var values = {
"object1" : JSON.stringify(object1),
"object2" : JSON.stringify(object2)
};
var response = $http.post(url,data);
Server Side Code :
#RequestMapping(value = "/deleteData",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Result deleteData(#RequestBody HashMap<String, Object> dataHashMap) {
Object1 object1= (Object1) JsonConvertor.jsonToObject((String) dataHashMap.get("object1"), Object1.class);
Object2 object2= (Object2) JsonConvertor.jsonToObject((String) dataHashMap.get("object2"), Object2.class);
}

How to call #RequestMapping method of Controller having specified URL using AJAX

I'm very new to Spring and Portlet. I want to use jqgrid to show some list. I am trying to call a method in controller which is annoted with the #RequestMapping but the method is not being called
My Controller has following method
#Controller(value = "myController")
public class MyController {
#RequestMapping(value="/myURL",method=RequestMethod.GET)
public #ResponseBody MyDTO initItemSearchGrid(RenderResponse response, RenderRequest request){
MyDTO myDto=new MyDTO();
return myDto;
}
}
My JSP code using AJAX
var urlink="/myURL"; /* myURL is the exact String written in value Attribute of
resourceMapping in Controller*/
$.ajax({
url :urlink,
cache: false,
data:$('#myForm').formSerialize(),
dataType: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(jsondata){
...
}
});
When above AJAX code is executing my method is not called.
You mention Portlets in your question. Working with Spring and portlets is a bit different from servlets.
So, assuming you have a portlet like this
#Controller
#RequestMapping("VIEW") // VIEW mapping (as opposed to EDIT)
public class MyPortlet {
#RenderMapping
public ModelAndView handleRenderView(RenderRequest request, RenderResponse response) {
ResourceURL resourceUrl = response.createResourceURL();
resourceUrl.setResourceID("myResource"); // this is the id used to reference a #ResourceMapping
ModelAndView ret = new ModelAndView("myPortlet");
ret.addObject("resourceUrl", resourceUrl.toString());
return ret;
}
#ResourceMapping("myResource")
public void handleMyResource(ResourceRequest request, ResourceResponse response) {
OutputStream out = response.getPortletOutputStream();
// write whatever to output
}
}
As you can see, the #ResourceMapping is identified by a resource ID. The url for the resource mapping can be created using the standard portlet API methods and classes createResourceURL() and javax.portlet.ResourceURL.
If you prefer to use the portlet taglibrary instead, you can also generate a resource URL using the <portlet:resourceRequest> tag.
Your view might look something like this
myPortlet.jsp
...
<script>
$.ajax({
url :${resourceUrl},
cache: false,
data:$('#myForm').formSerialize(),
dataType: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(jsondata){
.........
.........
.........
}
});
</script>
...

Resources