本文共 8547 字,大约阅读时间需要 28 分钟。
入门条件
•Java 8已安装。
•任何Java IDE(最好是STS或IntelliJ IDEA)。
•使用HTML,CSS和JavaScript,基本了解基于Java和Spring的Web开发和UI开发。
背景
在本文中,我将尝试使用Java 8和Spring Boot创建一个小型端到端Web应用程序。
我选择了SpringBoot,因为它更容易配置并且可以很好地与其他技术堆栈配合使用。我还使用了REST API和SpringData JPA以及H2数据库。
我使用 Spring Initializer 添加所有依赖项,并使用我的所有配置创建一个空白的工作项目。
我使用Maven作为构建工具,但也可以使用Gradle。
pom.xml
4.0.0
com.example
bootdemo
0.0.1-SNAPSHOT
jar
bootDemo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.3.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-devtools
org.springframework.boot
spring-boot-starter-data-rest
org.springframework.boot
spring-boot-starter-web
com.h2database
h2
runtime
org.springframework.boot
spring-boot-starter-test
test
org.springframework.restdocs
spring-restdocs-mockmvc
test
org.springframework.boot
spring-boot-maven-plugin
在UI部分,我使用了AngularJS和BootStrap CSS以及基本的JS,CSS和HTML。
这是一个非常简单的可用于创建Web应用程序的项目。
结构
实施
让我们从SpringBootApplication类开始。
@SpringBootApplication
public class BootDemoApplication {
@Autowired
UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(BootDemoApplication.class, args);
}
}
我们现在创建Controller。
@Controller
public class HomeController {
@RequestMapping("/home")
public String home() {
return "index";
}
}
这将作为我们SPA的主页。现在我们创建一个Controller来处理一些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);
}
}
在这里,我们有不同的方法来处理来自客户端的不同测试调用。
我在Controller中安装了一个Service类 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());
}
}
在典型的Web应用程序中,通常有两种类型的数据对象:DTO(通过客户端进行通信)和实体(通过DB进行通信)。
DTO
public class UserDto {
Integer userId;
String userName;
List skillDtos= new ArrayList<>();
public UserDto(Integer userId, String userName, List 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 getSkillDtos() {
return skillDtos;
}
public void setSkillDtos(List 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 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 getSkills() {
return skills;
}
public void setSkills(List skills) {
this.skills = skills;
}
public User() {
}
public User(String userName, List 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{
}
@Repository
public interface SkillRepository extends JpaRepository{
}
在默认情况下,扩展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());
}
}
现在让我们关注UI部分。
使用Angular时,我们需要遵循一些指导原则。
index.html
Main PageUser
Skills
placeholder="use comma to separate skills"/>
Save User
{
{allUsers | json}}{ {skill.skillName}}
在创建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
在打开一个简单的页面之后,输入名称和技能,输入的数据将保留在数据库中。
转载地址:http://ivqll.baihongyu.com/