Not able to hit controller with Spring Boot - java

Can anyone please help me as I am not able to hit the controller for one of my URLs. Here is the code:
#Controller
#RequestMapping("/posts")
public class PostController {
#Autowired
private PostRepository repository;
#RequestMapping(value = "", method = RequestMethod.GET)
public String listPosts(Model model) {
model.addAttribute("posts", repository.findAll());
return "postList";
}
#RequestMapping(value = "/new", method = RequestMethod.GET)
public String newProject() {
return "newPost";
}
#RequestMapping(value = "/create", method = RequestMethod.POST)
public ModelAndView create(#RequestParam("postDescription") String comment) {
repository.save(new Posts());
return new ModelAndView("redirect:/postList");
}
//...
}
and the JSP:
<form action="<spring:url value="/posts/create" />">
<div class="form-group">
<label for="postDescription">Post</label>
<button type="submit" id="save" class="btn btn-primary">Save</button>
</form>
I'm able to hit RegistrationController but not PostController.
Do I need to configure something else?

Related

thymeleaf and spring boot form exception

I'm trying to add data to my database and reload the same page using spring boot and thymeleaf but when I save data I face this error
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'org.closure.gcp.entities.QuestionEntity'; nested exception
is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value 'adsf'; nested exception is java.lang.NumberFormatException: For input string: "adsf"
controller code :
#Controller
#RequestMapping(path = "/Questions")
public class QuestionView {
#Autowired
QuestionRepo questionRepo;
#RequestMapping(path = "/")
public String index(#ModelAttribute("question") QuestionEntity question, Model model)
{
List<QuestionEntity> list = questionRepo.findAll();
model.addAttribute("questions", list);
return "Questions";
}
#RequestMapping(value="/add", method=RequestMethod.POST)
public String addQuestion(Model model,#ModelAttribute("question") QuestionEntity question) {
questionRepo.save((QuestionEntity)model.getAttribute("question"));
List<QuestionEntity> list = questionRepo.findAll();
model.addAttribute("questions", list);
return "Questions";
}
}
thymeleaf page :
<html>
<header>
<title>Questions</title>
</header>
<body>
<h2>hello questions</h2>
<hr>
<tr th:each="q: ${questions}">
<td th:text="${q.question}"></td>
<br>
<td th:text="${q.question_type}"></td>
<hr>
</tr>
<!-- <form th:action="#{/add}" th:object="${question}" method="post"> -->
<form action="./add" th:object="${question}" method="POST">
<input type="text" th:field="*{question}" />
<br >
<input type="text" th:field="*{question_type}" />
<br >
<input type="submit" value="save" >
</form>
</body>
</html>
#Entity
#Table(name="question")
public class QuestionEntity {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Integer id;
#Column(nullable=false)
private String question;
#Column(nullable=false)
private String question_type;
#ManyToOne(optional = true)
private InterestEntity interest;
#ManyToOne(optional = true)
private LevelEntity level;
#Column(nullable = true)
private String sup_file;
#Column(nullable = false)
private int pionts;
#ManyToMany
private List<ContestEntity> contest;
#OneToMany(mappedBy ="question")
private List<AnswerEntity> answers;
// getters and setters
}
notice when I try to open another page in "/add" it works
I found this to solve
I just made a model class and use it instead of entity
and I used just one method to handle index and add requests
#Controller
#RequestMapping(path = "/Questions")
public class QuestionView {
#Autowired
QuestionRepo questionRepo;
#RequestMapping(path = {"/",""},method = {RequestMethod.POST,RequestMethod.GET})
public String index(#ModelAttribute("question") QuestionModel question, Model model,HttpServletRequest request)
{
if(request.getMethod().equals("POST"))
{
questionRepo.save(new QuestionEntity().question(question.getQuestion()).question_type(question.getQuestion_type()));
}
List<QuestionEntity> list = questionRepo.findAll();
model.addAttribute("questions", list);
return "Questions";
}
}
It is better to have 2 separate methods, one for GET and one for POST and to use redirect after the POST (see https://en.wikipedia.org/wiki/Post/Redirect/Get). This is how I would code this based on your separate QuestionModel class:
#Controller
#RequestMapping(path = "/Questions")
public class QuestionView {
#Autowired
QuestionRepo questionRepo;
#GetMapping
public String index(Model model)
{
List<QuestionEntity> list = questionRepo.findAll();
model.addAttribute("questions", list);
model.addAttribute("question", new QuestionModel());
return "Questions";
}
#PostMapping("/add")
public String addQuestion(#Valid #ModelAttribute("question") QuestionModel question, BindingResult bindingResult, Model model) {
if(bindingResult.hasErrors()) {
return "Questions";
}
questionRepo.save(new QuestionEntity().question(question.getQuestion()).question_type(question.getQuestion_type()));
return "redirect:/Questions";
}
}
Main points:
Use separate methods for GET and POST
Add the #Valid annotation to the #ModelAttribute in the POST method so any validation annotations on QuestionModel are checked (Because you probably want to make sure the question has at least some text in it for example).
Use BindingResult as parameter to check if there are validation errors.
Use "redirect:" to force a new GET after the POST to help avoid double submissions if a user would refresh the browser.

Property or field 'email' cannot be found on null

I'm trying to POST from a form within a Boostrap Modal.
Here's my form:
<form role="form" id="emailForm" action="#" th:action="#{/emailSubmission}" th:object="${university}" method="post">
<div class="form-group">
<label for="emailID"><span class="glyphicon glyphicon-user"></span> Username</label>
<input type="text" class="form-control" id="emailID" th:value="*{email}" placeholder="Enter email"></input>
</div>
<button type="submit" value="Submit" id="submitButton" class="btn btn-default btn-success btn-block" ><span class="glyphicon glyphicon-check"></span> Register</button>
</form>
Here's my controller:
#Controller
public class RegistrationController {
#RequestMapping(value = "/emailSubmission", method = RequestMethod.POST)
public String registerEmail(#ModelAttribute("university") University uni, BindingResult result, Model model)
{
System.out.println(uni.getEmail());
return "index";
}
}
And my University class:
public class University {
private String email;
public University(){
}
public String getEmail(){
return email;
}
public void setEmail(String email){
this.email = email;
}
}
I'm new to Spring and can't figure out what's going wrong and why I'm receiving the error mentioned in the title.
Changing:
th:value="*{email}"
to:
th:field="*{email}"
gives me 'Neither BindingResult nor plain target object for bean name 'university' available as request attribute' error.
You have to add the university object as an attribute to the model in your controller:
#GetMapping(value = "/index")
public String login(Model model) {
model.addAttribute("university", new University());
return "index";
}
Here is what I have for your, hope it helps. If you don't understand just tell me, have a good night.
target.request(MediaType.APPLICATION_JSON)
.post(Entity.json(Json.createObjectBuilder()
.add("attribute1", "value1")
.add("attribute2", "value2")
.build()));
or if you prefer:
MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
map.add("attribute1", "value1");
map.add("attribute2", "value2");
target.request(MediaType.APPLICATION_FORM_URLENCODED)
.post(Entity.form(map));
Now what I should do with it?
#POST
public Response post(JsonObject json) {
return Response.ok(service.persist(MyFactory.create(json.getString("attribute1"), json.getString("attribute2"))).build();
}
Or of course if you prefer:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(#FormParam("attribute1") String attribute1, #FormParam("attribute2") String attribute2) {
return Response.ok(service.persist(MyFactory.create(attribute1, attribute2))).build();
}

issue in redirecting after form submission in spring

I've a simple form
<form:form commandName="user">
<form:input path="name"/>
<input type="submit" value="Go" />
</form:form>
through which I get data and save in Database using
#Controller
public class UserController {
#Autowired
private UserService userService;
#ModelAttribute("user")
public User construct(){
return new User();
}
#RequestMapping("/users")
public String users(Model model) {
model.addAttribute("users", userService.findAll());
return "users";
}
#RequestMapping("/register")
public String showRegiteratinForm() {
return "user-register";
}
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String doRegiteratin(#ModelAttribute("user") User user) {
userService.save(user);
return "users";
}
}
and want to show all users
<P> The User on the server are </P>
<c:forEach items="${users}" var="user">
<p>${user.name}</p>
</c:forEach>
on users page using
#Service
public class UserService implements IDbCrud<User>{
#Autowired
private UserRepository userRepository;
#Override
public List<User> findAll() {
// TODO Auto-generated method stub
return userRepository.findAll();
}
#Override
public void save(User obj) {
// TODO Auto-generated method stub
userRepository.save(obj);
}
}
data is inserted, but issue is no data/user is showed at user page and if I change form to this
<form:form commandName="user" action="/context/users">
<form:input path="name"/>
<input type="submit" value="Go" />
</form:form>
I get all users which are already saved but the last one is not saved. How to do the trick for get this work accordingly.

How to pass model from view to controller in Spring?

I have a controller
#RequestMapping(value = "/admin/manage/{id}", method = RequestMethod.GET)
public ModelAndView goManage(#PathVariable int id) {
UserAccount userAccount = userAccountService.findUserAccount(id);
ModelAndView mav = new ModelAndView("admin/manage");
mav.addObject("userAccount", userAccount);
return mav;
}
and i pass userAccount model to manage.jsp view. In view I display this model. Example:
<div id="info">
<label>Login:</label><label>${userAccount.userDto.username}</label><br />
<label>Name:</label><label>${userAccount.userDto.firstName}
${userAccount.userDto.lastName}</label>
</div>
<form:form
action="${pageContext.request.contextPath}/admin/go"
modelAttribute="userAccount" method="post">
<input class="myButton" type="submit" value="Go" />
</form:form>
And it's ok, but I want pass this model userAccount from view further to next controller when I clicked button Go. My above form implementation doesen't work. How I can pass object from view? It's possible?
#RequestMapping(value = "/admin/go", method = RequestMethod.POST)
public ModelAndView goWithDrawalInvestment(
#ModelAttribute("userAccount") UserAccount userAccount) {
userAccount.setBalance(0);
mav.addObject("userAccount", userAccountDto);
return mav;
}

How make a link to show a list of a subject an jsp?

In my jsp project/overview I need to add a link which takes me to review/add and lets the user add the review to the specific project but unfortunately I have problem making that link. Any help is really appreciated :-)
This is the projectController:
#Controller
#RequestMapping(value = "/project")
public class ProjectController {
#Autowired
private ProjectService projectService;
#RequestMapping(value = "/add", method = RequestMethod.GET)
#Secured("ROLE_MANAGER")
public ModelAndView addProjectPage() {
ModelAndView modelAndView = new ModelAndView("project/add");
modelAndView.addObject("project", new Project());
return modelAndView;
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
#Secured("ROLE_MANAGER")
public ModelAndView addingProject(#ModelAttribute Project project) {
ModelAndView modelAndView = new ModelAndView("project/overview");
Map<String, String> validationResult = validate(project, false);
String message = "";
if (validationResult.isEmpty()) {
project.setStatus("Actief");
projectService.addProject(project);
message = "Project was successfully added.";
modelAndView = new ModelAndView("project/overview");
List<Project> projects = projectService.getProjects();
modelAndView.addObject("projects", projects);
} else {
for (String key : validationResult.keySet()) {
modelAndView.addObject(key, validationResult.get(key));
}
modelAndView.addObject("project", project);
}
modelAndView.addObject("message", message);
return modelAndView;
}
#RequestMapping(value = "/overview")
#Secured({"ROLE_MANAGER"})
public ModelAndView listOfProjects() {
ModelAndView modelAndView = new ModelAndView("project/overview");
List<Project> projects = projectService.getProjects();
modelAndView.addObject("projects", projects);
return modelAndView;
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
#Secured("ROLE_MANAGER")
public ModelAndView editProjectPage(#PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("project/edit");
Project project = projectService.getProject(id);
modelAndView.addObject("project", project);
return modelAndView;
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
#Secured("ROLE_MANAGER")
public ModelAndView edditingProject(#ModelAttribute Project project,
#PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("project/edit");
Map<String, String> validationResult = validate(project, true);
String message = "";
if (validationResult.isEmpty()) {
projectService.updateProject(project);
message = "Project was successfully edited.";
modelAndView = new ModelAndView("project/overview");
List<Project> proejcts = projectService.getProjects();
modelAndView.addObject("projects", proejcts);
} else {
for (String key : validationResult.keySet()) {
modelAndView.addObject(key, validationResult.get(key));
}
modelAndView.addObject("project", project);
}
modelAndView.addObject("message", message);
return modelAndView;
}
#RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
#Secured("ROLE_MANAGER")
public ModelAndView deleteProject(#PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("project/overview");
projectService.deleteProject(id);
String message = "Project was successfully deleted.";
modelAndView.addObject("message", message);
List<Project> projects = projectService.getProjects();
modelAndView.addObject("projects", projects);
return modelAndView;
}
private Map<String, String> validate(Project project, boolean edit) {
Map<String, String> result = new HashMap<String, String>();
if (StringUtils.isEmptyOrWhitespaceOnly(project.getTitle())) {
result.put("titleError", "Cannot be empty");
}
Project tempProject = projectService.getProjectByTitle(project.getTitle());
if (tempProject != null) {
if (edit) {
if (tempProject.getId() != project.getId()) {
result.put("titleError", "Already taken");
}
} else {
result.put("titleError", "Already used");
}
}
return result;
}
#RequestMapping(value = {"/"}, method = RequestMethod.GET)
#Secured("ROLE_MANAGER")
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is welcome page!");
model.setViewName("home");
return model;
}
#RequestMapping(value = "/projectReviews/{id}", method = RequestMethod.GET)
public ModelAndView projectReviews(#PathVariable Integer id){
ModelAndView projectReviewsView = new ModelAndView("project/projectreviewslist");
Project project = projectService.getProject(id);
Set<Review> projectReviews = project.getReviews();
projectReviewsView.addObject("project", project);
projectReviewsView.addObject("projectReviews", projectReviews);
return projectReviewsView;
}
}
Here the project/overview where I need to make the list to project/projectreviewslist.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<t:masterpage>
<jsp:body>
<body>
<div class="container" id="main">
<div class="login" style="width: auto;">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title pull-left">Lijst van projecten</h3>
</div>
<div class="panel-body">
<fieldset>
<legend>Hier ziet u een lijst van projecten. Hier kunt u ze wijzigen, verwijderen of updaten.</legend>
<p>${message}</p>
<div class="box">
<table class="table table-bordered table-hover table-striped" width="600">
<thead height="50px">
<tr>
<th width="5%">ID</th>
<th width="30%">Titel</th>
<th width="30%">Begin datum</th>
<th width="30%">Eind datum</th>
<th width="30%">Status</th>
<th width="5%">Acties</th></tr>
</thead>
<tbody>
<c:forEach var="project" items="${projects}">
<tr>
<td>${project.id}</td>
<td>${project.title}</td>
<td>${project.startDate}</td>
<td>${project.endDate}</td>
<td>${project.status}</td>
<td>
Wijzigen<br/>
Verwijderen<br/>
Reviews<br/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="form-actions">
Een nieuwe project toevoegen<br/>
</div>
</fieldset>
</div>
</div>
</div>
</div>
</jsp:body>
</t:masterpage>

Categories