I'm trying to delete multiple Items with the same name in my web app. But it's giving me an error 500 when I do the POST.
This is my Form Code
<form method="POST" name="deleteFormAdd" id="deleteFormAdd" enctype="multipart/form-data">
<input type="hidden" name="_csrf" th:value="${_csrf.token}" />
<!--Asset ID set to hidden so the User can't see it-->
<input type="hidden" th:each="deleteCategory, itemStat : ${DeleteCategoryObject}"
th:name="assetID"
th:value="${deleteCategory.assetID}"/>
<!-- For showing all the Asset to be deleted -->
<input class="w3-input w3-border w3-round-large" type="text"
th:each="deleteCategory, itemStat : ${DeleteCategoryObject}"
th:name="${DeleteCategoryObject[__${itemStat.index}__].assetType}"
th:value="${deleteCategory.assetType}"
disabled="disabled"/>
<br></br>
<input type="button" class="btn btn-primary btn-block" value="Yes" th:onclick="'javascript:submitForm(\'deleteFormAdd\',\''+#{/delete-asset}+'\')'" />
<button type="reset" onclick="window.location.href = 'manage-assets.html';" class="btn btn-default btn-block"> Cancel</button>
</form>
Submit Form Ajax
function submitForm(formID, url){
var formData = new FormData($("#" + formID)[0]);
$.ajax({
dataType: 'json',
url: url,
data : formData,
type : "POST",
enctype : "multipart/form-data" ,
processData : false,
contentType : false,
success : function(data) {
if (data.status == 1) {
openAlertDialog("Success", "The Asset type has been deleted!", "Continue", "manage-assets");
} else {
openAlertDialog("Error", data.message, "Continue", "manage-assets");
}
},
error : function(data) {
openAlertDialog("Error", data.message, "Continue", "manage-assets");
},
});
}
Spring Controller
#RequestMapping(value = "/delete-asset", method = RequestMethod.POST)
public #ResponseBody String deleteAsset(#ModelAttribute List<AssetCategory> assetCategories) {
JsonObject result = new JsonObject();
if (assetCategories != null && !assetCategories.isEmpty()) {
String[] arr = new String[assetCategories.size()];
for (int i =0; i < assetCategories.size(); i++) {
arr[i] = assetCategories.get(i).getAssetID();
}
assetService.deleteAssets(arr);
result.addProperty("result", "Success");
result.addProperty("status", 1);
result.addProperty("message", "Asset Deleted!");
}
return result.toString();
}
Spring Service
#Override
public AssetCategory deleteAssets(String[] assetID) {
return dao.deleteAssets(assetID);
}
Spring DAO
#Query("Delete From AssetCategory A WHERE A.assetID IN (:assetID)")
public AssetCategory deleteAssets(#Param("assetID") String[] assetID);
Spring Console Error
Failed to instantiate [java.util.List]: Specified class is an interface] with root cause
org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface
This is the Form Data (it contains the asset ID's)
Seems issue with your ajax function. Check with below:
function submitForm(formID, url) {
var assetIdList = [];
var assetIdObj;
$("#" + formID).find('input[name="assetID"]').each(function () {
assetIdObj = {};
assetIdObj.assetID = $(this).val();
assetIdList.push(assetIdObj);
});
$.ajax({
dataType: 'json',
url: url,
data: {assetCategories: assetIdList},
type: "POST",
enctype: "multipart/form-data",
processData: false,
contentType: false,
success: function (data) {
if (data.status === 1) {
openAlertDialog("Success", "The Asset type has been deleted!", "Continue", "manage-assets");
} else {
openAlertDialog("Error", data.message, "Continue", "manage-assets");
}
},
error: function (data) {
openAlertDialog("Error", data.message, "Continue", "manage-assets");
},
});
}
Update this html code from:
<input type="hidden" th:each="deleteCategory, itemStat : ${DeleteCategoryObject}"
th:name="assetID"
th:value="${deleteCategory.assetID}"/>
To this:
<input type="hidden" th:each="deleteCategory, itemStat : ${DeleteCategoryObject}"
name="assetID"
th:value="${deleteCategory.assetID}"/>
You are using multipart/form-data. So, your request header has multipart/form-data Content-Type which have data as form type. like key=value.
So just remove #ModelAttribute annotation and add consumes properties to your mapping annotation.
//if you're using spring version more than 4.3, use below #PostMapping for readability
//#PostMapping(value = "/delete-asset", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
#RequestMapping(value = "/delete-asset", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public #ResponseBody String deleteAsset(List<AssetCategory> assetCategories) {
JsonObject result = new JsonObject();
//you can use apache's commons-collection
if (CollectionUtils.isNotEmpty(assetCategories)) {
//and you can also use stream api
String[] arr = assetCategories.stream()
.map(AssetCategory::getAssetID)
.toArray();
assetService.deleteAssets(arr);
result.addProperty("result", "Success");
result.addProperty("status", 1);
result.addProperty("message", "Asset Deleted!");
}
return result.toString();
}
Related
I was having some problem when trying to put multiple buttons in one JSP form.
<form:form action="/search" method="POST">
<tr>
<td align="left">
<input type="button" onclick="valSubmit('doImageExtractSearchList', this.form);" value="Image Extract" />
</td>
<td align="right">
<input type="button" onclick="valSubmit('doCardIssueSearchList', this.form);" value="Card Search" />
</td>
</tr>
</form:form>
In my controller class, how can I differentiate it comes from which button and specify the API?
#RequestMapping(value = "/search", method = { RequestMethod.POST })
public String doSubmit() {
return "";
}
#RequestMapping(value = "/imageExtract", method = { RequestMethod.POST })
public String doSubmit() {
return "";
}
#RequestMapping(value = "/cardSearch", method = { RequestMethod.POST })
public String doSubmit() {
return "";
}
Thanks!
Since you already trigger a function call on click , why don't you use the function to make an Ajax call to the backend api . That way you could provide separate url for the POST call depending upon the parameter passed into the jquery method like :
function valSubmit(value, form) {
var url;
if(value == "doImageExtractSearchList") {
url = "http://something/search/imageExtract";
}
else if(value == "doCardIssueSearchList") {
url = "http://something/search/cardExtract";
}
var form = $('#formId');
var data = form.serialize();
$.ajax({
type: "POST",
url: url,
data: data,
success: function(result) {
alert('ok');
},
error: function(result) {
alert('error');
}
});
}
The origin server is refusing to service the request because the payload is in a format not supported by this method on the target resource.
Controller code
#RestController
public class UserController
{
#Autowired
public IretrieveService retrieveService;
#RequestMapping(value="/register", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ModelAndView doRegister(#RequestBody UserBean userBean,BindingResult result)
{
ModelAndView view = new ModelAndView("index");
System.out.println("username "+userBean.getUsername());
if(!result.hasFieldErrors())
{
if(retrieveService.insert(userBean) != null)
{
System.out.println("done");
}
}
return view;
}
}
Angular js code
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller("UserController", ['$scope', '$http', function($scope, $http, httpPostService) {
var self=this;
self.userBean={username:''};
$scope.insertData = function()
{
alert($scope.userBean.username);
$http({
method: "POST",
url: "register",
data: $scope.userBean.username
}).then(function(response){
console.log(response.status);
console.log("in success");
}, function(response){
console.log(response.status);
console.log("in fail");
});
};
}]);
</script>
<form method="post" action="register" name="myForm">
<label for="username" class="control-label">First Name:</label>
<input type="text" data-ng-model="userBean.username" class="form-control" placeholder="Enter Firstname"/>
<button type="submit" data-ng-click="insertData()" class="btn btn-primary">Submit</button>
</form>
Error comes but didn't pass value from angular js to controller class
You are getting 415 http error because of your controller expects application/json but you are sending raw string data.
Here is a working example of how to post json data:
Javascript:
var data = { "name":"emre" }
$.ajax({
type: "POST",
url: "http://localhost:8080/yourUrl",
data: JSON.stringify(data),
contentType: "application/json",
cache: false,
timeout: 600000,
success: function (data) {
alert("success")
},
error: function (e) {
alert("ERROR : ", e);
}
});
Controller :
#CrossOrigin
#PostMapping
public ResponseEntity post(#RequestBody UserBean request) {
return ResponseEntity.status(HttpStatus.CREATED).body(request); // your response
}
UserBean class :
#Data // comes from lombok for getter setter purpose
class UserBean {
private String name;
}
You can adjust controller and javascript according to your needs.
It looks to me like the data you send to the controller is a String and not a UserBean object. Your payload is $scope.userBean.username but your controller expects #RequestBody UserBean userBean.
Changing the controller to
public ModelAndView doRegister(#RequestBody String userName, BindingResult result)
might solve the problem.
I have this form
<div class="row">
<h1 class="page-header">
Create
</h1>
<form ng-submit="create()", enctype="multipart/form-data">
<div class="form-group">
<label>Name:</label>
<input type="text" ng-model="subforum.name" class="form-control" />
</div>
<div class="form-group">
<label>Desc:</label>
<input type="text" ng-model="subforum.desc" class="form-control" />
</div>
<input type="file" ngf-select ng-model="subforum.icon" name="subforum.icon"
accept="image/*" ngf-max-size="2MB" required
ngf-model-invalid="errorFile">
<img ng-show="myForm.file.$valid" ngf-thumbnail="subforum.icon" class="thumb"> <button ng-click="subforum.icon= null" ng-show="subforum.icon">Remove</button>
<button class="btn btn-success" type="submit">Create</button>
</form>
``
In my JS
.config(function($stateProvider) {
$stateProvider.state('create', {
url:'/subforum/create',
views: {
'main': {
templateUrl:'subforum/create.tpl.html',
controller: 'CreateCtrl'
}
},
data : { pageTitle : "Create Subforum" }
})
and
.factory('subforumService', function($resource) {
var service = {};
service.create = function (subforum, success, failure) {
var SubForum= $resource ("/web-prog/rest/subforums");
SubForum.save({}, subforum, success, failure) ;
};
.controller("CreateCtrl", function($scope, $state, subforumService) {
$scope.create = function() {
$scope.subforum.author = JSON.parse(localStorage.getItem ("logedUser"));
subforumService.create($scope.subforum,
function(returnedData) {
$state.go("home");
},
function() {
alert("Error creating");
});
};
I know thats not best practice to save user in LocalStorage but for now its like that.
On backend i have controller and in that controller i have methode:
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity<SubForumResource> createPodforum(#RequestBody SubForumResource sentPodforum) {
}
and SubForumResource is
public class PodforumResource extends ResourceSupport {
private String name;
private String desc;
private byte[] icon;}
with geters and seters and everything i need.
So when i have form without image it works without problems. But i need icon too. Im new to angularjs but need it for this project. When i try to use FormData() i dont know how to use $resource. So if someone can help me i would be thankful. This is my first prject i need to work front end so im lost.
You can refer below code for angularjs :
this.addEmployee = function (requestData, file) {
var data = new FormData();
data.append('file', file[0]);
data.append('requestData', new Blob([JSON.stringify(requestData)], {
type: "application/json"
}));
var config = {
transformRequest: angular.identity,
transformResponse: angular.identity,
headers: {
'Content-Type': undefined
}
}
var url = "http://localhost:8080/addEmployee";
var promise1 = $http.post(url, data, config);
var promise2 = promise1.then(function (response) {
return response.data;
},
function errorCallback(response) {
alert(response.data.errorMessage);
});
return promise2;
}
And for controller :
#RequestMapping(value = "/addEmployee", method = RequestMethod.POST, consumes = {"multipart/form-data" })
#CrossOrigin
public CustomResponse addEmployee(#RequestPart("file") MultipartFile file, #RequestPart("requestData") Employee emp) {
}
I am having a problem uploading picture in Spring. I have encountered countless problems, which i have tried to solve. For my current error i have tried all the solution provide by spring but it still persist. According to spring the issue of MissingServletRequestPartException can be solved by including a MultipartResolver.`http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/multipart/support/MissingServletRequestPartException.html. I have done that (find below), but the issue still persist.
Error
timestamp: 1490599131962, status: 400, error: "Bad Request",…}
error:"Bad Request"
exception:"org.springframework.web.multipart.support.MissingServletRequestPartException"
message:"Required request part 'uploadfile' is not present"
path:"/uploadFile"
Config
#Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000);
return new CommonsMultipartResolver();
}
Controller
public ResponseEntity<?> uploadFile(#RequestParam("uploadfile") MultipartFile uploadfile, Picture picture, Principal principal, MultipartHttpServletRequest request) {
User user = (User) ((UsernamePasswordAuthenticationToken) principal).getPrincipal();
picture.setUser(user);
Iterator<String> itrator = request.getFileNames();
MultipartFile multiFile = request.getFile(itrator.next());
try {
System.out.println("File Length:" + multiFile.getBytes().length);
System.out.println("File Type:" + multiFile.getContentType());
// Crop the image (uploadfile is an object of type MultipartFile)
BufferedImage croppedImage = cropImageSquare(multiFile.getBytes());
String fileName=multiFile.getOriginalFilename();
System.out.println("File Name:" +fileName);
String path=request.getServletContext().getRealPath("/");
// Get the filename and build the local file path
File directory= new File(path+ "/uploads");
directory.mkdirs();
String filename = uploadfile.getOriginalFilename();
String ext = FilenameUtils.getExtension(filename);
File outPutFile = new File(directory.getAbsolutePath()+System.getProperty("file.separator")+picture.getUploadfile());
ImageIO.write(croppedImage, ext, outPutFile);
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
pictureService.save(picture, uploadfile);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
JS FILE
'use strict';
var $formUploader = $("#upload-file-input");
$formUploader.on("submit", function(e){
e.preventDefault();
var data = new FormData(this);
$.each($formUploader.serializeArray(), function(i, field) {
data[field.name] = field.value;
});*/
$.ajax({
//dataType: 'json',
url: $formUploader.prop('action'),
type: "POST",
//data: new FormData($("#upload-file-input")[0]),
data: data,
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
success: function (data) {
console.log(data);
// Handle upload success
$("#upload-file-message").text("File succesfully uploaded");
},
error: function (response) {
console.log(response);
// Handle upload error
$("#upload-file-message").text("File not uploaded (File might be big, size needed.)");
}
});
});
Form
<form id="upload-file-input" th:action="#{/uploadFile}" method="post" th:object="${picture}"
enctype="multipart/form-data" class="form-inline inline new-item">
<div th:replace="common/layout :: flash"></div>
<fieldset>
<legend> Upload Picture</legend>
<div class="row">
<div class="col s12 l8">
<div class="file-wrapper">
<input type="file" id="file" name="uploadfile" />
<span class="placeholder" data-placeholder="Choose an image...">Choose an image...</span>
<label for="file" class="button">Browse</label>
<span id="upload-file-message"></span>
</div>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</fieldset>
<div class="style16"></div>
</form>
You added all form values into the FormData, but didn't add a content of file. That's how it can be done:
...
var data = new FormData(this);
$.each($formUploader.serializeArray(), function(i, field) {
data[field.name] = field.value;
});
//next line will add content of file
data.append('fileContent', $('#file').files[0]);
$.ajax({ ...
You can use any name instead of fileContent, it doesn't matter.
In case when user enables to select multiple files at once, you have to add contents of all of this files:
...
var data = new FormData(this);
$.each($formUploader.serializeArray(), function(i, field) {
data[field.name] = field.value;
});
$.each($('#file').files, function(i, file) {
formData.append('fileContent' + i, file);
});
$.ajax({ ...
Below is my code attempt to post an Json serialize object (java pojo having list of other pojos) with JQuery Ajax call to Spring MVC controller.
Getting Bad request error from server.
When the modalForm data is removed from the Json object the MainPojo data received correctly at server side.
Html Code
Fisrt form
-------------
<form id="mainForm">
.....
</form>
Form in the modal
-----------------
<form id="modelform" ..>
<div id="row">
<input type="text" id="subject" />
<input type="text" id="max" />
<input type="text" id="min" />
</div>
<div id="row">
<input type="text" id="subject" />
<input type="text" id="max" />
<input type="text" id="min" />
</div>
.............
</form>}
Jquery
var mainObject = $('#mainForm').serializeObject();
var modelObject = $('#modelform').serializeObject();
mainObject.marks = modelObject;
Json ( Expected)
{
"name": "Some Name",
"age": "10",
"marks": [
{
"subject": "maths",
"max": "20",
"min":"12"
},
{
"subject": "english",
"max": "20",
"min":"12",
}
]
}
Json (actual output with the above code)
{
"name": "Some Name",
"age": "10",
"marks": [
{
"subject": "maths",
"subject": "english"
},
{
"max": "20",
"max":"20",
},
{
"min": "12",
"min":"12"
}
]
}
//Ajax call
$.ajax({
url: '/save',
type: 'POST',
contentType: 'application/json',
mimeType: 'application/json',
data : JSON.stringify(mainObject),
dataType: 'json',
success: function(data) {
alert(data.msg);
},
error:function (xhr, ajaxOptions, thrownError) {
alert('Technical error occured');
}
});
Java Pojo's
public class MainPojo {
private String name;
private String age;
private Lists<marks>
..................
}
public class ModelPojo {
private String subject;
private String maxMarks;
private String minMarks;
.....................
}
Controller Method
#RequestMapping(value = "save", headers = "Accept=application/json",
method = RequestMethod.POST)
public #ResponseBody String save(#RequestBody final MainPojo mainPojo) {
}
Please help me to identify the problem.
Thank You.
Modify html text like this
<form id="mainForm">
<input name="name" type="text" value="Some Name">
<input name="age" type="text" value="20">
</form>
<form class="modelform">
<input type="text" value="subject" name="subject"/>
<input type="text" value="max" name="max"/>
<input type="text" value="min" name="min"/>
</form>
<form class="modelform">
<input type="text" value="subject" name="subject" />
<input type="text" value="max" name="max"/>
<input type="text" value="min" name="min"/>
</form>
Then write javascript code to assign object value
<script>
var mainObject = $('#mainForm').serializeObject();
var modelObject = [];
$('.modelform').each(function(o){
modelObject.push($(this).serializeObject());
})
mainObject.marks = modelObject;
</script>
i have
#RequestMapping(value = "/save", method = RequestMethod.POST)
public #ResponseBody
MyEvent saveOrganization(#RequestBody Organization organization) {
return new MyEvent('save',organization);
}
y your mvc-servlets.xml
<context:component-scan base-package="com.jrey.project.controllers" />
<context:annotation-config></context:annotation-config>
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
my jquery post
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [ o[this.name] ];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
<script>
$(document)
.ready(
function() {
$('.submit', '#form')
.click(
function() {
var data = JSON
.stringify($('#form')
.serializeObject());
console.log(data);
$
.ajax({
type : "POST",
url : '${pageContext.request.contextPath}/controller/organization',
data : data,
dataType : 'json',
contentType : 'application/json;charset=UTF-8',
success : function(data) {
$(
'<div>'
+ data.message
+ '</div>')
.dialog(
{
title : 'Organizacion',
modal : true,
buttons : {
'Aceptar' : function() {
document.location.href = data.location;
}
}
}
);
},
});
});
});