validation with mvc and angular (#1378)
* validation with mvc and angular * fix dependency versions
This commit is contained in:
parent
d35f7d01f7
commit
04d8fed1c5
@ -46,6 +46,12 @@
|
|||||||
<artifactId>commons-fileupload</artifactId>
|
<artifactId>commons-fileupload</artifactId>
|
||||||
<version>${fileupload.version}</version>
|
<version>${fileupload.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<profiles>
|
<profiles>
|
||||||
@ -89,16 +95,17 @@
|
|||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<springframework.version>4.3.4.RELEASE</springframework.version>
|
<springframework.version>4.3.7.RELEASE</springframework.version>
|
||||||
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||||
<jstl.version>1.2</jstl.version>
|
<jstl.version>1.2</jstl.version>
|
||||||
<javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
|
<javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
|
||||||
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
|
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
|
||||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
<maven-compiler-plugin.source>1.8</maven-compiler-plugin.source>
|
<maven-compiler-plugin.source>1.8</maven-compiler-plugin.source>
|
||||||
<hibernate-validator.version>5.3.3.Final</hibernate-validator.version>
|
<hibernate-validator.version>5.4.0.Final</hibernate-validator.version>
|
||||||
<deploy-path>enter-location-of-server</deploy-path>
|
<deploy-path>enter-location-of-server</deploy-path>
|
||||||
<fileupload.version>1.3.2</fileupload.version>
|
<fileupload.version>1.3.2</fileupload.version>
|
||||||
|
<jackson.version>2.8.7</jackson.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -28,6 +28,16 @@ class ApplicationConfiguration extends WebMvcConfigurerAdapter {
|
|||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public InternalResourceViewResolver htmlViewResolver() {
|
||||||
|
InternalResourceViewResolver bean = new InternalResourceViewResolver();
|
||||||
|
bean.setPrefix("/WEB-INF/html/");
|
||||||
|
bean.setSuffix(".html");
|
||||||
|
bean.setOrder(2);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MultipartResolver multipartResolver() {
|
public MultipartResolver multipartResolver() {
|
||||||
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
|
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.baeldung.springmvcforms.controller;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.validation.ObjectError;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import com.baeldung.springmvcforms.domain.User;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
List<User> users = new ArrayList<User>() {
|
||||||
|
{
|
||||||
|
add(new User("ana@yahoo.com", "pass", "Ana", 20));
|
||||||
|
add(new User("bob@yahoo.com", "pass", "Bob", 30));
|
||||||
|
add(new User("john@yahoo.com", "pass", "John", 40));
|
||||||
|
add(new User("mary@yahoo.com", "pass", "Mary", 30));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@GetMapping("/userPage")
|
||||||
|
public String getUserProfilePage() {
|
||||||
|
return "user";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/user", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<Object> saveUser(@Valid User user, BindingResult result, Model model) {
|
||||||
|
if (result.hasErrors()) {
|
||||||
|
List<String> errors = new ArrayList<>();
|
||||||
|
result.getAllErrors().forEach(item->{
|
||||||
|
errors.add(item.getDefaultMessage());
|
||||||
|
});
|
||||||
|
return new ResponseEntity<>(errors, HttpStatus.OK);
|
||||||
|
} else {
|
||||||
|
if (users.stream().anyMatch(it -> user.getEmail().equals(it.getEmail()))) {
|
||||||
|
return new ResponseEntity<>(Collections.singletonList("Email already exists!"), HttpStatus.CONFLICT);
|
||||||
|
} else {
|
||||||
|
users.add(user);
|
||||||
|
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
@ResponseBody
|
||||||
|
public List<User> getUsers() {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.baeldung.springmvcforms.domain;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Digits;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
import org.hibernate.validator.constraints.Email;
|
||||||
|
import org.hibernate.validator.constraints.NotBlank;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Email
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Size(min = 4, max = 15)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Min(18)
|
||||||
|
@Digits(integer = 2, fraction = 0)
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String email, String password, String name, int age) {
|
||||||
|
super();
|
||||||
|
this.email = email;
|
||||||
|
this.password = password;
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
68
spring-mvc-forms/src/main/webapp/WEB-INF/html/user.html
Normal file
68
spring-mvc-forms/src/main/webapp/WEB-INF/html/user.html
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="ISO-8859-1">
|
||||||
|
<title>Users</title>
|
||||||
|
<script
|
||||||
|
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-messages.js"></script>
|
||||||
|
|
||||||
|
<script src="js/app.js"></script>
|
||||||
|
<link rel="stylesheet" href="css/user.css">
|
||||||
|
</head>
|
||||||
|
<body ng-app="app" ng-controller="UserCtrl">
|
||||||
|
|
||||||
|
<form name="userForm" method="POST" novalidate ng-class="{'form-error':submitted}" ng-submit="saveUser()" >
|
||||||
|
|
||||||
|
<label class="form-label">Email:</label>
|
||||||
|
<input type="email" name="email" required ng-model="user.email" class="form-input"/>
|
||||||
|
<div ng-messages="userForm.email.$error" ng-show="submitted && userForm.email.$invalid" class="error-messages">
|
||||||
|
<p ng-message="email">Invalid email!</p>
|
||||||
|
<p ng-message="required">Email is required!</p>
|
||||||
|
</div>
|
||||||
|
<div class="check" ng-show="submitted && userForm.email.$valid">✓</div>
|
||||||
|
|
||||||
|
<label class="form-label">Password:</label>
|
||||||
|
<input type="password" name="password" required ng-model="user.password" ng-minlength="4" ng-maxlength="15" class="form-input"/>
|
||||||
|
<div ng-messages="userForm.password.$error" ng-show="submitted && userForm.password.$invalid" class="error-messages">
|
||||||
|
<p ng-message="minlength">Password must be at least 4 characters!</p>
|
||||||
|
<p ng-message="maxlength">Password must not be longer than 15 characters!</p>
|
||||||
|
<p ng-message="required">Password is required!</p>
|
||||||
|
</div>
|
||||||
|
<div class="check" ng-show="submitted && userForm.password.$valid">✓</div>
|
||||||
|
|
||||||
|
<label class="form-label">Name:</label>
|
||||||
|
<input type="text" name="name" ng-model="user.name" ng-trim="true" required class="form-input" />
|
||||||
|
<div ng-messages="userForm.name.$error" ng-show="submitted && userForm.name.$invalid" class="error-messages">
|
||||||
|
<p ng-message="required">Name is required!</p>
|
||||||
|
</div>
|
||||||
|
<div class="check" ng-show="submitted && userForm.name.$valid">✓</div>
|
||||||
|
|
||||||
|
<label class="form-label">Age:</label>
|
||||||
|
<input type="number" name="age" ng-model="user.age" ng-min="18" class="form-input" required/>
|
||||||
|
<div ng-messages="userForm.age.$error" ng-show="submitted && userForm.age.$invalid" class="error-messages">
|
||||||
|
<p ng-message="min">Age must be greater than 18!</p>
|
||||||
|
<p ng-message="required">Age must be greater than 18!</p>
|
||||||
|
</div>
|
||||||
|
<div class="check" ng-show="submitted && userForm.age.$valid">✓</div>
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="form-button-save" >Save</button>
|
||||||
|
<button type="reset" ng-click="resetForm()" class="form-button-reset">Reset</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<div style="color:red;font-weight:bold">{{errorMessage}}</div>
|
||||||
|
<div style="color:green;font-weight:bold">{{message}}</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
All Users: <br />
|
||||||
|
<table id="users">
|
||||||
|
<tr>
|
||||||
|
<th>Email</th><th>Name</th><th>Age</th>
|
||||||
|
</tr>
|
||||||
|
<tr ng-repeat="usr in users">
|
||||||
|
<td>{{usr.email}}</td> <td>{{usr.name}}</td> <td>{{usr.age}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
77
spring-mvc-forms/src/main/webapp/css/user.css
Normal file
77
spring-mvc-forms/src/main/webapp/css/user.css
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
.form-label {
|
||||||
|
display:block;
|
||||||
|
margin-top:16px;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
border-radius:5px;
|
||||||
|
display:inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input p {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-button {
|
||||||
|
margin:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-error input.ng-invalid {
|
||||||
|
border-color:red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check {
|
||||||
|
display:inline;
|
||||||
|
color:green;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-messages {
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-messages p {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#customers {
|
||||||
|
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#users td, #users th {
|
||||||
|
border: 1px solid dodgerblue;
|
||||||
|
border-collapse:collapse;
|
||||||
|
padding: 4px;
|
||||||
|
width:200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#users tr:nth-child(even){background-color: lavender;}
|
||||||
|
|
||||||
|
#users th {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
text-align: left;
|
||||||
|
background-color: dodgerblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#users {
|
||||||
|
border-collapse:collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius:5px;
|
||||||
|
cursor:pointer;
|
||||||
|
margin:10px;
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-button-save {
|
||||||
|
background-color:lightgreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-button-reset {
|
||||||
|
background-color:lightpink;
|
||||||
|
}
|
70
spring-mvc-forms/src/main/webapp/js/app.js
Normal file
70
spring-mvc-forms/src/main/webapp/js/app.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
var app = angular.module('app', ['ngMessages']);
|
||||||
|
|
||||||
|
app.controller('UserCtrl', ['$scope','UserService', function ($scope,UserService) {
|
||||||
|
|
||||||
|
$scope.submitted = false;
|
||||||
|
|
||||||
|
$scope.getUsers = function() {
|
||||||
|
UserService.getUsers().then( function(data){
|
||||||
|
$scope.users = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.saveUser = function () {
|
||||||
|
$scope.submitted = true;
|
||||||
|
if ($scope.userForm.$valid){
|
||||||
|
UserService.saveUser($scope.user)
|
||||||
|
.then (function success(response){
|
||||||
|
$scope.message = 'User added!';
|
||||||
|
$scope.errorMessage = '';
|
||||||
|
$scope.getUsers();
|
||||||
|
$scope.user = null;
|
||||||
|
$scope.submitted = false;
|
||||||
|
},
|
||||||
|
function error(response){
|
||||||
|
if (response.status == 409){
|
||||||
|
$scope.errorMessage = response.data[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.errorMessage = 'Error adding user!';
|
||||||
|
}
|
||||||
|
$scope.message = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.getUsers();
|
||||||
|
|
||||||
|
$scope.resetForm = function () {
|
||||||
|
$scope.userForm.$setPristine();
|
||||||
|
$scope.user=null;
|
||||||
|
$scope.message='';
|
||||||
|
$scope.errorMessage='';
|
||||||
|
$scope.submitted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}]);
|
||||||
|
|
||||||
|
app.service('UserService',['$http', function ($http) {
|
||||||
|
|
||||||
|
this.saveUser = function saveUser(user){
|
||||||
|
return $http({
|
||||||
|
method: 'POST',
|
||||||
|
url: 'user',
|
||||||
|
params: {email:user.email, password:user.password, name:user.name, age:user.age},
|
||||||
|
headers: 'Accept:application/json'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.getUsers = function getUsers(){
|
||||||
|
return $http({
|
||||||
|
method: 'GET',
|
||||||
|
url: 'users',
|
||||||
|
headers:'Accept:application/json'
|
||||||
|
}).then( function(response){
|
||||||
|
return response.data;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
}]);
|
Loading…
x
Reference in New Issue
Block a user