i'm new in Spring and i trying to learn it with help Spring in action 5 (Craig Walls).I'm creating small Spring Boot MVC-application.Now i have a little problem with Thymeleaf.
I have Controller,View and model as POJO object.When i'm trying to get data from form Intellij Idea told me that something wrong with my Thymeleaf view in this line:
Model
import java.util.Date;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
#Data
public class Taco {
private Long id;
private Date createdAt;
#NotNull
#Size(min=5, message="Name must be at least 5 characters long")
private String name;
#Size(min=1, message="You must choose at least 1 ingredient")
private List<Ingredient> ingredients;
}
View
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="#{/styles.css}"/>
</head>
<body>
<h1>Design your taco!</h1>
<img src="../static/images/TacoCloud.png" alt="TacoCloud.png" th:src="#{/images/TacoCloud.png}">
<form method="POST" th:object="${taco}">
<div class="grid">
<div class="ingredient-group" id="wraps">
<h3>Designate yor wrap:</h3>
<div th:each="ingredient:${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="proteins">
<h3>Pick your protein:</h3>
<div th:each="ingredient: ${protein}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">INGREDIENT</span>
</div>
</div>
<div class="ingredient-group" id="cheeses">
<h3>Choose your cheese:</h3>
<div th:each="ingredient:${cheese}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="veggies">
<h3>Determine your veggies:</h3>
<div th:each="ingredient : ${veggies}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="sauces">
<h3>Select your sauce:</h3>
<div th:each="ingredient : ${sauce}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
</div>
<div>
<h3>Name your taco creation:</h3>
<input type="text" name="name" th:field="*{name}"/>
<br/>
<button>Submit your taco</button>
</div>
</form>
</body>
</html>
Controller
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import tacos.Ingredient.Type;
import tacos.Ingredient;
import org.springframework.web.bind.annotation.ModelAttribute;
import tacos.Taco;
import tacos.data.IngredientRepository;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
#Slf4j
#Controller
#RequestMapping("/design")
public class DesignTacoController {
private final IngredientRepository ingredientRepo;
#Autowired
public DesignTacoController(IngredientRepository ingredientRepo){
this.ingredientRepo=ingredientRepo;
}
#GetMapping
public String showDesignForm(Model model) {
List<Ingredient> ingredients=new ArrayList<>();
ingredientRepo.findAll().forEach(i->ingredients.add(i));
Type[] types = Ingredient.Type.values();
for (Type type : types) {
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
return "design";
}
private List<Ingredient> filterByType(
List<Ingredient> ingredients, Type type) {
return ingredients
.stream()
.filter(x -> x.getType().equals(type))
.collect(Collectors.toList());
}
#PostMapping
public String processDesign(#Valid #ModelAttribute("design") Taco design, Errors errors, Model model) {
if (errors.hasErrors()) {
return "design";
}
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
}
And finally i get this error:
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/design.html]")
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "design" - line 64, col 45)
I noticed two things on your code.
I don't see th:action on your form that is required for form submission.
change form method="POST" th:object="${taco}" to form method="POST" th:object="${design}"
Try fixing these two and it should work.
I encountered same issue.
Resolution for me was to add getters in Taco.java for name. Somehow lombok is not generating getters automatically at run time.
And th:object="${taco}" should be th:object="${design}"
No need to make changes for th:action. From tutorial
If you take another look at the tag in your view, you can see that its method attribute is set to POST. Moreover, the doesn’t declare an action attribute. This means that when the form is submitted, the browser will gather up all the data in the form and send it to the server in an HTTP POST request to the same path for which a GET request displayed the form—the /design path.
I found two thing in code:
I do not find any action your form in html. You should use th:action tag to add an action.
in html you used th:object="${taco}" for declare an object for your html form. But you do not add “taco” object in your model in controller method from where you return the html design. You should add the “taco” object in your controller method like below.
model.addAttribute(“taco”, taco Object);
Related
Been at this all day. I may be missing an annotation somewhere. I also cannot get this app to serve the index.html.
What am I missing here? The primary issue is not being able to get the form to submit anything to the backend. Is ModelAttribute correct?
Thanks in advance.
Controller:
package com.lms.application.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.lms.application.entity.Course;
import com.lms.application.service.CourseService;
#RestController
#RequestMapping("/courses")
public class CourseController {
#Autowired
private CourseService service;
#RequestMapping(method=RequestMethod.GET)
public ResponseEntity<Object> getCourses(){
return new ResponseEntity<Object>(service.getCourses(), HttpStatus.OK);
}
#RequestMapping(value="/submit", method=RequestMethod.POST)
public ResponseEntity<Object> createCourse(#ModelAttribute("course") Course course){
return new ResponseEntity<Object>(service.createCourse(course), HttpStatus.CREATED);
}
Form
<div class="container">
<form method="post" th:object="${course}" th:action="#{/courses/submit}">
<div class="row mb-3">
<label for="title" class="col-sm-2 col-form-label">Course Title</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="course.title" th:field="${course.title}"></input>
</div>
</div>
<div class="row mb-3">
<label for="credit" class="col-sm-2 col-form-label">Course
Credits</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="course.credits" th:field="${course.credits}"></input>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
Before demanding an Object from Thymeleaf you have to create and pass one there. Thymeleaf won't create an object for you.
You need to pass the object via Model to the Controller like so:
#ModelAttribute("course")
public Course course() {
return new Course();
}
You need to make sure Course object has getters, setters and default constructor for Thymeleaf to be able to work with it correctly.
I'm trying to handle a form submission with thymeleaf in my spring-boot application, i integrated
this example which worked fine on my app. I'm trying to change it a little bit, but this is what i'm getting as an exception:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'recruiter' cannot be found on null
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:213) ~[spring-expression-5.2.3.RELEASE.jar:5.2.3.RELEASE]
...
This is the object i'm trying to handle with thymeleaf
public class FormRec {
private String recruiter;
public String getRecruiter() {
return recruiter;
}
public void setRecruiter(String recruiter) {
this.recruiter = recruiter;
}
}
This is my Controller
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.service.minimicroservice.objects.FormRec;
#Controller
public class MyController {
#GetMapping("/form")
public String greetingForm(Model model) {
model.addAttribute("recForm", new FormRec());
return "form";
}
#PostMapping("/form")
public String greetingSubmit(#ModelAttribute FormRec rec) {
return "result";
}
}
result.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'Recruiter: ' + ${rec.recruiter}" />
Submit another message
</body>
</html>
part of the form.html
<body>
<form action="#" th:action="#{/form}" th:object="${recForm}" method="post">
<div class="form-row m-b-55">
<div class="name">Recruiter<br> Name</div>
<div class="value">
<div class="row row-space">
<div class="col-2">
<div class="input-group-desc">
<input class="input--style-5" type="text" name="first_name" th:field="*{recruiter}">
<label class="label--desc">Full Name</label>
</div>
</div>
...
In order to refer to a FormRec Object i use recForm as th:object in the form.html and rec to refer to it in the result.html.
Note: I pass a value to the th:field="*{recruiter}" input text when i submit the form (is not null)
You have to name the ModelAttribute rec that the data gets bound to. So in your controller method do this (notice the name = "rec"):
public String greetingSubmit(#ModelAttribute(name = "rec") FormRec rec) {
...
}
It should work.
Additional explanation:
I've had a closer look at why that happens and it's because Spring's ModelAttribute annotation by default infers from the name of the type and not the name of the parameter (the example link you provided says it's method parameter name, but it seems to be wrong).
So in this case Spring sends formRec (notice the camelCase, which it expects when the class name is called FormRec) to the result.html and not rec as you would expect.
If my explanation doesn't really make sense, then this is the Spring documentation on ModelAttribute:
The default model attribute name is inferred from the declared attribute type (i.e. the method parameter type or method return type), based on the non-qualified class name: e.g. "orderAddress" for class "mypackage.OrderAddress", or "orderAddressList" for "List".
I am learning how to use Spring Boot and Thymeleaf. I have an issue where I provide a list of a specific Objects in the Form List to the a Thymeleaf page. When the user selects the values and posts the results, the result is a String of the selected objects and incompatible with the Object I wanted to store the values in.
This may sound like a mouthful so below is the code.
My question is: Is there anyway to ensure that Thymeleaf returns a List of Objects?
Input: A class passes a bunch of Ingredients to the form
This class passes in a List of class Ingredient to the form (The filtering does not matter for this - A list is inserted as the value of the model attribute, with the key being a type of ingredient)
#GetMapping
public String showDesignForm(Model model) {
List<Ingredient> ingredients = new ArrayList<>();
ingredientRepo.findAll().forEach(i -> ingredients.add(i));
Type[] types = Ingredient.Type.values();
for (Type type : types) {
model.addAttribute(type.toString().toLowerCase(), filterByType (ingredients, type));
}
model.addAttribute("taco", new Taco());
return "design";
}
Thymeleaf takes that list and displays it in checkboxes
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="#{/styles.css}" />
</head>
<body>
<h1>Design your taco!</h1>
<img th:src="#{/images/TacoCloud.png}"/>
<form method="POST" th:object="${taco}">
<div class="grid">
<div class="ingredient-group">
<h3>Designate your wrap:</h3>
<div th:each="ingredient : ${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Pick your protein:</h3>
<div th:each="ingredient : ${protein}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Choose your cheese:</h3>
<div th:each="ingredient : ${cheese}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Determine your veggies:</h3>
<div th:each="ingredient : ${veggies}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Select your sauce:</h3>
<div th:each="ingredient : ${sauce}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
</div>
<div>
<h3>Name your taco creation:</h3>
<input type="text" th:field="*{name}"/>
<br/>
<button>Submit your taco</button>
</div>
</form>
</body>
</html>
Destination class: Expects the returned value to be List
package tacos;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
#Data
public class Taco {
private Long id;
private Date createdAt;
#NotNull
#Size(min=5, message="Name must be at least 5 characters long")
private String name;
#Size(min=1, message="You must choose at least 1 ingredient")
private List<Ingredient> ingredients;
}
Error:
Field error in object 'taco' on field 'ingredients': rejected value [Ingredient(id=FLTO, name=Flour Tortilla, type=WRAP),Ingredient(id=CHED, name=Cheddar, type=CHEESE)]; codes [typeMismatch.taco.ingredients,typeMismatch.ingredients,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [taco.ingredients,ingredients]; arguments []; default message [ingredients]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'ingredients'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'tacos.Ingredient' for property 'ingredients[0]': no matching editors or conversion strategy found]
I encountered same problem in some code but I overcame it through using Spring JPA. But If you were using other than Spring JPA, you could use this converter for your application. According to your code, property id of Ingredient is String. So code will be.
#Component
public class IngredientConverter implements Converter<String, Ingredient> {
private final IngredientRepo ingredientRepo;
#Autowired
public IngredientConverter(IngredientRepo ingredientRepo) {
this.ingredientRepo = ingredientRepo;
}
#Override
public Ingredient convert(String source) {
List<Ingredient> ingredients = new ArrayList<>();
ingredientRepo.findAll().forEach(i -> ingredients.add(i));
for (Ingredient ingredient : ingredients) {
// You may use equal() method
if (ingredient.getId() == source)
return ingredient;
}
return null;
}
}
I came across a video which helped create a converter between the String result of the Thymeleaf page and the POST method in Spring.
https://www.youtube.com/watch?v=e9mlrHyn73w&t=627s
You should change private List<Ingredient> ingredients; as private List<String> ingredients;
I am really new to Spring Boot, and I am currently going through the book. Spring Boot in action.
I created and complied my first web simple web app fine, expect the css file shows up blank in the console. I have already looked up the following post:
Spring Boot - CSS not loading
Spring Boot CSS Stripped
I am using Thymleaves and my css file is placed within the static folder as the post and book states, but nothing shows up. my current external link, seems to be the correct way too.
<link rel="stylesheet" th:href="#{/main.css}" />
Although, the css appear to show in the resources in console, the css file remains blank. Below are my files and code.
File Structure:
Template:
body {
background-color: #cccccc;
font-family: arial,helvetica,sans-serif;
}
.bookHeadline {
font-size: 12pt;
font-weight: bold;
}
.bookDescription {
font-size: 10pt;
}
label {
font-weight: bold;
}
<html xmlns:th="http://www.springframework.org/schema/data/jaxb">
<head>
<title>Reading List</title>
<link rel="stylesheet" th:href="#{/main.css}" />
</head>
<body>
<h2>Your Reading List</h2>
<div th:unless="${#lists.isEmpty(books)}">
<dl th:each="book : ${books}">
<dt class="bookHeadline">
<span th:text="${book.title}">Title</span> by
<span th:text="${book.author}">Author</span>
(ISBN: <span th:text="${book.isbn}">ISBN</span>)
</dt>
<dd class="bookDescription">
<span th:if="${book.description}"
th:text="${book.description}">Description</span>
<span th:if="${book.description eq null}">
No description available</span>
</dd>
</dl>
</div>
<div th:if="${#lists.isEmpty(books)}">
<p>You have no books in your book list</p>
</div>
<hr/>
<h3>Add a book</h3>
<form method="POST">
<label for="title">Title:</label>
<input type="text" name="title" size="50"></input><br/>
<label for="author">Author:</label>
<input type="text" name="author" size="50"></input><br/>
<label for="isbn">ISBN:</label>
<input type="text" name="isbn" size="15"></input><br/>
<label for="description">Description:</label><br/>
<textarea name="description" cols="80" rows="5">
</textarea><br/>
<input type="submit"></input>
</form>
</body>
</html>
Controller:
package codenotes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List;
#Controller
#RequestMapping("/")
public class BookController {
private BookRepository bookRepository;
#Autowired
public BookController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
#RequestMapping(value = "/{reader}", method = RequestMethod.GET)
public String readerBooks(
#PathVariable("reader") String reader,
Model model) {
List<Book> readingList =
bookRepository.findByReader(reader);
if (readingList != null) {
model.addAttribute("books", readingList);
}
return "readingList";
}
#RequestMapping(value = "/{reader}", method = RequestMethod.POST)
public String addToReadingList(
#PathVariable("reader") String reader, Book book) {
book.setReader(reader);
bookRepository.save(book);
return "redirect:/{reader}";
}
}
Repository:
package codenotes;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Long> {
List<Book> findByReader(String reader);
}
I believe you should read this, how to serve static content:
http://docs.spring.io/spring-boot/docs/1.4.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-static-content
To sum it up, your browser is caching your static resources, such as CSS files.
In order to break this behavior, try first clean your browser cache, in google chrome you go to settings then clear browsing data.
Secondly, add these lines to your application.properties file in order to bust the cache:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
or add this instead:
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/**
spring.resources.chain.strategy.fixed.version=v12
Please make the following changes
1. Move main.css into /static/css folder
2. Change
Let me know if does not work.
If you are using Spring Auth and you're not logged in, you'll also have to make sure that the user has access to see the styling.
In the WebSecurityConfig you just have to add "*/.css" to your list of allowed routes.
#Override
protected void configure(final HttpSecurity http) throws Exception {
...
.authorizeRequests()
//allow requests to all urls that match the pattern
.antMatchers("/", "/signup", "/login", "/*.css", "/*.jpg").permitAll()
//anything else you must be logged in
...
}
I know there are many threads on this topic i have tried most of them, still cant fix my problem.I am using SpringMVC and MongoDB What i am trying to achieve is, I will Store some data in database and then i will retrieve it back from data base to a select options. here is my codes.
Jsp page..
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="f"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<!DOCTYPE html>
<html lang="en">
<title>Master Referral</title>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width= device-width, initial-scale=1">
<link type="text/css" rel="stylesheet" href='<spring:url value="/resources/css/bootstrap.min.css" />' >
<link type="text/css" rel="stylesheet" href='<spring:url value="/resources/css/stylesvitalbeat.css" />' >
</head>
<body>
<div class="container-fluid">
<div class="row">
<form action="http://localhost:8080/LoginMavenSpringMVC/admin/create" method="post">
<div class="col-md-2 col-sm-3">
<label class="control-label">Create Category:</label></div>
<div class="col-md-2 col-sm-4">
<input type="text" class="form-control input-sm field_color" name="categoryName" placeholder="Name of the Category">
</div>
<div class="col-md-1 col-sm-3">
<input type="submit" class="btn btn-primary btn-sm height_margin" name="create" value="Create">
</div>
</form>
<div>
<form class="form-horizontal" action="http://localhost:8080/LoginMavenSpringMVC/admin/saveReferral" method="post">
<div class="row margin_div">
<div class="col-sm-3 col-md-2">
<label class="control-label">Select Category</label>
</div>
<div class="col-sm-5 col-md-4">
<f:select path="categoryOptions">
<f:options items="${list}"/>
</f:select>
</div>
</div>
</div>
controller class
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.java.Dao.services.RegisterDao;
import com.java.Dao.services.RegisterDaoImplementaion;
#Controller
#RequestMapping("/admin")
public class ReferralController {
#Autowired
RegisterDao registerDao;
#RequestMapping(value="/create", method=RequestMethod.POST)
public ModelAndView create(#ModelAttribute("create") Category create){
ModelAndView model =new ModelAndView("referralPage");
System.out.println("Referral Controller.");
System.out.println( create.getCategoryName());
if((StringUtils.hasText(create.getId()))) {
registerDao.UpdateCategory(create);
} else {
registerDao.addCategory(create);
}
List<Category> list= registerDao.categoryList();
model.addObject("list", list);
return model;
}
#RequestMapping(value="/saveReferral", method=RequestMethod.POST)
public ModelAndView save(#ModelAttribute("saveReferral") Referrals referral){
ModelAndView model=new ModelAndView("referralPage");
return model;
}
}
Dao services
dao class...
package com.java.Dao.services;
import java.util.List;
import com.java.Package.Login.Category;
public interface RegisterDao {
public void addCategory(Category createCategory);
public void UpdateCategory(Category createCategory);
public List<Category> categoryList();
}
Dao Implementation
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import com.java.Package.Login.Category;
import com.mongodb.DBCollection;
#Repository
public class RegisterDaoImplementaion implements RegisterDao {
#Autowired
private MongoTemplate mongoTemplate;
public static final String Collection_Category="CategoryList";
public void addCategory(Category createCategory) {
// TODO Auto-generated method stub
createCategory.setId(UUID.randomUUID().toString());
System.out.println("Object in Repos::"+createCategory);
mongoTemplate.insert(createCategory, Collection_Category);
}
public void UpdateCategory(Category createCategory) {
// TODO Auto-generated method stub
mongoTemplate.insert(createCategory, Collection_Category);
}
#Override
public List<Category> categoryList() {
return mongoTemplate.findAll(Category.class, Collection_Category);
}
}
Class to map categoryOptions
public class Referrals {
private String categoryOptions;
public String getCategoryOptions() {
return categoryOptions;
}
public void setCategoryOptions(String categoryOptions) {
this.categoryOptions = categoryOptions;
}
}
and I am getting this error log
Servlet.service() for servlet [spring-dispatcher] in context with path [/LoginMavenSpringMVC] threw exception [An exception occurred processing JSP page /WEB-INF/views/referralPage.jsp at line 366
363: </div>
364: <div class="col-sm-5 col-md-4">
365:
366: <f:select path="categoryOptions">
367: <f:options items="${list}"/>
368: </f:select>
369: <!-- <select class="form-control input-sm" name="categoryOptions" >
Stacktrace:] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'categoryOptions' available as request attribute
Where I am getting wrong? I have tried solutions from different question but couldn't solve it.
You are missing adding Referrals object to model.
#RequestMapping(value="/saveReferral", method=RequestMethod.POST)
public ModelAndView save(#ModelAttribute("saveReferral") Referrals referral){
ModelAndView model=new ModelAndView("referralPage");
model.addAttribute("categoryOptions",new Referrals()); //or referral
return model;
}
Exception is occuring because of <f:select path="categoryOptions">,you have mentioned categoryOptions in path but no where you are returning to this jsp with categoryOptions.
Update : So this says whenever you are loading referral jsp, you have to load with categoryOptions bean
And in below lines list is added to model using model.addObject() but path variable categoryOptions is missing. So after the line model.addObject("list", list); add model.addAttribute("categoryOptions", new Referrals());
<f:select path="categoryOptions">
<f:options items="${list}"/>
</f:select>