Создавайте простые веб-приложения с помощью Java 8, Spring Boot и Angular.

Java

Требования при поступлении

· Ява 8 установлена.

· Любая Java IDE (предпочтительно STS или IntelliJ ИДЕЯ).

· Базовое понимание веб-разработки на основе Java и Spring и разработки пользовательского интерфейса с использованием HTML, CSS и JavaScript.

задний план

В этой статье я попытаюсь создать небольшое сквозное веб-приложение с использованием Java 8 и Spring Boot.

Я выбрал SpringBoot, потому что его проще настроить и он хорошо работает с другими технологическими стеками. Я также использовал REST API и SpringData База данных JPA и H2.

я использую весну Инициализатор добавляет все зависимости и создает пустой рабочий проект со всей моей конфигурацией.

Я использую Maven в качестве инструмента сборки, но также доступен Gradle.

pom.xml

<?xml version="1.0"
encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>

    <artifactId>bootdemo</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <packaging>jar</packaging>

    <name>bootDemo</name>

    <description>Demo project for Spring Boot</description>

    <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.3.RELEASE</version>

        <relativePath />

        <!-- lookup parent from repository
-->

    </parent>

    <properties>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <java.version>1.8</java.version>

    </properties>

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-jpa</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-devtools</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-rest</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

        <dependency>

            <groupId>com.h2database</groupId>

            <artifactId>h2</artifactId>

            <scope>runtime</scope>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.springframework.restdocs</groupId>

            <artifactId>spring-restdocs-mockmvc</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

</project>
 

Для пользовательского интерфейса я использовал AngularJS и BootStrap CSS вместе с базовыми JS, CSS и HTML.

Это очень простой проект, который можно использовать для создания веб-приложений.

структура



воплощать в жизнь

Начнем с класса SpringBootApplication.

@SpringBootApplication

public class BootDemoApplication {

 @Autowired

 UserRepository userRepository;

 public static void main(String[] args) {

 
SpringApplication.run(BootDemoApplication.class, args);

 }

}

Теперь мы создаем контроллер.

@Controller

public class HomeController {

 @RequestMapping("/home")

 public String home() {

  return "index";

 }

}

Это будет главная страница нашего SPA. Теперь мы создаем контроллер для обработки некоторых вызовов REST.

@RequestMapping("/user")

@RestController

public class UserController {

 @Autowired

 UserService
userService;

 @RequestMapping(Constants.GET_USER_BY_ID)

 public UserDto getUserById(@PathVariable Integer userId) {

  return userService.getUserById(userId);

 }

 @RequestMapping(Constants.GET_ALL_USERS)

 public List < UserDto > getAllUsers() {

  return userService.getAllUsers();

 }

 @RequestMapping(value = Constants.SAVE_USER, method =
RequestMethod.POST)

 public void saveUser(@RequestBody UserDto userDto) {

 
userService.saveUser(userDto);

 }

}

Здесь у нас есть разные методы для обработки разных тестовых вызовов от клиентов.

Я установил класс службы в контроллереUserService.

public interface UserService {

 UserDto
getUserById(Integer userId);

 void saveUser(UserDto userDto);

 List < UserDto
> getAllUsers();

}

@Service

public class UserServiceimpl implements
UserService {

 @Autowired

 UserRepository
userRepository;

 @Override

 public UserDto getUserById(Integer userId) {

  return
UserConverter.entityToDto(userRepository.getOne(userId));

 }

 @Override

 public void saveUser(UserDto userDto) {

 
userRepository.save(UserConverter.dtoToEntity(userDto));

 }

 @Override

 public List < UserDto > getAllUsers() {

  return
userRepository.findAll().stream().map(UserConverter::entityToDto).collect(Collectors.toList());

 }

}

В типичном веб-приложении обычно есть два типа объектов данных: DTO (которые взаимодействуют через клиент) и сущности (которые взаимодействуют через БД).

DTO

public class UserDto {

    Integer userId;

    String userName;

   
List<SkillDto> skillDtos= new ArrayList<>();

    public UserDto(Integer userId, String userName, List<SkillDto> skillDtos) {

        this.userId = userId;

        this.userName = userName;

        this.skillDtos = skillDtos;

    }

    public UserDto() {

    }

    public Integer getUserId() {

        return userId;

    }

    public void setUserId(Integer userId) {

        this.userId = userId;

    }

    public String getUserName() {

        return userName;

    }

    public void setUserName(String userName) {

        this.userName = userName;

    }

    public List<SkillDto> getSkillDtos() {

        return skillDtos;

    }

    public void setSkillDtos(List<SkillDto> skillDtos) {

        this.skillDtos = skillDtos;

    }

}

public class SkillDto {

    Integer skillId;

    String SkillName;

    public SkillDto(Integer skillId, String skillName) {

        this.skillId = skillId;

        SkillName =
skillName;

    }

    public SkillDto() {

    }

    public Integer getSkillId() {

        return skillId;

    }

    public void setSkillId(Integer skillId) {

        this.skillId = skillId;

    }

    public String getSkillName() {

        return SkillName;

    }

    public void setSkillName(String skillName) {

        SkillName =
skillName;

    }

}

Entity

@Entity

public class User implements Serializable{

    private static final long serialVersionUID = 0x62A6DA99AABDA8A8L;

@Column

@GeneratedValue(strategy = GenerationType.AUTO)

@Id

private Integer userId;

    @Column

    private String userName;

    @OneToMany(cascade = CascadeType.ALL, fetch =
FetchType.EAGER)

    private List<Skill> skills= new LinkedList<>();

    public Integer getUserId() {

        return userId;

    }

    public void setUserId(Integer userId) {

        this.userId = userId;

    }

    public String getUserName() {

        return userName;

    }

    public void setUserName(String userName) {

        this.userName = userName;

    }

    public List<Skill> getSkills() {

        return skills;

    }

    public void setSkills(List<Skill> skills) {

        this.skills = skills;

    }

    public User() {

    }

    public User(String userName, List<Skill> skills) {

        this.userName = userName;

        this.skills = skills;

    }

}

@Entity

public class Skill {

    @Column

@GeneratedValue(strategy = GenerationType.AUTO)

@Id

private Integer skillId;

    @Column

    private String skillName;

    @ManyToOne

    private User user;

    public Skill(String skillName) {

this.skillName = skillName;

}

public Integer getSkillId() {

        return skillId;

    }

    public void setSkillId(Integer skillId) {

        this.skillId = skillId;

    }

    public String getSkillName() {

        return skillName;

    }

    public void setSkillName(String skillName) {

        this.skillName = skillName;

    }

    public User getUser() {

        return user;

    }

    public void setUser(User user) {

        this.user = user;

    }

    public Skill() {

    }

    public Skill(String skillName, User user) {

        this.skillName = skillName;

        this.user = user;

    }

}

Для операций с базой данных мы используем SpringData JPA:

@Repository

public interface UserRepository extends
JpaRepository<User, Integer>{

}

@Repository

public interface SkillRepository extends
JpaRepository<Skill, Integer>{

}

По умолчанию расширениеJpaRepositoryПредоставляется большое количество операций CRUD, и вы также можете использовать его для создания собственных методов запросов.

Чтобы преобразовать DTO -> Entity и Entity -> DTO, я создал несколько базовых классов преобразователя.

public class UserConverter {

 public static User dtoToEntity(UserDto userDto) {

  User user = new User(userDto.getUserName(), null);

 
user.setUserId(userDto.getUserId());

 
user.setSkills(userDto.getSkillDtos().stream().map(SkillConverter::dtoToEntity).collect(Collectors.toList()));

  return user;

 }

 public static UserDto entityToDto(User user) {

  UserDto userDto =
new UserDto(user.getUserId(),
user.getUserName(), null);

 
userDto.setSkillDtos(user.getSkills().stream().map(SkillConverter::entityToDto).collect(Collectors.toList()));

  return userDto;

 }

}

public class SkillConverter {

 public static Skill dtoToEntity(SkillDto SkillDto) {

  Skill Skill = new Skill(SkillDto.getSkillName(), null);

 
Skill.setSkillId(SkillDto.getSkillId());

  return Skill;

 }

 public static SkillDto entityToDto(Skill skill) {

  return new SkillDto(skill.getSkillId(), skill.getSkillName());

 }

}

Теперь давайте сосредоточимся на части пользовательского интерфейса.

При работе с Angular нам необходимо следовать некоторым рекомендациям.

index.html

<!DOCTYPE html>

<html>

<head>

    <meta charset="ISO-8859-1">

    <title>Main Page</title>

</head>

<body ng-app="demo">

<hr/>

<div class="container" ng-controller="UserController">

    <div class="row">

        <label>User</label> <input type="text" ng-model="userDto.userName" class="input-sm
spacing"/>

        <label>Skills</label> <input type="text" ng-model="skills" ng-list class="input-sm custom-width spacing"

                                     placeholder="use comma to separate skills"/>

        <button ng-click="saveUser()" class="btn btn-sm
btn-info">Save User</button>

    </div>

    <hr/>

    <div class="row">

        <p>{{allUsers | json}}</p>

    </div>

    <hr/>

    <div class="row" ng-repeat="user in
allUsers">

        <div class="">

            <h3>{{user.userName}}</h3>

            <span ng-repeat="skill in
user.skillDtos" class="spacing">{{skill.skillName}}</span>

        </div>

    </div>

</div>

</body>

<script src="js/lib/angular.min.js"></script>

<script src="js/lib/ui-bootstrap-tpls-2.5.0.min.js"></script>

<script src="js/app/app.js"></script>

<script src="js/app/UserController.js"></script>

<script src="js/app/UserService.js"></script>

<link rel="stylesheet" href="css/lib/bootstrap.min.css"/>

<link rel="stylesheet" href="css/app/app.css"/>

</html>

При создании HTML не забудьте импортировать необходимые файлы JS и CSS.


app.js

'use strict'

var demoApp = angular.module('demo', ['ui.bootstrap', 'demo.controllers',

    'demo.services'

]);

demoApp.constant("CONSTANTS", {

    getUserByIdUrl:
"/user/getUser/",

    getAllUsers: "/user/getAllUsers",

    saveUser: "/user/saveUser"

});

UserController.js

'use strict'

var module = angular.module('demo.controllers', []);

module.controller("UserController", ["$scope", "UserService",

    function($scope, UserService) {

        $scope.userDto = {

            userId:
null,

           
userName: null,

           
skillDtos: []

        };

        $scope.skills = [];

        UserService.getUserById(1).then(function(value) {

           
console.log(value.data);

        }, function(reason) {

           
console.log("error
occured");

        }, function(value) {

           
console.log("no
callback");

        });

        $scope.saveUser = function() {

            $scope.userDto.skillDtos = $scope.skills.map(skill => {

                return {

                   
skillId: null,

                   
skillName: skill

                };

            });

            UserService.saveUser($scope.userDto).then(function() {

               
console.log("works");

                UserService.getAllUsers().then(function(value) {

                    $scope.allUsers = value.data;

                }, function(reason) {

                   
console.log("error
occured");

                }, function(value) {

                   
console.log("no
callback");

                });

                $scope.skills = [];

                $scope.userDto = {

                   
userId: null,

                   
userName: null,

                   
skillDtos: []

                };

            }, function(reason) {

               
console.log("error
occured");

            }, function(value) {

               
console.log("no
callback");

            });

        }

    }

]);

UserService.js

'use strict'

angular.module('demo.services', []).factory('UserService', ["$http", "CONSTANTS", function($http, CONSTANTS) {

    var service = {};

    service.getUserById = function(userId) {

        var url = CONSTANTS.getUserByIdUrl + userId;

        return $http.get(url);

    }

    service.getAllUsers = function() {

        return $http.get(CONSTANTS.getAllUsers);

    }

    service.saveUser = function(userDto) {

        return $http.post(CONSTANTS.saveUser, userDto);

    }

    return service;

}]);

app.css

body{

   
background-color: #efefef;

}

span.spacing{

    margin-right: 10px;

}

input.custom-width{

    width: 200px;

}

input.spacing{

    margin-right: 5px;

}

Приложения можно создавать с помощью

mvn clean installилиjava -jar bootdemo-0.0.1-SNAPSHOT.jar

Откройте браузер и нажмите http://localhost:8080/home.

После открытия простой страницы введите имя и навыки, введенные данные останутся в базе.



Продукт моей предпринимательской команды, MadPecker, в основном используется для управления ошибками, управления тестированием и распространения приложений. Веб-сайт: www.madpecker.com. Друзья, которые в этом нуждаются, могут попробовать его и испытать на себе!
Данная статья написана техническим персоналом команды MadPecker, просьба указывать источник для перепечатки