I've been working on a little project with Java Spring. I've already set the table structure in Navicat to be able "null" values. I have also set the model to be able to null values.
But still, I can't input null values into the column and received this error messages.
FYI: I'm using Spring Tool Suite 3.9.7 IDE
Field error in object 'sertifikasihapus' on field 'modified_on': rejected value [];
codes [typeMismatch.sertifikasihapus.modified_on,typeMismatch.modified_on,typeMismatch.java.sql.Timestamp,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [sertifikasihapus.modified_on,modified_on];
arguments [];
default message [modified_on]];
default message [Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Timestamp' for property 'modified_on';
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [#javax.persistence.Column java.sql.Timestamp] for value '';
nested exception is java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]]]
<script>
$('#idBtnHapusHapus').click(function() {
var vDataRole = $('#idFrmHapusSertifikasi').serialize();
var angka = $('#Id').val();
var nama = $('#idNamaSertifikasi').val();
if ($("#idModifiedOn").val().length < 1) {
$('#idModifiedOn').val(null);
debugger;
$.ajax({
url : './hapussertifikasi/' + angka,
type : 'Put',
data : vDataRole,
dataType : "json",
success : function(model) {
debugger;
window.location = './sertifikasi'
},
error : function(model) {
debugger;
}
});
} else {
debugger;
$.ajax({
url : './hapussertifikasi/' + angka,
type : 'Put',
data : vDataRole,
dataType : "json",
success : function(model) {
debugger;
window.location = './sertifikasi'
},
error : function(model) {
debugger;
}
});
}
});
</script>
<div class="col-xs-12">
<div class="row">
<form id="idFrmHapusSertifikasi" method="post">
<input type="hidden" class="form-control" id="Id" name="id"
placeholder="">
<input type="hidden" class="form-control"
id="idNamaSertifikasi" name="certificate_name" placeholder="">
<input type="hidden" class="form-control" id="idBulanBerlaku"
name="valid_start_month" placeholder="">
<input
type="hidden" class="form-control" id="idTahunBerlaku"
name="valid_start_year" placeholder="">
<input
type="hidden" class="form-control" id="idPenerbit" name="publisher"
placeholder="">
<input type="hidden" class="form-control"
id="idBulanBerlakuS" name="until_month" placeholder="">
<input
type="hidden" class="form-control" id="idTahunBerlakuS"
name="until_year" placeholder="">
<input type="hidden"
class="form-control" id="idCatatan" name="notes" placeholder="">
<input type="hidden" class="form-control" id="idCreateOn"
name="createOn" placeholder="">
<input type="hidden"
class="form-control" id="idCreateBy" name="createBy" placeholder="">
<input type="hidden" class="form-control" id="idModifiedOn"
name="modified_on" placeholder="">
<input type="hidden"
class="form-control" id="idModifiedBy" name="modified_by"
placeholder="">
</form>
<div class="col-xs-2">
<i class="glyphicon glyphicon-trash center" style="font-size: 50px"></i>
</div>
<div class="col-xs-8">
<div class="clTulisanHapus center" id="idTulisanHapus">
<p>Anda Yakin ingin menghapus Sertifikasi</p>
<!-- I WANTED THE CERTIFICATE NAME TO BE HERE -->
<div th:each="item:${oneprofil}">
<b><p th:text="${item.certificate_name}+' ?'"></p></b>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-offset-8">
<div class="btn-group">
<input type="hidden" id="idDataId"> <input type="hidden"
id="idDataNama">
<button type="button" id="idBtnHapusBatal" data-dismiss="modal"
class="btn clBtnMdlHapus">Tidak</button>
<button type="button" id="idBtnHapusHapus" data-id="${item.id}"
class="btn clBtnMdlHapus">Ya</button>
</div>
</div>
Looks like your value is not null but an empty String (""). You can use the keyword null without any "quotation marks".
For more info, see this question:
in practice you can simply pretend that it's "merely a special literal that can be of any reference type".
[Failed to convert property value of type 'java.lang.String' to
required type 'java.sql.Timestamp' for property 'modified_on';
You are receiving the value as an empty string instead of null which leads to type mismatch and causing the issue.
From HTML I see that you are sending it as for hidden parameter. There is an alternative way to automatically set the creation date and modified date in Spring Boot.
Use below in Entity
#PrePersist
protected void prePersist() {
createdAt = set value here
}
#PreUpdate
protected void preUpdate() {
modifiedOn = set valye here
}
Hibernate
#CreationTimestamp - Documentation
#UpdateTimestamp - Documentation
Spring Data JPA
#CreatedDate - Documentation
#LastModifiedDate - Documentation
Related
I'm trying to upload a file to cloudinary. I'm stucked at how to only get parts of image from the form. It keeps on throwing exception: Invalid image file. If I remove all text inputs in the form, the uploading is successful. I guess that happens because the form also has text inside. Please help me solve this. I'm really grateful for your support.
Here is my code:
Form.jsp:
<form role="form" action="<c:url value="/admin/product/update"/>" method="post" enctype="multipart/form-data">
<input name="id" value="${product.id}" hidden="">
<div class="form-group">
<label>Name:</label> <input class="form-control" value="${product.name}" name="name" />
</div>
<div class="form-group">
<label>Price:</label> <input class="form-control" value="${product.price}" type="number" name="price" />
</div>
<div class="form-group">
<label>Quantity:</label> <input class="form-control" value="${product.quantity}" type="number" name="quantity" />
</div>
<div class="form-group">
<label>Image:</label> <input class="form-control" value="${product.image}" name="image" />
</div>
<div class="form-group">
<label>Description </label> <br>
<textarea rows="4" cols="50" name="description" value="${product.description}" ></textarea>
</div>
<div class="form-group">
<label>Category</label>
<div class="checkbox">
<select name="catid">
<c:forEach items="${categorylist}" var="c">
<option value="${c.id}">${c.name}</option>
</c:forEach>
</select>
</div>
</div>
<div class="form-group">
<label>image</label> <input type="file" name="image" value="${product.image }" />
</div>
Servlet.java
BeanUtils.populate(product, request.getParameterMap());
//if (catid != product.getCategory().getId()) {
// Category category = new Category();
category = dao2.getCategoryByID(catid);
product.setCategory(category);
Map result = null;
Collection<Part> fileParts = request.getParts();
for (Part part : fileParts) {
String fileName = part.getSubmittedFileName();
result = UploadImage.uploadImage(fileName, part);
String url = String.valueOf(result.get("url"));
product.setImage(url);
if (result == null) {
throw new RuntimeException("Loi upload");
}
}
dao.update(product);
The Cloudinary upload method supports uploading media files from the sources like a local path, a remote URL, a private storage URL (S3 or Google Cloud storage), a base64 data URI, or an FTP URL.
Based on your code, it seems that you are only supplying the filename of the image.
String fileName = part.getSubmittedFileName();
result = UploadImage.uploadImage(fileName, part);
You would need to update the code to input the local path of the image.
Below is code from a controller that I'm aiming to make sure it's receiving two input parameters (name and code) from a front-end interface.
It's a page that takes two parameters within a submit form, "name" and "code".
#RequestMapping(method = RequestMethod.POST)
public String transfer(#RequestParam(name = "name") String name,
#RequestParam(name = "code") String code,
Errors errors, RedirectAttributes redirectAttributes) {
if (errors.hasErrors()) {
return "htmlPageOne";
}
try {
User userToBeTransferred = usersRepository.findByName(name);
userToBeTransferred.setTransferred(true);
Region regionOfTransference = regionsRepository.findByCode(code);
regionOfTransference.setPopulationNumber(regionOfTransference.getPopulationNumber() + 1);
userToBeTransferred.setRegion(regionOfTransference);
usersRepository.save(userToBeTransferred);
regionsRepository.save(regionOfTransference);
return "redirect:/section/users/new";
} catch (IllegalArgumentException e) {
return "htmlPageOne";
}
}
The front-page form :
<form class="form-horizontal" method="POST" action="/section/users/new" th:object="${user}">
<input type="hidden" th:field="*{id}"/>
<div class="form-group row">
<label for="name" class="col-form-label">User name</label>
<input type="text" class="form-control" id="name" th:field="*{name}" name="name"/></div>
<div class="form-group row">
<label for="code" class="col-form-label">Code</label>
<input type="text" class="form-control" id="code" th:field="*{region.code}" name="code"/></div>
<button type="submit" class="btn btn-primary col-sm-6 ">Save</button>
</form>
For some reason, I'm getting the following error after I click to submit the form :
There was an unexpected error (type=Internal Server Error, status=500).
An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments to which they apply: public java.lang.String
I'm not sure if I'm using the requestparams correctly, so maybe it's got something to do with this? I don't know, I've been stuck on this for a few hours now, so would appreciate if someone could help me.
So, I'm trying to to a POST request to a local Spring MVC project, but every time I try, I keep getting 400: Bad Request, with the error specified in the title. Not sure why, because when I check what's being sent, it's correct.
Spring REST controller request
#RequestMapping(value="/add", method = RequestMethod.POST)
void addPet(#RequestParam String name, #RequestParam String photo, #RequestParam String status) {
Pet pet = new Pet(name, photo, status);
this.petRepo.save(pet);
}
AngularJS request sending the data
$http({
method: "post",
url: "http://localhost:8080/pet/add",
data:{
name: angular.element("#name")[0].value,
photo: angular.element("#photo")[0].value,
status: angular.element("#status")[0].value
}
}).success(function(data, status) {
})
.error(function(data, status) {
alert("Error");
console.log(data);
console.log(status);
});
front-end HTML that's calling the AngularJS function
<div class="form-group">
<label for="name">Pet Name</label>
<input type="text" class="form-control" id="name">
</div>
<div class="form-group">
<label for="photo">Photo URL</label>
<input type="text" class="form-control" id="photo">
</div>
<div class="form-group">
<label for="status">Status</label>
<input type="text" class="form-control" id="status" placeholder="Something descriptive like 'Available' or 'Taken'">
</div>
<div class="form-group">
<div class="btn-group">
<button type="button" class="btn btn-primary" ng-click="preview()">Preview</button>
<button type="button" class="btn btn-success" ng-click="submit()">Submit</button>
<button type="button" class="btn btn-danger" ng-click="clear()">Clear</button>
</div>
</div>
You are using #RequestParam in the backend but in angular you are putting the values in the body of the request.
You have to use #RequestBody in the backend or adjust the frontend to put the values in url parameters.
Found the answer. I followed SSH's answer above for the front-end, and for the backend, I changed the function to:
void addPet(#RequestBody Pet pet)
try like this
<div class="form-group">
<label for="name">Pet Name</label>
<input type="text" class="form-control" ng-model="form.name" id="name">
</div>
<div class="form-group">
<label for="photo">Photo URL</label>
<input type="text" class="form-control" ng-model="form.photo" id="photo">
</div>
<div class="form-group">
<label for="status">Status</label>
<input type="text" class="form-control" ng-model="form.status" id="status" placeholder="Something descriptive like 'Available' or 'Taken'">
</div>
<div class="form-group">
<div class="btn-group">
<button type="button" class="btn btn-primary" ng-click="preview()">Preview</button>
<button type="button" class="btn btn-success" ng-click="submit(form)">Submit</button>
<button type="button" class="btn btn-danger" ng-click="clear()">Clear</button>
</div>
</div>
and in controller use this
$scope.form = {"name":"","photo":"","status":""}
$http({
method: "post",
url: "http://localhost:8080/pet/add",
data:{
name: $scope.form.name,
photo: $scope.form.photo,
status: $scope.form.status
}
}).success(function(data, status) {
})
.error(function(data, status) {
alert("Error");
console.log(data);
console.log(status);
});
i cant get the value of a freeMarker variable when i put my code in a external javascript file
here is my page when the javascript code inside, this works i can get the value of my freemarker variable in this way:
<#import "../masterPage.html" as layout>
<#layout.masterPageLay bread1="my bread1" bread2="my bread2">
<#assign title="value 1">
<#assign subtitle="value 2">
<script>
function doAjaxPost()
{
var name= $('#name').val();
var lastName= $('#lastName').val();
var json = {"name" : name, "lastName" : lastName};
console.log(json);
var variableFreeMarker = "${freeMarkValue}";
console.log('this value is: ' + variableFreeMarker);
$.ajax(
{
type: "POST",
url: "myUrl",
data: JSON.stringify(json),
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
beforeSend: function(xhr)
{
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
},
success: function(data)
{
},
error:function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
/* error: function (xhr, ajaxOptions, thrownError)
{
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
}*/
});
}
</script>
<form name="myform">
Name in view: <input type="text" id="name" name="name">
<br>
Last Name in view: <input type="text" id="lastName" name="lastName">
<br>
Show modify name in view: <input type="text" id="modifyname" name="modifyname">
<br>
<input type="button" value="Add Users" onclick="doAjaxPost()">
</form>
<br>
</#layout.masterPageLay>
but if i put my javascript code in a external file in this case myPageScript.js and then call that script in my page i cant get the value of my freeMarker variable this is how i'm calling my script
<script src="../resources/js/scripts/myPageScript.js"></script>
and this is my page that dont work
<#import "../masterPage.html" as layout>
<#layout.masterPageLay bread1="my bread1" bread2="my bread2">
<#assign titulo="value 1">
<#assign subtitulo="value 2">
<script src="../resources/js/scripts/myPageScript.js"></script>
<form name="myform">
Name in view: <input type="text" id="name" name="name">
<br>
Last Name in view: <input type="text" id="lastName" name="lastName">
<br>
Show modify name in view: <input type="text" id="modifyname" name="modifyname">
<br>
<input type="button" value="Add Users" onclick="doAjaxPost()">
</form>
<br>
</#layout.masterPageLay>
this output in my chrome console "${freeMarkValue}" instead of the value of the variable
here are my controllers i'm processing the form using jquery ajax
#RequestMapping(value = "myForm", method = RequestMethod.GET)
public String myForm(Model model) {
model.addAttribute("freeMarkValue", "controll");
return "myForm";
}
#RequestMapping(value = "myForm", method = RequestMethod.POST)
public #ResponseBody String getTags(#RequestBody final String json, Model model)
throws IOException
{
ObjectMapper mapper = new ObjectMapper();
User objetmapped = mapper.readValue(json, User .class);
User person = new User iox();
person.setName(objetmapped .getName());
person.setLastName(objetmapped .getLastName());
);
model.addAttribute("freeMarkValue", "second controller value");
return toJson(objetmapped );
}
private String toJson(User person)
{
ObjectMapper mapper = new ObjectMapper();
try
{
String value = mapper.writeValueAsString(person);
// return "["+value+"]";
return value;
}
catch (JsonProcessingException e)
{
e.printStackTrace();
return null;
}
}
You can move your variable into a script block in the html page.
<#import "../masterPage.html" as layout>
<#layout.masterPageLay bread1="my bread1" bread2="my bread2">
<#assign titulo="value 1">
<#assign subtitulo="value 2">
<script src="../resources/js/scripts/myPageScript.js"></script>
<script>
// This variable can be accessed from myPageScript.js
var variableFreeMarker = "${freeMarkValue}";
</script>
<form name="myform">
Name in view: <input type="text" id="name" name="name">
<br>
Last Name in view: <input type="text" id="lastName" name="lastName">
<br>
Show modify name in view: <input type="text" id="modifyname" name="modifyname">
<br>
<input type="button" value="Add Users" onclick="doAjaxPost()">
</form>
Or add it as a value of a hidden input etc..
<input type="hidden" id="myVal" value="${freeMarkValue}">
Your JS (in a seperate script) would then need to read the value for example using jQuery.
var aValue = $("#myVal").val();
I use the first method for common stuff such as adding a date format string that is specific to the user on to every page. They will have global scope so be careful with naming.
I have a jsp file contains a form and I need to validate the form. The jsp page will be opened as pop-up page and hence I choose not to pop-up the validation message again. Here is my code.
<script type="text/javascript">
function validateForm() {
var x=document.forms["myForm"]["name1"].value;
if (x.trim().length<=4){
return false;
}
}
</script>
<form name="myForm" method="POST" action="write.jsp" onsubmit="return validateForm();">
Name: <input type="text" name="name1" value="<%=name%>" size="20"/> <br>
Price: <input type="text" name="price" value="<%=price%>" size="20" /><br>
Due time: <input type="text" name="DueTime" value="<%=dueday%>" size="20" /><br>
Location: <input type="text" name="Location" value="<%=address%>" size="20" /><br>
Photo Url: <input type="text" name="url" value="<%=imagePath%>" size="20" /><br>
Description: <input type="text" name="desc" value="<%=desc%>" size="20" /><br>
<input type="submit" name="submit" onclick="window.close()"/>
<% if(validateForm = false) { %> <a>error message</a> <% } %>
</form>
I am validating for first input "name1" only and the input length is less than 4.
I'd like to display a error message below the submit button. The codes is not working, can anyone help me to fix this?
document.getElementsByName('name1')[0].value;
in place of
document.forms["myForm"]["name1"].value;
use a span below the submit button
html
<span id="error"></span>
script
function validateForm()
{
var x=document.getElementsByName('name1')[0].value;
if (x.trim().length<=4)
{
document.getElementById("error").innerHTML="atleast 4 letters required in name";
return false;
}
}
Use document.getElementsByName("name1") instead of document.forms["myForm"]["name1"].value;
Use as
function validateForm()
{
var x=document.getElementsByName("name1").value;
if (x.trim().length<=4)
{
alert("Message");
return false;
}
}