I am trying call a spring mvc controller from a form in my page, this my controller.
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public ResourceDTO create(#RequestBody ResourceCreateDTO dto)
throws Exception {
ResourceDTO responseDTO = null;
//Add the resourceCreate and gets the responseDTO.
return responseDTO;
}
This my ajax call:
$.ajax({
type: "POST",
url: context + "/editor/create",
data: $("#createForm").serialize(),
cache: false,
success:function(result){
},
error:function(){
}
});
I'm getting this response: HTTP 415
This mi form call data (From developer view on Chrome):
resource-id:1006
resource-name:asdf
resource-description:asdfasdf
resource-folder:0
resource-folder-type:1000
resource-scene-width:
resource-scene-height:
I only have to use filled fields in this option. Not problem for empty fields.
Mi ResourceCreateDTO (serializable) have this fields:
private Integer resourceTypeId;
private Integer resourceId;
private String resourceName;
private String resourceDescription;
private Integer folderId;
private Integer resourceType;
private Integer sceneWidth;
private Integer sceneHeight;
/**GETTERS AND SETTERS**/
Related
Spring 5.0.7: MVC, Data, Security.
I configure multipartResolver.
I send next Ajax request:
$.ajax({
type: 'POST',
cache: false,
processData: false,
contentType: false,
url: '/api/v1/category/add',
data: new FormData(form)
}).done(result=>{console.log(result);}).fail(result=>{
console.error('ERROR:', result.responseJSON.httpStatus, result.responseJSON.message, result);
self.toast.error('API Error.');
});
But there is an error: Content type 'multipart/form-data;boundary=----WebKitFormBoundary6xBCDjCtYYuUVR5c' not supported
why? i don't understand why error happen.
Controller:
#RestController
#Secured("hasRole('ADMIN')")
#RequestMapping(value = "/api/v1")
public class ApiController {
private static final Logger LOGGER = LogManager.getLogger(ApiController.class);
#PostMapping(value = "/category/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
private Response categoryAdd(Response response, #RequestBody CategoryAddForm categoryAddForm) {
LOGGER.info(categoryAddForm.toString());
return response;
}
}
CategoryAddForm:
public class CategoryAddForm {
private String name;
private String description;
private MultipartFile preview;
public CategoryAddForm() { }
public CategoryAddForm(String name, String description, MultipartFile preview) {
this.name = name;
this.description = description;
this.preview = preview;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public MultipartFile getPreview() {
return preview;
}
}
I do not know what else to write, but SO requires more text. (
In your controller, use #RequestParam instead of #RequestBody.
Was having the same issue and it worked for me.
See this SO answer for more info
You need to add this maven dependency commons-fileupload:commons-fileupload:1.3.x
and declare MultipartResolver bean
#Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000);
return multipartResolver;
}
Above method is for Spring controllers. If you want to do for Async Spring controllers refer this article.
http://www.baeldung.com/spring-file-upload
Hope it helps!
I using a small code of Ajax and my code is working.There is no error in my code but when i set cache false in my ajax it add some value in request.I want to know What is the value and its purpose.
My code is
function validate() {
var user = $('#user').val();
var num = $('#num').val();
var mobile= $('#otp').val();
$.ajax({
type: "GET",
url: "/validateOtp",
data: {user: user , num: num , mobile: mobile},
dataType: 'text',
cache: false,
timeout: 600000,
success : function(response) {
alert( response );
},
error : function(xhr, status, error) {
alert(xhr.responseText);
}
});
}
it generate request like this in browser
http://localhost:8080/validateOtp?user=1234&num=12345&otp=1234&_=1528862398631
you can see the value added by ajax &_=1528862398631
and My backend code is in Spring MVC
#Controller
#RequestMapping("/validateOtp")
public class ValidateOTPAjaxController {
private final Logger logger =
LogManager.getLogger(this.getClass().getSimpleName());
#Autowired
private OTPService otpService;
#RequestMapping(method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
public String getAllDistrict(#RequestParam(value = "user") String user,
#RequestParam(value = "num") String num, #RequestParam(value = "mobile") String mobile) {
logger.debug(user);
logger.debug(num);
logger.debug(mobile);
return "OK";
}
By setting the cache property to false jQuery will append a timestamp to the URL, so the browser won't cache it (as the URL is unique for every request. See the documentation for details: http://api.jquery.com/jQuery.ajax/
And your controller should be like following:
#Controller
public class ValidateOTPAjaxController {
private final Logger logger =
LogManager.getLogger(this.getClass().getSimpleName());
#Autowired
private OTPService otpService;
#RequestMapping(value = "/validateOtp", method = RequestMethod.GET)
public String getAllDistrict(#RequestParam("user") String user,
#RequestParam("num") String num, #RequestParam("mobile") String mobile) {
logger.debug(user);
logger.debug(num);
logger.debug(mobile);
return "OK";
}
}
So, i need to add custom validation to my page, the problem is, i don't have any form, i collect and send data almost manually, here is my ajax post:
$.ajax({
type: "POST",
url: "/settings/propertyedit",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: {
propertyName : propName,
propertyValue : propVal,
Id : Id,
SettingId : SettingId,
},
beforeSend: function (xhr) {
xhr.setRequestHeader($.metaCsrfHeader, $.metaCsrfToken);
},
success: function (response) {
//Do some something good
},
error: function(response){
//do some something worning
}
});
And controller:
#Link(label = "property edit", family = "SettingsController", parent = "Settings")
#RequestMapping(value = "/settings/propertyedit", method = RequestMethod.POST)
#ResponseBody
public String atmpropertyedit(#RequestParam String propertyName,
#RequestParam String propertyValue,
#RequestParam Long Id,
#RequestParam Long SettingId) {
//Check if it is an error
//If correct i want to return some text in success function
//If error happens want to return some relevant text to error function
}
So, the point is, that validation is also custom, so i cant throw exception simply with try catch and if i am trying to do something like:
return new ResponseEntity<>(HttpStatus.NOT_EXTENDED);//Error type is for testing purposes
I will get 400 error even without triggering into my controller. At this point i just want some simple method to let know my ajax what has happened in my controller.
The controller can be as simple as this one, you can make it happen with custom response class which I named CommonResp and an Enum VALIDATION.
Controller - returns Response class.
#ResponseBody
public CommonResp atmpropertyedit(#RequestParam String propertyName,
#RequestParam String propertyValue,
#RequestParam Long Id,
#RequestParam Long SettingId) {
// error
if (!isValidPropertyName(propertyName)) return new CommonResp(VALIDATION.INVALID_PROPERTY_NAME);
// success
return new CommonResp(VALIDATION.OK);
}
}
CommonResp.java - will be the json response.
public class CommonResp implements Serializable {
private int code;
private String message;
public CommonResp() {
this(VALIDATION.OK);
}
private CommonResp(final int code, final String message){
this.code = code;
this.message = message;
}
public CommonResp(VALIDATION validation) {
this(validation.getCode(), validation.getMessage());
}
/* Getters and Setters */
}
VALIDATION.java
public enum VALIDATION {
OK(200, "OK"),
INVALID_PROPERTY_NAME(401, "PropertyName is not valid");
private int code;
private String message;
private VALIDATION(int code, String message) {
this.setCode(code);
this.message = message;
}
/* Getters and Setters */
}
Please let me know if there are any better implementations. (propably tons of, It's just that i don't know :P)
I have a view from where I am sending a request to a Controller and as a result getting response back to the view page. Now I want to pass the ajax response in to the next Controller but I do not know what will be the type of response in Controller
This is my ajax code:
$.ajax({
type: "POST",
url: "<c:url value="/menu/menucheckout/${restaurant_menu.name}"/>",
data : {"amount":amount, "orderoption" :orderoption, "date":date , "time":time ,'menuitemsArray': menuitemsArray ,'menuPriceArray': menuPriceArray , 'menuSpiceeArray': menuSpiceeArray , 'ItemQuantityArray': ItemQuantityArray },
success: function(response){
console.log(response);
window.location.href = "/BistroServicesMenuApp/welcome/getordercheckout/"+response.model;
}
});
Here is the Menu Controller
#Controller
#RequestMapping(value = "/menu")
public class MenuController {
#Autowired
private MenuTypeService menutypeService;
#RequestMapping(value="/menucheckout/{restaurantname}" ,method = RequestMethod.POST )
#ResponseBody
public ModelAndView menucheckout(#PathVariable("restaurantname") String restaurantname , HttpSession session, HttpServletRequest request, HttpServletResponse response) throws SQLException, NamingException, IOException
{
ModelAndView model = new ModelAndView("/welcome/getordercheckout");
System.out.println("COMING IN menucheckout CONTROLLER" + restaurantname);
System.out.println("orderoption" + request.getParameter("orderoption"));
String amount = request.getParameter("amount");
String orderoption = request.getParameter("orderoption");
String date = request.getParameter("date");
String time = request.getParameter("time");
String[] menuitemsArray = request.getParameterValues("menuitemsArray[]");
String[] menuPriceArray = request.getParameterValues("menuPriceArray[]");
String[] menuSpiceeArray = request.getParameterValues("menuSpiceeArray[]");
String[] ItemQuantityArray = request.getParameterValues("ItemQuantityArray[]");
model.addObject("restaurantname", restaurantname);
model.addObject("amount", amount);
model.addObject("orderoption", orderoption);
model.addObject("date", date);
model.addObject("time", time);
model.addObject("menuitemsArray", menuitemsArray);
model.addObject("menuPriceArray", menuPriceArray);
model.addObject("menuSpiceeArray", menuSpiceeArray);
model.addObject("ItemQuantityArray", ItemQuantityArray);
return model;
}
}
Now Here is the Second Controller "OrderController":
#Controller
#RequestMapping("/welcome")
public class OrderController {
#Autowired
private OrderService orderService;
#RequestMapping("/getordercheckout/{response}")
public ModelAndView getOrderCheckOut(#PathVariable("response") ModelAndView response)
{
ModelAndView model = new ModelAndView("/getordercheckout");
model.addObject("response" , response);
System.out.println("Response : " +response);
return model;
}
Now here I want to get the response but I am not sure what will be the datatype of reponse.
The System.out.println prints this error:
ModelAndView: reference to view with name '[object Object]'; model is null
Please Help me out as I am new to the Spring MVC.
Thank You in advance.
I'm searching how I can interprete a JSON parameter in my #ResourceMapping in Spring Portlet MVC. When I add #RequestBody, I got the message: #RequestBody is not supported... Really stuck on this one.
I have this:
View side:
<portlet:resourceURL var="getTest" id="ajaxTest" ></portlet:resourceURL>
<p>
<button onClick="executeAjaxTest();">Klik mij!</button>
<button onClick="$('#ajaxResponse').html('');">Klik mij!</button>
</p>
<p>
<h3>Hieronder het antwoord:</h3>
<h4 id="ajaxResponse"></h4>
</p>
<script>
function executeAjaxTest() {
var jsonObj = {
user: "Korneel",
password: "testpassword",
type: {
testParam: "test",
}
}
console.debug(JSON.stringify(jsonObj));
$.ajax({
dataType: "json",
contentType:"application/json",
mimeType: 'application/json',
url:"<%=getTest%>",
data:JSON.stringify(jsonObj),
success : function(data) {
$("#ajaxResponse").html(data['testString']);
}
});
}
</script>
Controller side:
#ResourceMapping(value="ajaxTest")
#ResponseBody
public void ajaxTestMethod(ResourceRequest request, ResourceResponse response) throws IOException, ParseException {
LOGGER.debug("ajax method");
JSONObject json = JSONFactoryUtil.createJSONObject();
json.put("testString", "Ik ben succesvol verstuurd geweest!");
response.getWriter().write(json.toString());
}
How can I use the spring magic to auto map this JSON data to my own model?
Note: It's Spring Portlet MVC, not regular Spring MVC..
#ResponseBody annotation is not supported out of the box in Spring MVC portlet framework, but you can implement #ResponseBody handling yourself.
We do it by implementing custom view type and model and view resolver.
Implement custom model and view resolver (ModelAndViewResolver), let's say JsonModelAndViewResolver.
In resolveModelAndView method, check whether controller method has #ResponseBody annotation (or more specific condition to identify JSON output - e.g. annotation + required supported mime type).
If yes, return your custom View implementation - let's say SingleObjectJson view (extending AbstractView).
Pass your to-be-serialized object to the view instance.
The view will serialize the object to JSON format and write it to the response (by using Jackson, Gson or other framework in renderMergedOutputModel method).
Register the new resolver as AnnotationMethodHandlerAdapter.customModelAndViewResolvers.
You need to build your json object like this:
var jsonObj = {
user: "Korneel",
password: "testpassword",
"type.testParam" : "test"
};
$.ajax({
dataType: "json",
contentType:"application/json",
mimeType: 'application/json',
url:"<%=getTest%>",
data:jsonObj,
success : function(data) {
$("#ajaxResponse").html(data['testString']);
}
});
In your Controller you should use the #ModelAttribute annotation:
#ModelAttribute(value = "jsonObj")
public JsonObjCommand obtenerJsonObjCommand() {
JsonObjCommand jsonObjCommand = new JsonObjCommand();
return jsonObjCommand;
}
#ResourceMapping(value = "ajaxTest")
public void ajaxTestMethod(
ResourceRequest request,
ResourceResponse response,
#ModelAttribute(value = "jsonObj") JsonObjCommand jsonObjCommand)
throws IOException, ParseException {
LOGGER.debug("USER: " + jsonObjCommand.getUser());
LOGGER.debug("Password: " + jsonObjCommand.getPassword());
LOGGER.debug("TestParam: " + jsonObjCommand.getType().getTestParam());
LOGGER.debug("ajax method");
JSONObject json = JSONFactoryUtil.createJSONObject();
json.put("testString", "Ik ben succesvol verstuurd geweest!");
response.getWriter().write(json.toString());
}
Don't forget your beans:
public class JsonObjCommand {
private String user;
private String password;
private TypeJson type;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public TypeJson getType() {
return type;
}
public void setType(TypeJson type) {
this.type = type;
}
}
public class TypeJson {
private String testParam;
public String getTestParam() {
return testParam;
}
public void setTestParam(String testParam) {
this.testParam = testParam;
}
}
According to the documentation, #RequestBody is only supported in Servlet environments, not Portlet environments (same for #ResponseBody). So it seems you can't use that functionality.