validation with mvc and angular (#1378)

* validation with mvc and angular

* fix dependency versions
This commit is contained in:
lor6 2017-03-19 17:25:11 +02:00 committed by Grzegorz Piwowarek
parent d35f7d01f7
commit 04d8fed1c5
7 changed files with 368 additions and 2 deletions

View File

@ -46,6 +46,12 @@
<artifactId>commons-fileupload</artifactId>
<version>${fileupload.version}</version>
</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>
<profiles>
@ -89,16 +95,17 @@
</profiles>
<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>
<jstl.version>1.2</jstl.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>
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
<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>
<fileupload.version>1.3.2</fileupload.version>
<jackson.version>2.8.7</jackson.version>
</properties>
</project>

View File

@ -27,6 +27,16 @@ class ApplicationConfiguration extends WebMvcConfigurerAdapter {
bean.setSuffix(".jsp");
return bean;
}
@Bean
public InternalResourceViewResolver htmlViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/html/");
bean.setSuffix(".html");
bean.setOrder(2);
return bean;
}
@Bean
public MultipartResolver multipartResolver() {

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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">&#x2713;</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">&#x2713;</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">&#x2713;</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">&#x2713;</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>

View 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;
}

View 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;
} );
}
}]);