Skip to content
Snippets Groups Projects
Commit 52e4c84e authored by Hoai Viet Nguyen's avatar Hoai Viet Nguyen
Browse files

add inputvalidaiton an errors hints

parent fa51c38d
No related branches found
No related tags found
No related merge requests found
Showing
with 97 additions and 19 deletions
...@@ -31,6 +31,7 @@ dependencies { ...@@ -31,6 +31,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5' testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.json:json:20231013' implementation 'org.json:json:20231013'
} }
......
package de.thk.gm.gdw.todolist.controllers package de.thk.gm.gdw.todolist.controllers
import de.thk.gm.gdw.todolist.dtos.TaskDto
import de.thk.gm.gdw.todolist.services.TasksService import de.thk.gm.gdw.todolist.services.TasksService
import de.thk.gm.gdw.todolist.services.UsersService import de.thk.gm.gdw.todolist.services.UsersService
import jakarta.validation.Valid
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
import org.springframework.ui.Model import org.springframework.ui.Model
import org.springframework.validation.BindingResult
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
import org.springframework.web.servlet.mvc.support.RedirectAttributes
import java.util.* import java.util.*
@Controller @Controller
...@@ -22,8 +26,13 @@ class TasksController (private val tasksRestController: TasksRestController, pri ...@@ -22,8 +26,13 @@ class TasksController (private val tasksRestController: TasksRestController, pri
} }
@PostMapping("/tasks") @PostMapping("/tasks")
fun saveTask(name: String, @PathVariable userId: UUID): String { fun saveTask(@Valid taskDto: TaskDto, bindingResult: BindingResult, redirectAttributes: RedirectAttributes, @PathVariable userId: UUID): String {
tasksRestController.saveTask(name, userId) if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("errors", bindingResult)
} else {
tasksRestController.saveTask(taskDto, userId)
}
return "redirect:/users/$userId/tasks" return "redirect:/users/$userId/tasks"
} }
...@@ -35,12 +44,17 @@ class TasksController (private val tasksRestController: TasksRestController, pri ...@@ -35,12 +44,17 @@ class TasksController (private val tasksRestController: TasksRestController, pri
} }
@PutMapping("/tasks/{id}") @PutMapping("/tasks/{id}")
fun updateTask(@PathVariable userId: UUID, @PathVariable id: UUID, name: String, open: Boolean): String { fun updateTask(@PathVariable userId: UUID, @PathVariable id: UUID,@Valid taskDto: TaskDto,bindingResult: BindingResult, redirectAttributes: RedirectAttributes): String {
if(bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("errors", bindingResult)
} else {
var task = tasksRestController.getTaskById(id, userId) var task = tasksRestController.getTaskById(id, userId)
task.name = name task.name = taskDto.name
task.open = open task.open = taskDto.open
tasksService.save(task) tasksService.save(task)
return "redirect:/users/$userId/tasks/${task.id}" }
return "redirect:/users/$userId/tasks/${id}"
} }
@DeleteMapping("/tasks/{id}") @DeleteMapping("/tasks/{id}")
......
package de.thk.gm.gdw.todolist.controllers package de.thk.gm.gdw.todolist.controllers
import de.thk.gm.gdw.todolist.dtos.TaskDto
import de.thk.gm.gdw.todolist.models.Task import de.thk.gm.gdw.todolist.models.Task
import de.thk.gm.gdw.todolist.services.TasksService import de.thk.gm.gdw.todolist.services.TasksService
import de.thk.gm.gdw.todolist.services.UsersService import de.thk.gm.gdw.todolist.services.UsersService
import jakarta.validation.Valid
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
...@@ -15,11 +17,11 @@ class TasksRestController (private val tasksService: TasksService, private val u ...@@ -15,11 +17,11 @@ class TasksRestController (private val tasksService: TasksService, private val u
@PostMapping("/tasks") @PostMapping("/tasks")
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
fun saveTask(name : String, @PathVariable userId: UUID) { fun saveTask(@Valid @RequestBody taskDto: TaskDto, @PathVariable userId: UUID) {
val user = usersService.getUserById(userId) val user = usersService.getUserById(userId)
if(user != null) { if(user != null) {
var task = Task() var task = Task()
task.name = name task.name = taskDto.name
task.user = user task.user = user
tasksService.save(task) tasksService.save(task)
} else { } else {
...@@ -59,12 +61,13 @@ class TasksRestController (private val tasksService: TasksService, private val u ...@@ -59,12 +61,13 @@ class TasksRestController (private val tasksService: TasksService, private val u
@PutMapping("/tasks/{id}") @PutMapping("/tasks/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT) @ResponseStatus(HttpStatus.NO_CONTENT)
fun updateTask(@PathVariable("id") id : UUID, name : String, @PathVariable userId: UUID) { fun updateTask(@PathVariable("id") id : UUID, @Valid @RequestBody taskDto: TaskDto, @PathVariable userId: UUID) {
val user = usersService.getUserById(userId) val user = usersService.getUserById(userId)
if(user != null) { if(user != null) {
var task = tasksService.getByIdAndUser(id, user) var task = tasksService.getByIdAndUser(id, user)
if(task != null) { if(task != null) {
task.name = name task.name = taskDto.name
task.open = taskDto.open
tasksService.save(task) tasksService.save(task)
} else { } else {
throw ResponseStatusException(HttpStatus.NOT_FOUND) throw ResponseStatusException(HttpStatus.NOT_FOUND)
......
package de.thk.gm.gdw.todolist.controllers package de.thk.gm.gdw.todolist.controllers
import de.thk.gm.gdw.todolist.dtos.UserDto
import jakarta.validation.Valid
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
import org.springframework.ui.Model import org.springframework.ui.Model
import org.springframework.validation.BindingResult
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.servlet.mvc.support.RedirectAttributes
@Controller @Controller
@RequestMapping(produces = [MediaType.TEXT_HTML_VALUE]) @RequestMapping(produces = [MediaType.TEXT_HTML_VALUE])
...@@ -18,8 +22,13 @@ class UsersController (private val usersRestController: UsersRestController) { ...@@ -18,8 +22,13 @@ class UsersController (private val usersRestController: UsersRestController) {
} }
@PostMapping("/users") @PostMapping("/users")
fun saveUsers(email: String): String { fun saveUsers(@Valid userDto: UserDto, bindingResult: BindingResult, redirectAttributes: RedirectAttributes): String {
usersRestController.saveUser(email)
if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("errors", bindingResult)
} else {
usersRestController.saveUser(userDto)
}
return "redirect:/" return "redirect:/"
} }
} }
\ No newline at end of file
package de.thk.gm.gdw.todolist.controllers package de.thk.gm.gdw.todolist.controllers
import de.thk.gm.gdw.todolist.dtos.UserDto
import de.thk.gm.gdw.todolist.models.User import de.thk.gm.gdw.todolist.models.User
import de.thk.gm.gdw.todolist.services.UsersService import de.thk.gm.gdw.todolist.services.UsersService
import jakarta.validation.Valid
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
...@@ -14,9 +16,10 @@ class UsersRestController (private val usersService: UsersService) { ...@@ -14,9 +16,10 @@ class UsersRestController (private val usersService: UsersService) {
@PostMapping("/users") @PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
fun saveUser(@RequestParam email : String): User { fun saveUser(@Valid @RequestBody userDto: UserDto): User {
var user = User() var user = User()
user.email = email user.email = userDto.email
user.birthday = userDto.birthday
usersService.saveUser(user) usersService.saveUser(user)
return user return user
} }
...@@ -38,10 +41,10 @@ class UsersRestController (private val usersService: UsersService) { ...@@ -38,10 +41,10 @@ class UsersRestController (private val usersService: UsersService) {
@PutMapping("/users/{id}") @PutMapping("/users/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT) @ResponseStatus(HttpStatus.NO_CONTENT)
fun updateUser(email: String, @PathVariable id: UUID) { fun updateUser(@Valid @RequestBody userDto: UserDto, @PathVariable id: UUID) {
var user = usersService.getUserById(id) var user = usersService.getUserById(id)
if (user != null) { if (user != null) {
user.email = email user.email = userDto.email
usersService.saveUser(user) usersService.saveUser(user)
} else { } else {
throw ResponseStatusException(HttpStatus.NOT_FOUND) throw ResponseStatusException(HttpStatus.NOT_FOUND)
......
package de.thk.gm.gdw.todolist.dtos
import jakarta.validation.constraints.Size
class TaskDto {
@Size(min = 1, max = 50)
var name: String = ""
var open: Boolean = true
}
\ No newline at end of file
package de.thk.gm.gdw.todolist.dtos
import jakarta.validation.constraints.Email
import jakarta.validation.constraints.Past
import jakarta.validation.constraints.PastOrPresent
import jakarta.validation.constraints.Size
import org.springframework.format.annotation.DateTimeFormat
import java.time.LocalDateTime
import java.util.*
class UserDto {
@Email
@Size(min = 5, max = 50)
var email: String = ""
@DateTimeFormat(pattern = "yyyy-MM-dd")
@PastOrPresent
var birthday: Date? = null
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ package de.thk.gm.gdw.todolist.models ...@@ -3,6 +3,7 @@ package de.thk.gm.gdw.todolist.models
import jakarta.persistence.Entity import jakarta.persistence.Entity
import jakarta.persistence.Id import jakarta.persistence.Id
import jakarta.persistence.Table import jakarta.persistence.Table
import java.time.LocalDateTime
import java.util.* import java.util.*
@Entity @Entity
...@@ -11,4 +12,6 @@ class User { ...@@ -11,4 +12,6 @@ class User {
@Id @Id
val id : UUID = UUID.randomUUID() val id : UUID = UUID.randomUUID()
var email: String = "" var email: String = ""
val createdAt: LocalDateTime = LocalDateTime.now()
var birthday: Date? = null
} }
\ No newline at end of file
...@@ -4,8 +4,14 @@ ...@@ -4,8 +4,14 @@
<form action="/users/${task.user.id}/tasks/${task.id}" method="post"> <form action="/users/${task.user.id}/tasks/${task.id}" method="post">
<label>Task name</label><br> <label>Task name</label><br>
<input type="text" value="${task.name}" name="name"><br> <input type="text" value="${task.name}" name="name"><br>
<#if errors?? && errors.getFieldError("name")??>
${errors.getFieldError("name")["defaultMessage"]}<br>
</#if>
<label>Open?</label> <label>Open?</label>
<input type="text" value="${task.open?string}" name="open"><br> <input type="text" value="${task.open?string}" name="open"><br>
<#if errors?? && errors.getFieldError("open")??>
${errors.getFieldError("open")["defaultMessage"]}<br>
</#if>
<input type="hidden" name="_method" value="PUT"/> <input type="hidden" name="_method" value="PUT"/>
<button>Update</button> <button>Update</button>
</form> </form>
......
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
</ul> </ul>
<form action="/users/${user.id}/tasks" method="post"> <form action="/users/${user.id}/tasks" method="post">
<input name="name" type="text"> <input name="name" type="text">
<#if errors?? && errors.getFieldError("name")??>
${errors.getFieldError("name")["defaultMessage"]}
</#if>
<button>Create task</button> <button>Create task</button>
</form> </form>
<br> <br>
......
...@@ -6,7 +6,16 @@ ...@@ -6,7 +6,16 @@
</#list> </#list>
</ul> </ul>
<form action="/users" method="post"> <form action="/users" method="post">
<input placeholder="max.mustermann@example.org" name="email"> <label for="email">Email</label>
<input placeholder="max.mustermann@example.org" name="email" minlength="5" maxlength="50" type="email" id="email"><br>
<#if errors?? && errors.getFieldError("email")??>
${errors.getFieldError("email")["defaultMessage"]}
</#if>
<label for="birthday">Birthday</label>
<input name="birthday" type="date" id="birthday">
<#if errors?? && errors.getFieldError("birthday")??>
${errors.getFieldError("birthday")["defaultMessage"]}
</#if>
<button>Create user</button> <button>Create user</button>
</form> </form>
</@base.layout> </@base.layout>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment