Spring ParamsInterceptor complains about #RequestParam- BEFORE REQUEST - ajax

i'am sending ajax get request to spring mvc handler and i can pass parameter-values.
Problem is, that i became ERROR everytime:
spring.interceptor.ParamsInterceptor - BEFORE REQUEST:
org.springframework.beans.NotWritablePropertyException: Invalid
property 'fromDate' of bean class
[com.example.CallDbController]: Bean
property 'fromDate' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the
getter?
[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
My Ajax-Requst:
$.ajax({
type : "GET",
url : 'myUrl.action',
data : {
"fromDate" : start
},
success : function(msg) {
console.log('something to do...');
}
});
and my controller handler:
#Controller
#RequestMapping("/calldb/*")
public class CallDbController {
#RequestMapping(value = { "myUrl.action" }, method = RequestMethod.GET)
public #ResponseBody String[] getTimeDifference(#RequestParam("fromDate") String startDate) {
//something to do...
}
}
I'am confusing, that "fromDate" Request-Parameter from GET-Request
is being interprited as Bean-Property.

i've finde my problem. Exception has been thrown due to Implementation of some interceptor.

Related

upgrading spring boot with groovy controller returns 406 causing HttpMediaTypeNotAcceptableException

I have a Groovy application that I am dealing with which is having some odd behavior when upgrading from spring-boot 1.3.0.RELEASE to 1.4.0.RELEASE. The controller always returns a 406 on any error and I am not sure what type of content it expects to return. The code is below:
SomeController.groovy:
#RestController
#RequestMapping('/some/mapping')
class SomeController extends AbstractController {
#Autowired
private SomeService someService
#RequestMapping(path = '/abc/{some_param}/some_action', method = RequestMethod.PUT, consumes = MediaType.TEXT_PLAIN_VALUE)
#ResponseStatus(HttpStatus.NO_CONTENT)
#PreAuthorize('isAuthenticated() && (principal.username == #username || principal.admin)')
void setValue(#PathVariable String some_param, #RequestBody String body_content) throws ValidationException, NotFoundException {
handleViolations(validate(AnObject, [some_param: some_param, body: body_content]))
try {
someService.setValue(some_param, body_content)
} catch(AlreadyExistsException e) {
throw new ValidationException([body: 'IN_USE'])
}
}
}
SomeControllerSpec.groovy < The test...
class AccountControllerSpec extends AbstractControllerSpec {
static final BASE_URL = 'http://localhost:8080/api/'
def client = new CustomRESTClient(BASE_URL)
// This test fails
def 'testing api'() {
//Expected 400 bad request but receiving a 406 not acceptable
client.put(
path: "/api/abc/fake_param/some_action",
// The body doesn't conform to the expectations of the API
body: 'blah',
contentType: MediaType.TEXT_PLAIN_VALUE
).status == HttpStatus.SC_BAD_REQUEST
// Exception thrown:
// INFO 22125 --- [tp1838490665-22] c.c.w.c.RestEndpointsConfiguration : org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
}
}
The Exception in the logs:
INFO 22125 --- [tp1838490665-22] c.c.w.c.RestEndpointsConfiguration : org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
I have tried many things including setting the expected header type:
client.setHeaders(accept: MediaType.TEXT_PLAIN_VALUE)
I have been trying various other things but to no avail. The exception persists.
Note: The action at the endpoint completes as expected.

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 MVC Ajax form properties name

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
}

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);
}

Resources