I have a registration form page index.html for users for a car rental app I'm building
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Register</title>
</head>
<body>
<form action="#" th:action="#{/register}" th:object="${user}"
method="post">
<p>User Name <input type="text" name="name"></p>
<p>Password <input type="password" name="password"></p>
<button type="submit">Register</button>
</form>
</body>
</html>
And a corresponding controller class where I want to invoke a new user using the factory class then save it to MySQL DB
Controller Class:
#Controller
public class IndexController {
#Autowired
private UserService userService;
private CustomerFactory userFactory;
private UserController controller;
#GetMapping("/")
public String registerForm(Model model){
return "index";
}
#GetMapping("/car-list")
public String carList(){
return "index";
}
#PostMapping("/register")
public String registerUser(#ModelAttribute User user){
User u = userFactory.createUser(user.getName(), user.getPassword());
//userService.saveUser(user);
return "car-list";
}
}
Here is the User class:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "userID", nullable = false)
private int userID;
private String name;
private String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
//getters setters and toString omitted
}
Here is my factory class:
public class CustomerFactory implements com.project.CS4125.service.UserFactory {
#Override
public User createUser(String name, String password) {
return new User(name, password);
}
}
My problem is I need to create the new User through the factory class then save it but get this error
: Cannot invoke "com.project.CS4125.service.CustomerFactory.createUser(String, String)" because "this.userFactory" is null
Any help appreciated.
Take a look at this section of your code. How many autowired fields does it show?
#Autowired
private UserService userService;
private CustomerFactory userFactory;
private UserController controller;
The answer is one, the UserService.
Annotations such as #Autowired apply only to the element that immediately follows them. This section of code shows one field with an #Autowired annotation and two fields without this annotation. These other two fields are thus left at their default value of null, hence the NullPointerException attempting to call a method of the CustomerFactory.
If you want values for all three of these fields to be autowired, ensure all three fields have an #Autowired annotation:
#Autowired
private UserService userService;
#Autowired
private CustomerFactory userFactory;
#Autowired
private UserController controller;
Related
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.
I want to make an orderform with spring boot where I can Save the order with more order items.
I dont't know how to implement the Service, Class and even the thymeleaf page for this.
Any hint would be great!
Here's a picture what I want to make
An here's my two entity class(no getters and setters, and customer for brevity)
#Entity
#Table(name = "order_item")
public class OrderItem {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "order_id")
private Order order;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "product_id")
private Product product;
private int qty;
private double amount;
public OrderItem() {}
public OrderItem(int id, Order order, Product product, int qty, double amount) {
super();
this.id = id;
this.order = order;
this.product = product;
this.qty = qty;
this.amount = amount;
}
#Entity
#Table(name="order")
public class Order {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private Date dateTime;
private double total;
private int paidStatus;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="customer_id")
private Customers customer;
#OneToMany(mappedBy="customOrder")
private List<OrderItem> orderItems;
You simply need to create a repository, service and controller.
1. First, let's create repositories for our models.
public interface CustomerRepository extends JpaRepository<Customer, Long> {}
public interface ProductRepository extends JpaRepository<Product, Long> {}
public interface OrderRepository extends JpaRepository<Order, Long> {}
2. Second, let's create our service layer.
(Note: I gathered all the functionality here for an example.You can distribute it to different layers.)
public interface OrderService {
List<Customer> findAllCustomers();
List<Product> findAllProducts();
List<Order> findAllOrders();
}
#Service
public class OrderServiceImpl implements OrderService {
private final CustomerRepository customerRepository;
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
public OrderServiceImpl(CustomerRepository customerRepository,
ProductRepository productRepository,
OrderRepository orderRepository) {
this.customerRepository = customerRepository;
this.productRepository = productRepository;
this.orderRepository = orderRepository;
}
#Override
public List<Customer> findAllCustomers() {
return customerRepository.findAll();
}
#Override
public List<Product> findAllProducts() {
return productRepository.findAll();
}
#Override
public List<Order> findAllOrders() {
return orderRepository.findAll();
}
}
3. Now add a controller layer, this will reply to your urls. (Note: here are simple examples just to help you understand the operation. You can come up with many different solutions.)
#Controller
#RequestMapping("/order")
public class OrderController {
private final OrderService orderService;
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
#GetMapping("/create")
public String createOrder(Model model) {
model.addAttribute("customers", orderService.findAllCustomers());
model.addAttribute("products", orderService.findAllProducts());
model.addAttribute("order", new Order());
return "order-form";
}
#PostMapping("/insert")
public String insertOrder(Model model, Order order) {
// Save operations ..
return "order-view";
}
}
4. Here, customers and products come from your database.
The 'Submit Form' button will be sending the entity id's of the selections here to the insertOrder method. (You can duplicate your other fields in a similar way and I recommend you to examine the example in this link to dynamically duplicate this product selection area.)
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<div>
<form action="/order/insert" method="post" th:object="${order}">
<p>
<label>Select Customer</label>
</p>
<p>
<select name="customer.id">
<option th:each="customer : ${customers}"
th:value="${customer.id}"
th:text="${customer.name}">Customer Name</option>
</select>
</p>
<p>
<label>Select Product</label>
</p>
<p>
<select name="orderItems[0].product.id">
<option th:each="product : ${products}"
th:value="${product.id}"
th:text="${product.name}">Product Name</option>
</select>
<input type="text" name="orderItems[0].quantity" />
</p>
<button type="submit">Submit Form</button>
</form>
</div>
</body>
</html>
I recommend you to read this example, which has scope for necessary library and spring settings.
There is link to github: https://github.com/Lukszn/ProjectProfile I'm using Spring 4.3.7.RELEASE, MySQL Connector Java: 5.1.39 and hibrnate: 5.2.9. Finaly
There i have User and his Account model. In account i have #Lob accPicture and some Strings(+ get/set). I'm trying a lot of answers from stackoverflow and documentation to show Account image, but without success. Last think what I do : created own ImageController. I successfully stored image in database but when I'm trying to display it in my jsp, it is showing "HTTP Status 400 -
The request sent by the client was syntactically incorrect."
Firstly I show you my User model:
#Entity
#Table(name = "users")
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(unique = true)
#NotBlank
#Size(min=4,max=20)
private String login;
#NotBlank
private String password;
#Column(unique = true)
#Email
#NotBlank
private String email;
private String permission;
#OneToMany()
private List<Account> accounts;
public User(final String login, final String password, final String email) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(login));
Preconditions.checkArgument(!Strings.isNullOrEmpty(password));
Preconditions.checkArgument(!Strings.isNullOrEmpty(email));
this.login = login;
this.password = password;
this.email = email;
}
public User() {
}
}
+ get/set
Account model:
#Entity
#Table(name = "accounts")
public class Account {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private boolean ifBasicAccount;
private String accTitle;
private String accFirstName;
private String accLastName;
private String accBirthdate;
private String accPhoneNumber;
private String accEducation;
private String accExperience;
private String accAbilities;
private String accInterests;
private String accProjects;
private String accDescription;
#Lob
private byte[] accPicture;
#ManyToOne
private User user;
public Account() {
}
+ get/set
next Account Controller:
#Controller
public class AccountController {
#Autowired
AccountRepository accountRepository;
#Autowired
UserRepository userRepository;
#RequestMapping(method = RequestMethod.GET, value ="addAccount")
public String addAccount(Model model) {
Account account = new Account();
model.addAttribute("account", account);
return "addAccount";
}
#RequestMapping(method = RequestMethod.POST, value ="addAccount")
public String addAccount(#ModelAttribute Account account, HttpSession session) {
User user = userRepository.findOne((Long) session.getAttribute("user_id"));
account.setIfBasicAccount(false);
account.setUser(user);
accountRepository.save(account);
return "redirect:/accounts";
}
#RequestMapping("/accounts")
public String accountList(Model model, HttpSession ses) {
long userId = (Long) ses.getAttribute("user_id");
List<Account> accounts = accountRepository.findUserAccounts(userId);
model.addAttribute("accounts", accounts);
return "accounts";
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
public String editAccountForm(Model model, #PathVariable long id) {
Account account = accountRepository.findOne(id);
model.addAttribute("account",account);
return "editAccountForm";
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
public String editAccount(#ModelAttribute Account account, #PathVariable long id) {
Account accountToUpdate = accountRepository.findOne(id);
accountToUpdate.setAccTitle(account.getAccTitle());
accountToUpdate.setAccFirstName(account.getAccFirstName());
accountToUpdate.setAccLastName(account.getAccLastName());
accountToUpdate.setAccBirthdate(account.getAccBirthdate());
accountToUpdate.setAccPhoneNumber(account.getAccPhoneNumber());
accountToUpdate.setAccEducation(account.getAccEducation());
accountToUpdate.setAccExperience(account.getAccExperience());
accountToUpdate.setAccAbilities(account.getAccAbilities());
accountToUpdate.setAccInterests(account.getAccInterests());
accountToUpdate.setAccProjects(account.getAccProjects());
accountToUpdate.setAccDescription(account.getAccDescription());
accountRepository.save(accountToUpdate);
return "redirect:/accounts";
}
#RequestMapping("/delete")
public String deleteAccount(Model model) {
return "deleteAccount";
}
#RequestMapping("/read/{id}")
public String read(#PathVariable long id) {
return accountRepository.findOne(id).toString();
}
#RequestMapping("/delete/{id}")
public String delete(#PathVariable long id) {
Account account = accountRepository.findOne(id);
accountRepository.delete(account);
return "redirect:/accounts";
}
}
and last one ImageController:
#Controller
#RequestMapping("/user")
public class ImageController {
private AccountRepository accountRepository;
#RequestMapping(value = "/accounts", method = RequestMethod.GET)
public void showImage(#RequestParam("id") Long id, HttpServletResponse response, HttpServletRequest request)
throws ServletException, IOException {
Account account = accountRepository.getOne(id);
response.setContentType("image/jpeg, image/jpg, image/png, image/gif");
response.getOutputStream().write(account.getAccPicture());
response.getOutputStream().close();
}
}
my .jsp to show account:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
<%# page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# include file="/WEB-INF/parts/header.jsp" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center">
<table class="table table-striped">
<h1>Accounts:</h1>
<c:forEach items="${accounts}" var="account" begin="0" varStatus="theCount">
<tr>
<td>${theCount.index+1}</td>
<td><b>Nazwa: </b>${account.accTitle}</td>
<td><b>Opis: </b>${account.accDescription}</td>
<td><img src="/ProjectProfile/user/accounts?id=${account.id}"/></td>
<td><a style="width: 180px;height: 20px;" href="./edit/${account.id}" class="badge badge-primary">Show/Edit</a></td>
<td><a style="width: 180px;height: 20px;" href="./delete/${account.id}" class="badge badge-danger">Delete</a></td>
</tr>
</c:forEach>
</table>
Add Account
</body>
</html>
Maybe I need use Base64Encoder, but i don't know how? .... I use pom.xml and AppConfig for configuration. Please, check out this project, maybe somebody can help?
<img id="photo" src="data:image/png;base64,${PHOTOYOUNEED}" />
In the controller responsible for the image sending to the html:
(...)
String photoencodeBase64 = modelX.getStringPhoto();
modelAndView.addObject("PHOTOYOUNEED", photoencodeBase64 );
and I also use this method in the model to convert byte[] to string in base64:
public static String convertBinImageToString(byte[] binImage) {
if(binImage!=null && binImage.length>0) {
return Base64.getEncoder().encodeToString(binImage);
}
else
return "";
}
and I call it in the getStringPhoto() getter inside the model.
Ok Eunito, let's see... Changed Account.java(model):
#Entity
#Table(name = "accounts")
public class Account {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private boolean ifBasicAccount;
private String accTitle;
private String accFirstName;
private String accLastName;
private String accBirthdate;
private String accPhoneNumber;
private String accEducation;
private String accExperience;
private String accAbilities;
private String accInterests;
private String accProjects;
private String accDescription;
#Lob
private byte[] accPicture;
private String stringPhoto;
#ManyToOne
private User user;
public Account() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAccTitle() {
return accTitle;
}
public void setAccTitle(String accTitle) {
this.accTitle = accTitle;
}
public String getAccFirstName() {
return accFirstName;
}
public void setAccFirstName(String accFirstName) {
this.accFirstName = accFirstName;
}
public String getAccLastName() {
return accLastName;
}
public void setAccLastName(String accLastName) {
this.accLastName = accLastName;
}
public String getAccBirthdate() {
return accBirthdate;
}
public void setAccBirthdate(String accBirthdate) {
this.accBirthdate = accBirthdate;
}
public String getAccPhoneNumber() {
return accPhoneNumber;
}
public void setAccPhoneNumber(String accPhoneNumber) {
this.accPhoneNumber = accPhoneNumber;
}
public String getAccEducation() {
return accEducation;
}
public void setAccEducation(String accEducation) {
this.accEducation = accEducation;
}
public String getAccExperience() {
return accExperience;
}
public void setAccExperience(String accExperience) {
this.accExperience = accExperience;
}
public String getAccAbilities() {
return accAbilities;
}
public void setAccAbilities(String accAbilities) {
this.accAbilities = accAbilities;
}
public String getAccInterests() {
return accInterests;
}
public void setAccInterests(String accInterests) {
this.accInterests = accInterests;
}
public String getAccProjects() {
return accProjects;
}
public void setAccProjects(String accProjects) {
this.accProjects = accProjects;
}
public String getAccDescription() {
return accDescription;
}
public void setAccDescription(String accDescription) {
this.accDescription = accDescription;
}
public byte[] getAccPicture() {
return accPicture;
}
public void setAccPicture(byte[] accPicture) {
this.accPicture = accPicture;
}
public String getStringPhoto() {
return convertBinImageToString(accPicture);
}
public void setStringPhoto(String stringPhoto) {
this.stringPhoto = stringPhoto;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public boolean isIfBasicAccount() {
return ifBasicAccount;
}
public void setIfBasicAccount(boolean ifBasicAccount) {
this.ifBasicAccount = ifBasicAccount;
}
public static String convertBinImageToString(byte[] accPicture) {
if(accPicture!=null && accPicture.length>0) {
return Base64.getEncoder().encodeToString(accPicture);
}
else
return "";
}
}
I have two controllers for Account(one is only for showing image-I'm not so sure that's a good thing, because i have two the same RequestMappings). So see changed ImageController:
#Controller
#RequestMapping("/admin/user")
public class ImageController {
#Autowired
AccountRepository accountRepository;
#RequestMapping(value = "/accounts", method = RequestMethod.GET)
public void showImage(#RequestParam("id") long id, Model model) {
Account account = accountRepository.findById(id);
String photoencodeBase64 = account.getStringPhoto();
model.addAttribute("accPicture", photoencodeBase64);
}
}
And .jsp to show image:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
<%# page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# include file="/WEB-INF/parts/header.jsp" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center">
<table class="table table-striped">
<h1>Accounts:</h1>
<c:forEach items="${accounts}" var="account" begin="0" varStatus="theCount">
<tr>
<td>${theCount.index+1}</td>
<td><b>Title: </b>${account.accTitle}</td>
<td><b>Description: </b>${account.accDescription}</td>
<td><b>Image: </b><img id="photo" src="data:image/png;base64,${account.accPicture}" /></td>
<td><a style="width: 180px;height: 20px;" href="./edit/${account.id}" class="badge badge-primary">Show/Edit</a></td>
<td><a style="width: 180px;height: 20px;" href="./delete/${account.id}" class="badge badge-danger">Delete</a></td>
</tr>
</c:forEach>
</table>
Add Account
</body>
</html>
so what is happen- when i add new account -> write Title, Name etc. and add image from file my browser show me HTTP Status 400 - The request sent by the client was syntactically incorrect. - > there i need see all user accounts.
In STS console nothing happend. In MySQL too.
Why not use Spring Content JPA? This can provide a storage service and rest endpoints for managing content associated with jpa entities.
pom.xml
<!-- Java API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-jpa</artifactId>
<version>0.1.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.1.0</version>
</dependency>
Configuration
#Configuration
#EnableJpaStores
#Import("org.springframework.content.rest.config.RestConfiguration.class")
public class MysqlConfig {
// schema management
//
#Value("/org/springframework/content/jpa/schema-drop-mysql.sql")
private Resource dropRepositoryTables;
#Value("/org/springframework/content/jpa/schema-mysql.sql")
private Resource dataRepositorySchema;
#Bean
DataSourceInitializer datasourceInitializer() {
ResourceDatabasePopulator databasePopulator =
new ResourceDatabasePopulator();
databasePopulator.addScript(dropReopsitoryTables);
databasePopulator.addScript(dataReopsitorySchema);
databasePopulator.setIgnoreFailedDrops(true);
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource());
initializer.setDatabasePopulator(databasePopulator);
return initializer;
}
}
To associate content, add Spring Content annotations to your account entity.
Account.java
#Entity
public class Account {
// replace #Lob field with
#ContentId
private String contentId;
#ContentLength
private long contentLength = 0L;
// if you have rest endpoints
#MimeType
private String mimeType = "text/plain";
Create a "store":
AccountImagesStore.java
#StoreRestResource(path="accountImages)
public interface AccountImagesStore extends ContentStore<Account, String> {
}
This is all you need to create REST endpoints # /accountImages. When your application starts, Spring Content will look at your dependencies (seeing Spring Content JPA/REST), look at your AccountImagesStore interface and inject an implementation of that interface for JPA. It will also inject a #Controller that forwards http requests to that implementation. This saves you having to implement any of this yourself whch I think is what you are after.
So...
curl -X POST /accountImages/{account-id}
with a multipart/form-data request will store the image in the database and associate it with the account entity whose id is account-id.
curl /accountImages/{account-id}
will fetch it again and so on...supports full CRUD.
So all you should need to display this in your JSP is an image tag:
There are a couple of getting started guides here. The reference guide is here. And there is a tutorial video here. The coding bit starts about 1/2 way through.
HTH
I'm trying to show all Customers from my local database(PostgreSQL) on the html page using Thymeleaf. My project is using Spring Boot.
Connection and getting data from database is not the point of this question(or is it?). The point is that thymeleaf does not see model that i passed through controller.
homePage.html
!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Opera</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Opera home page'" />
<ul th:each="customer : ${customers}">
<li>
<span th:text="${customers.getFirstName}">Name</span>
<span th:text="${customers.getLastName}">Surname</span>
<span th:text="${customers.getPhone}">Phone</span>
<span th:text="${customers.getEmail}">e-mail</span>
</li>
</ul>
</body>
</html>
HomePageController.java
#Controller
#RequestMapping("/")
public class HomePageController {
private CustomerRepository customerRepository;
#Autowired
public HomePageController(CustomerRepository customerRepository){
this.customerRepository = customerRepository;
}
#RequestMapping(method = RequestMethod.GET)
public String homePage(Model model) {
List<Customer> customers = Lists.newArrayList(customerRepository.findAll());
model.addAttribute("customers", customers);
return "homePage";
}
}
CustomerRepository.java
#Repository
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}
Customer.java
#Entity
#Getter #Setter
public class Customer {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#NotNull private String firstName;
#NotNull private String lastName;
#NotNull private String phoneNumber;
#NotNull private String email;
protected Customer(){}
public Customer(Long id, String firstName, String lastName, String phoneNumber, String email){
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
this.email = email;
}
#Override
public String toString(){
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s', phoneNumber='%s', emailr='%s']",this.getId(),
firstName, lastName, phoneNumber, email);
}
}
Screenshot from html file showing problem:
screen
Edit: some english corrections :(
Dont use getter in the template. Do like this:
<span th:text="${customer.firstName}">Name</span>
Sorry you also have to remove the s
I am trying to implement 'forgot password' functionality using JSF SEAM in our index page, I am using a a4j:jsFunction to send the users email and card number via two 's
It seems to work fine when I just send the email (as a string), but when I added card number (int) it threw the following..
Caused by: javax.el.PropertyNotFoundException: /index.xhtml #256,138 assignTo="#{forgotPasswordActions.cardnumber}": The class 'org.javassist.tmp.java.lang.Object_$$_javassist_seam_5' does not have the property 'cardnumber'.
The backing bean looks like this...
#Stateless
#Name("forgotPasswordActions")
public class ForgotPasswordActionsBean implements ForgotPasswordActions, Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Logger private Log log;
#In private EmailService emailService;
#In private UserDAO userDAO;
#In private MessagePoster messagePoster;
#In private Map<String, String> messages;
private User user;
private String address;
private String email;
private int cardnumber;
#Override
public void resetPassword(){
new RunAsOperation(true) {
public void execute() {
if(StringUtils.isNotEmpty(email)){
user = userDAO.findByEmail(email);
}
else{
messagePoster.postPopupInfoMessage(messages.get("inputEmpty"));
}
if(user!=null && cardnumber == user.getCardId()){
String newPassword = generateRandomPassword();
log.debug("updating password...");
user.setPassword(newPassword);
user = userDAO.makePersistent(user);
address = user.getEmail();
log.debug("password changed to: "+newPassword);
Map<String, Object> emailInfo = new HashMap<String, Object>();
emailInfo.put("name", user.getFirstname());
emailInfo.put("newPassword", newPassword);
emailService.sendToAddress(Email.user_password_reset, address, emailInfo);
messagePoster.postPopupInfoMessage(messages.get("pwReset")+" "+user.getEmail());
}
else{
messagePoster.postPopupInfoMessage(messages.get("resetFailed"));
}
}
}.run();
}
//---------------------- Setters
#Override
public void setEmail(String email) {
this.email = email;
}
#Override
public void setCardno(int cardnumber) {
this.cardnumber = cardnumber;
}
}
and the JSF / HTML
<div id="forgotPasswordDialog" title="Forgot Password">
<div class="textBox">
<input id="emailLookupval" type="text" />
<input id="cardNoval" type="text" />
<button onclick="resetPassword(jQuery('#emailLookupval').val(),jQuery('#cardNoval').val())" type="button">Reset</button>
<a4j:form id="forgotPassword">
<a4j:jsFunction name="resetPassword"
action="#{forgotPasswordActions.resetPassword}"
oncomplete="jQuery('#forgotPasswordDialog').dialog('open')">
<a4j:actionparam name="userEmail" assignTo="#{forgotPasswordActions.email}" />
<a4j:actionparam name="userCardno" assignTo="#{forgotPasswordActions.cardnumber}" />
</a4j:jsFunction>
</a4j:form>
</div>
</div>
I cant work out why it wont set this bean property?? Any help appreciated!
Your setter is called setCardno() while setCardnumber() is been expected by the view. The #{bean.property} does not relate to property names in the bean. It relates to getter/setter method names. There are 2 ways to fix this:
Rename the setter method:
public void setCardnumber(int cardnumber) {
this.cardnumber = cardnumber;
}
Or, rename the view property:
assignTo="#{forgotPasswordActions.cardno}"