1. 程式人生 > 程式設計 >使用Java 8,Spring Boot和Angular建立簡單的Web應用程式

使用Java 8,Spring Boot和Angular建立簡單的Web應用程式

入門條件

· 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

<?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>複製程式碼
 複製程式碼

在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<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());

 }

}複製程式碼

現在讓我們關注UI部分。

使用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,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,主要做BUG管理、測試管理、應用分發,網址:www.madpecker.com,有需要的朋友歡迎試用、體驗!
本文為MadPecker團隊技術人員編寫,轉載請標明出處