Unable to Run the following Spring Boot Application that uses JDBC Template - spring

I have created a simple Spring Boot Application that adds Dog information into the MySql database.
The controller class for this Application is DogController.java
package com.dog.resue.controller;
import com.dog.resue.dao.DodRepository;
import com.dog.resue.service.DogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date;
#Controller
#RequestMapping(path="/")
public class DogController {
#Autowired
private DodRepository dodRepository;
#Autowired
private DogService dogService;
#RequestMapping(value ="/home",method = {RequestMethod.POST,RequestMethod.GET})
public String adddog(#RequestParam("name") String name,
#RequestParam("rescued") #DateTimeFormat(pattern = "yyyy-MM-dd") Date rescued,
#RequestParam("vaccinated") Boolean vaccinated, Model model)
{
dogService.addADog(name, rescued, vaccinated);
System.out.println("name = " + name + ",rescued = " + rescued + ", vaccinated = " + vaccinated);
return "index";
}
}
and the corresponding Service class is
package com.dog.resue.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
import java.util.Date;
#Service
public class DogServiceImpl implements DogService {
#Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplate=new JdbcTemplate(dataSource);
}
#Override
public void addADog(String name, Date rescued, Boolean vaccinated) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("INSERT INTO dog(name,rescued,vaccinated) VALUES(?,?,?)",name,rescued,vaccinated );
}
}
And the thymeleaf HTML File is
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<!-- META SECTION -->
<title>Dog Rescue</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- END META SECTION -->
<!-- BEGIN STYLE -->
<style>
table, th, td {
border: 1px solid black;
padding: 1px;
}
</style>
<!-- END STYLE -->
</head>
<body>
<h2>Current Dogs In Rescue</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Rescue Date</th>
<th>Vaccinated</th>
</tr>
</thead>
<tbody>
<tr th:each="dogs : ${dogs}">
<td th:text="${dogs.id}">Text ...</td>
<td th:text="${dogs.name}">Text ...</td>
<td th:text="${dogs.rescued}">Text ...</td>
<td th:text="${dogs.vaccinated}">Text...</td>
</tr>
</tbody>
</table>
</div>
<h2>Add A Dog</h2>
<form action="#" th:action="#{/home}" >
<label>Name<input type="text" name="name" id="name"></input></label>
<label>Vaccinated<input type="text" name="vaccinated" id="vaccinated"></input></label>
<label>Rescued<input type="text" name="rescued" id="rescued"></input></label>
<input type="submit" value="Submit"></input>
</form>
</body>
</html>
While running this code i am getting following Error
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Jul 22 21:50:32 IST 2018
There was an unexpected error (type=Bad Request, status=400).
Required String parameter 'name' is not present
url is http://localhost:8080/home
Kindly help me to solve this issues

Your Request parameters are missing in URL( name,rescued,vaccinated)
Your url should be
http://localhost:8080/home?name=ARULSUJU&rescued=2012-12-12&vaccinated=true
because all the parameters are required

Looking at your controller
Why you have rescued as Date Type you can change it as String.
So your controller will be
#RequestMapping(value ="/home",method = {RequestMethod.POST,RequestMethod.GET})
public String adddog(#RequestParam("name") String name,
#RequestParam("rescued") String rescued,
#RequestParam("vaccinated") Boolean vaccinated, Model model)
{
dogService.addADog(name, rescued, vaccinated);
System.out.println("name = " + name + ",rescued = " + rescued + ", vaccinated = " + vaccinated);
return "index";
}
Now try this URL
http://localhost:8080/home?name=test&rescued=2014-12-12&vaccinated=true

in your thymeleaf html file add this xmlns :
xmlns:th="http://www.thymeleaf.org"

Related

Input values were not transmitted to the PostMapping controller

create.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css" href="/css/main.css" />
</head>
<body>
<a th:href="#{/admin/}">Admin</a>
<br>
<br>
<br>
<h1>Add core phrases to the database</h1>
<br>
<br>
<form method="POST" th:object="${corePhrasesCreateForm}">
<table>
<tr>
<td>Quotation cluster (" "):</td>
<td><input
type="number"
id="quotation-cluster"
name="quotation-cluster"
th:value="${quotationCluster}"/></td>
<td th:if="${#fields.hasErrors('quotationCluster')}" th:errors="*{quotationCluster}">quotationCluster</td>
</tr>
<tr>
<td>Quotation Exclamation cluster ("!")</td>
<td><input
type="number"
id="quotation-exclamation-cluster"
name="quotation-exclamation-cluster"
th:value="${quotationExclamationCluster}"/></td>
<td th:if="${#fields.hasErrors('quotationExclamationCluster')}" th:errors="*{quotationExclamationCluster}">quotationExclamationCluster</td>
</tr>
<tr>
<td>Phrases</td>
<td><textarea rows="5" cols="60" name="value" placeholder="Key phrases" th:text="${value}"></textarea></td>
<td class="error" th:if="${#fields.hasErrors('value')}" th:errors="*{value}">value</td>
</tr>
</table>
<br/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
Validator
import com.example.marketing3.semantics.semanticsClusters.repositories.ClusterRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
#RequiredArgsConstructor
#Service
public class CorePhraseFormValidator implements Validator {
private final ClusterRepository clusterRepository;
#Override
public boolean supports(Class<?> clazz) {
return false;
}
#Override
public void validate(Object target, Errors errors) {
System.out.println();
}
Controller
#Controller
#RequestMapping("/semantics/phrases/core")
#RequiredArgsConstructor
public class CorePhraseController {
#GetMapping({"/create", "/create/"})
public String createGet(CorePhrasesCreateForm corePhrasesCreateForm) {
return "semantics/phrases/core/create";
}
#PostMapping({"/create", "/create/"})
public String createPost(#Valid CorePhrasesCreateForm corePhrasesCreateForm,
BindingResult bindingResult,
RedirectAttributes atts) {
corePhraseFormValidator.validate(corePhrasesCreateForm, bindingResult);
if (bindingResult.hasErrors()) {
return "semantics/phrases/core/create";
}
atts.addAttribute("message", "Core phrases created");
String result = "";
return "redirect:/general/message";
}
}
The form has been rendered.
I entered
Quotation cluster (" "): 1
Quotation Exclamation cluster ("!"): 2
And some text for phrases.
Like this:
The problem:
To createPost quotationCluster and quotationExclamationCluster came as zeroes.
But I entered 1 and 2 respectively.
Could you help me understand what I have don wrongly and correct the situation.
Change
<input type="number" id="quotation-cluster"
name="quotation-cluster" th:value="${quotationCluster}"/>
To:
<input type="number" id="quotation-cluster" th:field="*{questionCluster}"
name="quotationCluster" th:value="${quotationCluster}"/>
the name and th:field should be same as the declared attribute in your java class CorePhraseForm. Repeat this for the the next input (Textarea).

Getting all the time: Invalid property of bean class: Bean property is not readable

I always get this error, nonetheless whether I create the getter/setter manually or doing it via Lombok.
So, I guess the error has nothing to do with the Getters/Setters but I cannot find the answer to my problem.
This is my error message:
Invalid property 'person' of bean class [java.util.ArrayList]: Bean property 'person' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
This is my Enttiy class:
#Data
#Getter
#Setter
#Entity
#Table(name="incomeoutgo", schema = "public")
public class IncomeOutgo extends AbstractPersistable<Long> {
#Version
#NotNull
#Column(name ="id")
private Long id;
#Column(name="dayofweek")
private Date dayofweek;
#Column(name="location")
private String location;
#Size(min = 5, max = 50)
#Column(name ="person")
private String person;
#Min(0)
#Column(name ="version")
private Integer version;
#Column(name="income")
private int income;
#Column(name="outgo")
private int outgo;
}
And this is my Controller class
#RequiredArgsConstructor
#Controller
#RequestMapping(value = "/incomeoutgo")
public class IncomeOutgoController {
private static final String INCOMEOUTGO_VIEW = "incomeoutgo";
private final IncomOutgoService incomeoutgoService;
#GetMapping
public String showShop(Model model) {
List<IncomeOutgo> incomeOutgoList = incomeoutgoService.getIncomeOutgoList();
model.addAttribute(INCOMEOUTGO_VIEW, incomeOutgoList);
return INCOMEOUTGO_VIEW;
}
#PostMapping("/incomeoutgo")
public String addUser(#ModelAttribute("incomeoutgo") IncomeOutgo incomeoutgo, BindingResult bindingResult) {
incomeoutgoService.addIncomeOutgo(incomeoutgo);
return "incomeoutgo";
}
}
And last but not least my Thymeleaf template:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Incomes / Expenses</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<table>
<tr>
<th>Id</th>
<th>Day of Week</th>
<th>Name</th>
<th>Location</th>
<th>Income</th>
<th>Expense</th>
</tr>
<tr th:each="incomeoutgo : ${incomeoutgo}">
<td th:text="${incomeoutgo.id}">id</td>
<td th:text="${incomeoutgo.dayofweek}">dayofweek</td>
<td th:text="${incomeoutgo.person}">person</td>
<td th:text="${incomeoutgo.location}">location</td>
<td th:text="${#numbers.formatCurrency(incomeoutgo.income)}">"${#numbers.formatCurrency(incomeoutgo.income)}"</td>
<td th:text="${#numbers.formatCurrency(incomeoutgo.outgo)}">"${#numbers.formatCurrency(incomeoutgo.outgo)}"</td>
</tr>
</table>
<form action="#" th:action="#{/incomeoutgo}" th:object="${incomeoutgo}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{person}" /></td>
<td th:if="${#fields.hasErrors('person')}" th:errors="*{person}">Name Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>
The error is explained: Invalid property 'person' of bean class [java.util.ArrayList]. You're trying to call getPerson() on a java.util.ArrayList (which doesn't have that property). I suspect it's in your form:
<form ... th:object="${incomeoutgo}">
You've added incomeoutgo to your model as a List<IncomeOutgo>, but you're trying to treat it as an IncomeOutgo instead. You need to create a single object and use that instead when trying to bind form field values.
model.addAttribute(INCOMEOUTGO_VIEW, incomeOutgoList);
model.addAttribute("page", new IncomeOutgo());
.
.
.
<form ... th:object="${page}">
<input type="text" th:field="*{person}" />
(Side node, reusing the same variable name multiple times makes the code confusing. You have the model attribute ${incomeoutgo}, the temporary loop variable th:each="incomeoutgo : ${incomeoutgo}" and the bound thymeleaf object th:object="${incomeoutgo}" which may or may not be related.)

Spring: Error Button Action on Form after add registration (Spring Security)

I do an example with login page - Spring Security.
Shortly:
There's root page ("localhost:8080/") - here's a link on the main page.
Click a link on the main page go to main.html(localhost:8080/main/
If User doesn't authorize he is redirected to login page
When the user authorizes the main page is opened
The main page show messages and filter by tag
I enter a tag in input and push the button Search(Найти), messages are filtered by tag
When I have added authorization filter has stopped work.
This is my source code:
root page - have link on Main page
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Gretting start: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div>Hello, user</div>
<a th:href="#{/main}">Main page</a>
</body>
</html>
Main page
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div>
<form method="post">
<input type="text" name="text" placeholder="Введите сообщение" />
<input type="text" name="tag" placeholder="Тэг">
<button type="submit">Добавить</button>
</form>
</div>
<div>Список сообщений</div>
<form method="post" action="filter">
<input type="text" name="filter">
<button type="submit">Найти</button>
</form>
<div th:each = "message : ${messages}">
<b th:text = "${message.id}"></b>
<span th:text = "${message.text}"></span>
<i th:text = "${message.tag}"></i>
</div>
</body>
</html>
Controller processes all mapping
package com.example.sweater;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.sweater.domain.Message;
import com.example.sweater.repos.MessageRepo;
#Controller
public class GreetingController {
#Autowired
private MessageRepo messageRepo;
#GetMapping("/")
public String greeting(Model model) {
return "greeting";
}
#GetMapping("/main")
public String main(Model model) {
Iterable<Message> messages = messageRepo.findAll();
model.addAttribute("messages", messages);
return "main";
}
#PostMapping("/main")
public String add(#RequestParam String text, #RequestParam String tag, Model model) {
Message message = new Message(text, tag);
messageRepo.save(message);
Iterable<Message> messages = messageRepo.findAll();
model.addAttribute("messages", messages);
return "main";
}
#PostMapping("/filter")
public String filter(#RequestParam String filter, Model model) {
Iterable<Message> messages;
if (filter != null && !filter.isEmpty()) {
messages = messageRepo.findByTag(filter);
} else {
messages = messageRepo.findAll();
}
model.addAttribute("messages", messages);
return "main";
}
}
WebSecurityConfig have one In Memory User. antMathcers("/") permitAll and anyRequest authenticated
package com.example.sweater.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Bean
#Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("u")
.password("p")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
My screenshots
root page
Main page
When I enter filter tag and push Button "Найти"(= Search), I've got an error:
#PostMapping("/filter") doesn't catch the action in the form. I checked in the debugger. I can't catch an error and don't know why does this happen.
I have GitHub repository: https://github.com/aalopatin/sweater
Commit with the comment "Add messages" - filter work
Commit with the comment "Add remote repository and Login" - filter doesn't work and add login
I found solving. In a form on the main page need to add 'th' attribute because I use Thymeleaf so template engine. It's needed for _csrf defending which auto insert token in a form if you use Thymeleaf:
<form method="post" th:action="filter">
<input type="text" name="filter">
<button type="submit">Найти</button>
</form>

Why can't I go to other Controller rather than HomeController in Spring framework?

I created a Spring project with STS, using MySql with MyBatis.
I'm trying to make a function for Members to Sign up, but it only keep visiting Homecontroller.java instead of MemberController, when I click the submit button.
This is the arrangement of my files and codes.
This is from index.jsp
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<P> The time on the server is ${serverTime}. </P>
<h1> This is the first page to Log In</h1>
<form id="form1" action="members/logIn">
LogIn <p>
ID: <input type="text" name="id" id="id">
Password: <input type="password" name="pwd" id="pwd">
<input type="button" onclick="logIn()" value="press to LogIn">
</form>
<p><br><br><h3>Move to SignUp page</h3>
<input type="button" onclick="window.location='views/signUp.jsp'" value="Move to Sign Up page">
<h1> This is to Sign Up </h1>
<form id="form2" action="members/join">
ID:
<input type="text" placeholder="Insert ID">
Name:
<input type="text" placeholder="Insert Name"> <p>
PWD:
<input type="text" placeholder="Insert your PWD"> <p>
PWD Check:
<input type="text" placeholder="Confirm your PWD"><p>
Address:
<input type="text" placeholder="Insert Address."> <p>
<input type="submit" value="Sign Up">
</form>
</body>
</html>
and HomeController.java
package kr.co.promptech.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Handles requests for the application home page.
*/
#Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
System.out.println("Arrived at HomeController.");
return "index";
}
}
MemberController.java
package kr.co.promptech.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import kr.co.promptech.model.Members;
import kr.co.promptech.service.MemberService;
#Controller
#RequestMapping(value="/members")
public class MemberController {
#Autowired
private MemberService memberService;
#RequestMapping(value="join")
public String memberJoin(#RequestParam("id") String id, #RequestParam("pwd") String pwd,
#RequestParam("name") String name, #RequestParam("address") String address){
System.out.println("We have arrived at MemberController");
memberService.memberJoin(new Members(id, pwd, name, address));
return "main";
}
}
Why the Sign Up button keep brings me to HomeController instead MemberController?
also, can anyone help me how to make a button that brings me to main.jsp from index.jsp?
this is not working...
Hope someone can help me here...
OMG, I just found out that all the tags of index.jsp did not have name properties.
It was all my faults... sorry, and Thanks for your answer,

Thymeleaf form validation with spring MVC

This has been asked a few times but all of them did not answer my question. I have been trying to get different functionalities to work with Thymeleaf for two days now and been very unsuccessful. I have only been able to get it to work with spring-boot, however right now I am using spring-MVC.
First I will show you my dependencies
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Create a New Account</title>
<link th:href="#{/resources/css/loginForm.css}" href="/resources/css/loginForm.css" rel="stylesheet"
type="text/css"/>
</head>
<body>
<form action="#" th:action="#{/createNewAccount}" th:object="${user}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{username}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{username}">Name Error</td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" th:field="*{password}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{password}">Password Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>
Now so you can see the errors my intellij IDE is showing:
User.java
package com.practice.domain;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* Created by DrewJocham on 8/30/15.
*/
public class User {
#NotNull
#Size(min = 2, max = 30)
private String username;
#NotNull
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
The field name you call hasErrors with needs to match the field name in the object. Like so:
<td th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Name Error</td>
Note that hasErrors('name') became hasErrors('username'), and:
<td th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</td>
Note that hasErrors('age') became hasErrors('password').
As for the errors being highlighted in Intellij, I think they're misleading, and are related to this open issue: https://youtrack.jetbrains.com/issue/IDEA-132738

Resources