既不是BindingResult也不是bean名称的普通目标对象' tweets'可用作请求属性

时间:2015-06-15 20:38:06

标签: java spring-mvc spring-data-jpa

我试图将全局表单添加到用户可以发布的位置。我出于某种原因得到了这个错误,一直在研究这个错误,它必须是我的控制器的东西,但不确定

在home.jsp中

<form:form modelAttribute= "tweets">
<form:input path="tweet" />
 <input id="user" name="user" type="hidden" value="${user}"/>
<input type="submit" value="send" />
</form:form>
TweetsController中的

 public class TweetsController {

private TweetsService tweetsService;

@ModelAttribute("tweets")
// name for tweet form in home public Tweets
public Tweets construct() {

    return new Tweets();
}

// //----------------------------------------------------------------------
@RequestMapping(value = "/")
public String newTweet(Model model) {
    model.addAttribute("tweets", new Tweets());
    return "/home";
}

@RequestMapping(method = RequestMethod.GET)
public String tweet(Model model) throws MessagingException {

    // key value - attribute and the value of the attribute
    // if key isn't passed, it will default to camelCased class name
    model.addAttribute("tweets", new CreateTweet());

    return "home";

}

@RequestMapping(method = RequestMethod.POST)
public String tweet(@ModelAttribute("tweets") CreateTweet tweet, BindingResult result,
        RedirectAttributes redirectAttributes) {

    if (result.hasErrors()) {
        return "redirect:/";
    }

    tweetsService.createTweet(tweet);

    return "redirect:/";

}

  }

TweetsServiceImpl

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class TweetsServiceImpl implements TweetsService {

    private TweetsRepository tweetsRepo;
@Autowired
private UserRepository userRepo;

@Autowired
public TweetsServiceImpl(UserRepository userRepo, TweetsRepository tweetsRepo) {

    this.userRepo = userRepo;
    this.tweetsRepo = tweetsRepo;

}

public TweetsRepository getTweetsRepo() {
    return tweetsRepo;
}

public void setTweetsRepo(TweetsRepository tweetsRepo) {
    this.tweetsRepo = tweetsRepo;
}

public UserRepository getUserRepo() {
    return userRepo;
}

public void setUserRepo(UserRepository userRepo) {
    this.userRepo = userRepo;
}

public List<Tweets> findAll() {

    return tweetsRepo.findAll();
}

@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void createTweet(CreateTweet createTweet) {
    Tweets tweet = new Tweets();
    tweet.setTweet(createTweet.getTweet());
    tweet.setUser(createTweet.getUser());
    tweetsRepo.save(tweet);

}

}

CreateTweet

public class CreateTweet {


@NotNull
@Size(min=1, max=500)
private String tweet;

@NotNull
private User user; 


public String getTweet() {
    return tweet;
}

public void setTweet(String tweet) {
    this.tweet = tweet;
}

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}


}

用户类

 @Entity
@Table(name = "usr", indexes = { @Index(columnList = "email", unique = true) })
// using usr because in may conflict with the name of the class
public class User {

    public static final int EMAIL_MAX = 250;
    public static final int NAME_MAX = 50;

    /*
     * public static enum Role {
     * 
     * UNVERIFIED, BLOCKED, ADMINISTRATOR
     * 
     * }
     */

    // primary key long, needs to be annotated with @Id
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    // add columns
    @Column(nullable = false, length = EMAIL_MAX)
    private String email;

    @Column(nullable = false, length = NAME_MAX)
    private String name;

    // no length, the password will be encrypted to some longer value than the
    // user enters
    @Column(nullable = false)
    private String password;

    @OneToMany(mappedBy="user")
    List<Tweets> tweets;


    public List<Tweets> getTweets() {
        return tweets;
    }

    public void setTweets(List<Tweets> tweets) {
        this.tweets = tweets;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(nullable = false)
    private String username;



    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isEditable() {
        User loggedIn = MyTools.getSessionUser();

        if (loggedIn == null) {
            return false;
        }

        return loggedIn.getId() == id;
    }

    public String getUsername() {

        return username;
    }

}

如何让表单显示在页面上,用户可以发帖?

1 个答案:

答案 0 :(得分:0)

您的TweetsController有错误。你想方设法就会在每个请求之前调用@ModelAttribute construct方法,总是创建一个新实例。

要解决此问题,您应该使用@SessionAttributes("tweets")为控制器添加注释。这样,当调用construct方法时,它会将模型属性存储在模型中,也会存储在会话存储中。此外,每当访问"tweets"模型属性时,它将在会话中被查找。因此,您的construct方法最初才会被调用。

@SessionAttributes("tweets")还将确保模型变量始终存在于请求中,并且您的错误将得到解决。

令人困惑的是,有时您将类Tweets和有时CreateTweet存储为"tweets"模型属性。无论如何,以下控制器应该适合你

@SessionAttributes("tweets")
public class TweetsController {

    private TweetsService tweetsService;

    @ModelAttribute("tweets")
    // name for tweet form in home public Tweets
    public Tweets construct() {
        return new Tweets();
    }

    // //----------------------------------------------------------------------
    @RequestMapping(value = "/")
    public String newTweet(Model model) {
        model.addAttribute("tweets", new CreateTweet());
        return "/home";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String tweet(@ModelAttribute("tweets") CreateTweet tweet, BindingResult result,
                        RedirectAttributes redirectAttributes) {
        if (result.hasErrors()) {
            return "redirect:/";
        }
        tweetsService.createTweet(tweet);
        return "redirect:/";
    }

}