I am trying to pass timestamp value in the format of "2013-12-31 12:00:00.000007", my java model class will take this property as "java.sql.Timestamp".
I tried passing using following html code, but it does not take the value entered in the field, instead it takes null value.
<td><input id="updateDateTime" name="updateDateTime" type="text" th:field="*{updateDateTime}"/></td>
As well in Controller class, i tried using custom binder as below, but still produces null values to "updateDateTime"
#InitBinder
public void binder(WebDataBinder binder) {
binder.registerCustomEditor(Timestamp.class,
new PropertyEditorSupport() {
public void setAsText(String value) {
try {
Date parsedDate = new SimpleDateFormat("MM/dd/YYYY HH:mm:ss.SSSSSS").parse(value);
setValue(new Timestamp(parsedDate.getTime()));
} catch (ParseException e) {
setValue(null);
}
}
});
}
Related
I have a date input that reaches the Controller and it performs a conversion from String to Date.
The problem is, the mapping method always returns one day less than I'd expect. If I pass 30/12/2010 it returns a Date object with 29/12/2010 as its value.
I have solved it with a small method that adds a day after the Mapper but I don't know if it is the most correct way:
public class DateMapperImpl implements DateMapper {
#Override
public String dateToString(Date date, String format) {
return date != null ? new SimpleDateFormat(format).format(date) : null;
}
#Override
public Date stringToDate(String date, String format) {
try {
return date != null ? addDayDate(new SimpleDateFormat(format).parse(date)) : null;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public Date addDayDate(Date fecha) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(fecha);
calendar.add(Calendar.DAY_OF_YEAR, 1);
return calendar.getTime();
}
}
Do you have any idea how to solve it properly?
SOLUTION
I already found the solution. In my case it has been necessary to add this method in the Application class.
#SpringBootApplication
public class BooksApplication {
public static void main(String[] args) {
SpringApplication.run(BooksApplication.class, args);
}
#PostConstruct
public void init(){
// Setting Spring Boot SetTimeZone
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
}
Thank you very much for the answers because they guided me to look for information with a different mindset.
I have the following controller which takes guids in string format as query parameters.
I wanted to verify they were a valid guid before executing the method but I'm not sure how to fire my custom ValidationAttribute:
controller.cs
public async Task<Profile> GetProfile([ValidGuid] string id)
{
...
}
ValidGuidAttribute.cs
internal class ValidGuidAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
try
{
Guid.Parse(value.ToString());
return true;
}
catch (Exception e)
{
throw new InvalidIdException($"{value.ToString()} is an invalid id");
}
}
}
Any help pointing out how to fire my IsValid method would be appreciated.
You should use a route constraint https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-constraints
[Route("getprofile/{id:guid}")]
public async Task<Profile> GetProfile(string id)
{
...
}
I'm trying to validate the information, user is giving at the registration. One of the fields contains the mailadress, which should be validated by looking in the database to confirm, it doesn't exist yet.
Problem is, that if i type an existing mailadress, it will give back a NonUniqueResultException, but also does store the new user with the duplicate mailadress in the database. Don't understand this, beacuse in the JSF-lifecycle after validation fails, it shouldn't go on to the invoke application phase, right?
Here's my code:
mail field in register formular
<b:inputText id="mail" required="true"
requiredMessage="Bitte geben Sie Ihre E-Mail-Adresse an!"
label="E-Mail" placeholder="name#example.com" value="#{registrierenManagedBean.nutzer.mail}">
<f:validator validatorId="mailValidatorRegistrieren"/>
<b:messages for="mail"/>
</b:inputText>
my custom validator
#FacesValidator("mailValidatorRegistrieren")
public class MailValidatorRegistrieren implements Validator {
#EJB
private DAO dao;
private String mail;
private static final Pattern EMAIL_PATTERN =
Pattern.compile("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE);
#Override
public void validate(FacesContext facesContext, UIComponent uiComponent, Object o) throws ValidatorException {
mail = (String)o;
boolean matchesPattern = EMAIL_PATTERN.matcher(mail).find();
if(!matchesPattern)
{
throw new ValidatorException((new FacesMessage("Invalid mail")));
}
if(mail.isEmpty()) {
return;
} else if(validateNutzer(mail)){
throw new ValidatorException(new FacesMessage("mail alredy used"));
} else{
return;
}
}
private boolean validateNutzer(String mail) {
try {
Nutzer n = dao.findNutzerByMail(mail);
return n.getMail().equals(mail);
} catch (NullPointerException e) {
return false;
}
}
}
and the "findNutzerByMail"-method from my DAO
public Nutzer findNutzerByMail(String mail) {
try {
return em.createNamedQuery("findNutzerByMail", Nutzer.class)
.setParameter("mail", mail)
.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
It's something really simple but I couldn't find a good example:
I have a custom data type that I'd like to bind to a SpringMVC checkbox, it looks like this: YES/NO:
public enum YesNoDataType {
YES("Yes"),
NO("No");
}
SpringMVC checkboxes auto-map to Booleans, now I need to map Selected->YES, Empty->NO.
I know I have to implement one of these 4 PropertyEditorSupport methods, but which ones, and how?
<form:checkbox path="testYesNo"></form:checkbox>
Model
private YesNoDataType testYesNo;
Controller
binder.registerCustomEditor(YesNoDataType.class, new PropertyEditorSupport() {
// Which ones to override?
#Override
public void setValue(Object value) {
// TODO Auto-generated method stub
super.setValue(value);
}
#Override
public Object getValue() {
// TODO Auto-generated method stub
return super.getValue();
}
#Override
public String getAsText() {
// TODO Auto-generated method stub
return super.getAsText();
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
// TODO Auto-generated method stub
super.setAsText(text);
}
});
I tried defining and registering some Converters (YesNoDataType / Boolean), but I see in SpringMVC's CheckboxTag.java that they're all useless. No converters or binding tweaks will work because the tag explicitly checks for Booleans and Strings only:
protected void writeTagDetails(TagWriter tagWriter) throws JspException {
tagWriter.writeAttribute("type", getInputType());
Object boundValue = getBoundValue();
Class<?> valueType = getBindStatus().getValueType();
if (Boolean.class.equals(valueType) || boolean.class.equals(valueType)) {
// the concrete type may not be a Boolean - can be String
if (boundValue instanceof String) {
boundValue = Boolean.valueOf((String) boundValue);
}
Boolean booleanValue = (boundValue != null ? (Boolean) boundValue : Boolean.FALSE);
renderFromBoolean(booleanValue, tagWriter);
}
else {
Object value = getValue();
if (value == null) {
throw new IllegalArgumentException("Attribute 'value' is required when binding to non-boolean values");
}
Object resolvedValue = (value instanceof String ? evaluate("value", value) : value);
renderFromValue(resolvedValue, tagWriter);
}
}
The String binding is irrelevant to me. In the getValue() String binding (Clause #2), a checkbox is selected if its value="" attribute matches the string in the model. What I need is a True/False boolean binding, but my Converter needs to be plugged into Clause #1 to obtain a Boolean from a custom type. Just very frustrated that Spring is so restrictive as soon as you try to go outside the narrow parameters of what's common. The issue is still outstanding.
I hava a POJO object with one BigDecimal field sum.
In controller I add this POJO object as form like this:
MyForm form = new MyForm();
model.addAttribute("command", form);
My jsp:
<form:input path="sum" size="27"/>
In controller i add initbinder:
binder.registerCustomEditor(BigDecimal.class, new SumEditor());
Part of my SumEditor class:
#Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(parseMoney(text));
}
private BigDecimal parseMoney(String str) {
try {
return new BigDecimal(str);
} catch (Exception e) {
logger.error("error", e);
}
return null;
}
But in JSP view I see (in input field): |null________|
How fix this? I need: |___________|
You should simply override getText method of SumEditor to have it return an empty string ("") for a null value :
#Override
public String getAsText() {
if (getValue == null) {
return "";
}
BigDecimal val = (BigDecimal) getValue();
return val.toStr(); // or whatever conversion you need
}