0

I'm working on Spring MVC project spring fail to convert user object that is needed for my Post object.

my NewPost object:

public class NewPost {

private int postId;
@NotEmpty(message ="Title must not be empty!")
@Length(max = 50, message="Title must be less then 50 character")
private String title;
@NotEmpty(message ="Comment must not be empty!")
private String content;
@Length(max = 100, message="must be less then 100 character")
private String imagePath;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime publishDate;
private User user;

my controller :

  //Get lates post from DB.
   @RequestMapping(value = "/displayBlogPage", method = RequestMethod.GET)
    public String displayLatesPost(Model model) {
    List<NewPost> displayAllPost = new ArrayList<>();
    displayAllPost = NPDao.getAllPost();
    model.addAttribute("displayAllPost", displayAllPost);

   //get newPost to the model.
    model.addAttribute("newPost", new NewPost());

    //get user object to the model
    model.addAttribute("user", userDao.getUserbyId(1));

    LocalDateTime timeStamp = LocalDateTime.now();
    model.addAttribute("timeStamp", timeStamp);

    return "NewPostPage";

}
//for add Post form
  @RequestMapping(value = "/newPost", method = RequestMethod.POST)
  public String createPost( @Valid @ModelAttribute("newPost") NewPost newPost,  BindingResult result) {

if(result.hasErrors()){
    return "NewPostPage";
}
    NPDao.addNewPost(newPost);

    return "redirect:NewPostPage";
}

my JSP

<sf:form  class="form-horizontal" 
 role="form"  method="POST" 
 action="newPost" modelAttribute="newPost" >
 <div class="col-md-12">
 <div class="form-group">
 <div class="col-md-6">
 <sf:input type="text" class="form-control" path="title" placeholder="title" />
 <sf:errors path="title" cssclass="error" ></sf:errors>
 </div>
 </div>
 <div class="form-group">
 <div class="col-md-6">
 <sf:input type="text" class="form-control" path="imagePath" placeholder="image" />
 <sf:errors path="imagePath" cssclass="error" ></sf:errors>
 <sf:input type="text" class="form-control" path="publishDate" placeholder="date" value="${timeStamp}" />
 <sf:errors type="date" path="publishDate" cssclass="error" ></sf:errors>
 <sf:input type="text" class="form-control" path="user" placeholder="user" value="${user}"/>
 <sf:errors path="user" cssclass="error" ></sf:errors>
 <sf:input type="text" class="form-control" path="postId" placeholder="postid"/>
 <sf:errors path="postId" cssclass="error" ></sf:errors>
 <div class="form-group">
 <div class="col-md-12">
 <textarea  type="text" class="form-control comment" name="comment"   placeholder="Comment" required ></textarea> 
 <input type="submit" id="add"class="btn btn-default" value="Submit Post"/>
 </div>
 </div>
 </div>
</sf:form>

here is the exception:

Failed to convert property value of type java.lang.String to required type com.sg.sophacms.Model.User for property user; nested exception is java.lang.IllegalStateException: Cannot convert value of type java.lang.String to required type com.sg.sophacms.Model.User for property user: no matching editors or conversion strategy found

Rnhep
  • 43
  • 1
  • 9
  • @Rnhep, is this exception occurring during POST call to the controller from the UI? –  Dec 21 '17 at 04:10
  • What is your JSP? Are you trying to bind it to a text field? If so you would need a conversion strategy like a PropertyEditor and getAsText/setAsText. See this thread: https://stackoverflow.com/questions/912257/converting-from-string-to-custom-object-for-spring-mvc-form-data-binding – gene b. Dec 21 '17 at 04:18
  • @Kumar. yes. this occurred during the POST call to the newPost method. when form is submit. – Rnhep Dec 21 '17 at 04:21
  • @geneb. I total for got to post the JSP. ill put it up quick. and yes my input field is a text field. – Rnhep Dec 21 '17 at 04:23
  • @Rnhep This exception is because User object it cmng as String from the UI. Can you remove type=“text” for that field and try again? –  Dec 21 '17 at 04:30

1 Answers1

0

In your Controller override initBinder (or annotate any method with @InitBinder) and provide a PropertyEditor for the class User and field name "user" (although it can be for any field of this class) with getAsText/setAsText:

@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {  // or @InitBinde
    binder.registerCustomEditor(User.class, "user", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            User user = new User(text); // Some kind of initialization of your object from string
            setValue(user);
        }

        @Override
        public String getAsText() {
            User user = getValue();
            return user.getId(); // Some kind of string from your User object
        }
    });
}

The idea is you need to specify logic to translate Object<->String. In the example above, I'm assuming you can construct User(str) from a string, and also that User.getId() will return a string. That is an example of an Object<->String translation strategy you need to bind an object to a text field.

gene b.
  • 10,512
  • 21
  • 115
  • 227
  • Thank you, I'm still learning java and spring MVC, so I'm sure how to construct the User(str) and do I invoke this method to my JSP? – Rnhep Dec 21 '17 at 04:52
  • You don't need to change the JSP -- it can have an Input Text path as now. The SpringMVC server side needs the PropertyEditor registered as I showed. If you want to get a User obj from a string, then how would you construct the obj? That's why I showed a User(str) constructor. A text field bound to a String is automatic, but to an Object requires some kind of conversion that you specify. – gene b. Dec 21 '17 at 04:59