Требования при поступлении
· Ява 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, просьба указывать источник для перепечатки