creative建网站平台,旅游网站功能,怎么配置wordpress,电脑网站显示安全证书有问题怎么解决总览 什么是REST#xff1f; REST#xff08;代表状态转移#xff09;是Web构建的体系结构样式#xff0c;已成为用于Web应用程序的标准软件设计模式 。 代表性国家转移一词最早由REST的发起人#xff0c;HTTP规范的主要作者之一Roy Fielding在其博士论文中使用 。 REST上… 总览 什么是REST REST代表状态转移是Web构建的体系结构样式已成为用于Web应用程序的标准软件设计模式 。 代表性国家转移一词最早由REST的发起人HTTP规范的主要作者之一Roy Fielding在其博士论文中使用 。 REST上有很多很好的参考包括 维基百科 理查森成熟度模型 Ryan Tomayko如何向他的妻子解释REST Roy Fielding的REST API必须由超文本驱动 Stackoverflow SOAP与REST 本教程基于使用Spring构建Rest Services并且本教程的开头也对REST进行了很好的概述。 什么是弹簧启动执行器 Spring Boot Actuator是Spring Boot的子项目。 它为您的应用程序添加了几项生产级服务而您只需花费很少的精力。 执行器的定义 致动器是负责移动或控制系统的组件。 执行器一词不限于Spring Boot 但是这是我们在这里的重点。 在Spring Boot应用程序中配置Actuator之后它允许您通过调用Spring Boot Actuator公开的不同技术不可知端点例如应用程序运行状况Bean记录器映射和跟踪来交互和监视应用程序。 在此Spring文档中列出了更多信息。 0 –带启动器的Spring Boot RESTful Web服务示例应用程序 我们将使用Spring Boot和Actuator构建一个示例RESTful Web应用程序。 该应用程序将是“用户名跟踪器”。 在此应用程序中一个人拥有一个帐户他们的帐户可能具有许多用户名。 查看并从 Github 下载代码 1 –项目结构 和往常一样我们有一个正常的Maven项目结构。 2 –项目依赖性 除了典型的Spring Boot依赖关系之外我们还为嵌入式数据库提供了HSQLDB并为所有Actuator依赖关系提供了spring-boot-starter-actuator。 ?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.michaelcgood/groupIdartifactIdmichaelcgood-springbootactuator/artifactIdversion0.0.1/versionpackagingjar/packagingnameSpring-Boot-Actuator-Example/namedescriptionMichael C Good - Spring Boot Actuator Example/descriptionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion1.5.6.RELEASE/versionrelativePath/ !-- lookup parent from repository --/parentpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingjava.version1.8/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.hsqldb/groupIdartifactIdhsqldb/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project3 –运行空应用程序 尽管我们没有编写任何代码但是我们将运行Spring Boot应用程序。 转到您的终端并按照命令进行操作。 mikes-MacBook-Air:Spring-Boot-Actuator-Example mike$ curl localhost:8080
{timestamp:1505235455245,status:404,error:Not Found,message:No message available,path:/} 我们尚未编写任何代码除了默认的容器生成HTML错误响应外Actuator还从/ error端点生成JSON响应。 mikes-MacBook-Air:Spring-Boot-Actuator-Example mike$ curl localhost:8080/health
{status:UP} 执行器/运行状况端点将让您知道您的应用程序是否启动。 4 –模型 现在为用户名跟踪器应用程序定义模型的字段。 如前所述一个人有一个帐户可能有许多用户名。 所以我们用OneToMany注释映射Set 用户名模型将具有密码和用户名 我们的模型将需要一个ID并使其自动生成 我们进行类构造以定义可以使用用户名和密码创建的帐户。 由于使用了这种自定义构造函数因此我们还需要设置一个没有参数的默认构造函数。 Account.java package com.michaelcgood.model;import java.util.HashSet;
import java.util.Set;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;import com.fasterxml.jackson.annotation.JsonIgnore;Entity
public class Account {public SetUsernames getUsernames() {return usernames;}public void setUsernames(SetUsernames usernames) {this.usernames usernames;}public Long getId() {return id;}public void setId(Long id) {this.id id;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}OneToMany(mappedBy account)private SetUsernames usernames new HashSet();IdGeneratedValueprivate Long id;JsonIgnorepublic String password;public String username;public Account(String name, String password) {this.username name;this.password password;}Account(){}} 用户名.java 由于一个帐户可以使用多个用户名因此情况也相反一个帐户可以使用多个用户名。 因此我们使用ManyToOne注释映射Account 要跟踪用户名我们需要URL和用户名 我们再次定义一个自动生成的ID 我们定义了一个自定义类构造函数该构造函数需要accounturl和username参数。 再一次我们需要定义一个默认的构造函数方法以避免引发错误。 package com.michaelcgood.model;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;import com.fasterxml.jackson.annotation.JsonIgnore;Entity
public class Usernames {JsonIgnoreManyToOneprivate Account account;public Account getAccount() {return account;}public void setAccount(Account account) {this.account account;}public Long getId() {return id;}public void setId(Long id) {this.id id;}public String getUrl() {return url;}public void setUrl(String url) {this.url url;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}IdGeneratedValueprivate Long id;public String url;public String username;Usernames(){}public Usernames(Account account, String url, String username){this.urlurl;this.accountaccount;this.usernameusername;}}5 –储存库 我们为两个模型创建一个存储库并使用派生查询创建搜索功能。 AccountRepository.java package com.michaelcgood.dao;import java.util.Optional;import org.springframework.data.jpa.repository.JpaRepository;import com.michaelcgood.model.Account;public interface AccountRepository extends JpaRepositoryAccount,Long {OptionalAccount findByUsername(String username);
} 用户名Repository.java package com.michaelcgood.dao;import java.util.Collection;import org.springframework.data.jpa.repository.JpaRepository;import com.michaelcgood.model.Usernames;public interface UsernamesRepository extends JpaRepositoryUsernames,Long {CollectionUsernames findByAccountUsername(String username);}6 –控制器 在控制器中我们定义将用于RESTful Web服务的所有映射。 我们用RestController而不是Controller注释控制器。 如javadoc中所述它是“一种方便注释其本身通过Controller和ResponseBody进行了注释。” 我们声明UsernamesRepository和AccountRepository的变量并使其成为最终变量因为我们只希望将值分配一次。 我们通过UsernamesRestController类构造函数将它们注释为Autowired。 {userId}和{usernamesId}是路径变量 。 这意味着这些值在URL中提供。 这将在我们的演示中显示。 Controller方法返回POJO普通的旧Java对象 。 Spring Boot自动连接HttpMessageConverter以将这些通用对象转换为JSON。 用户名RestController.java package com.michaelcgood.controller;import java.net.URI;
import java.util.Collection;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;import com.michaelcgood.dao.AccountRepository;
import com.michaelcgood.dao.UsernamesRepository;
import com.michaelcgood.model.Usernames;RestController
RequestMapping(/{userId}/usernames)
public class UsernamesRestController {private final UsernamesRepository usernamesRepository;private final AccountRepository accountRepository;AutowiredUsernamesRestController(UsernamesRepository usernamesRepository, AccountRepository accountRepository){this.usernamesRepository usernamesRepository;this.accountRepository accountRepository;}GetMappingCollectionUsernames readUsernames (PathVariable String userId){this.validateUser(userId);return this.usernamesRepository.findByAccountUsername(userId);}PostMappingResponseEntity? add(PathVariable String userId,RequestBody Usernames input){this.validateUser(userId);return this.accountRepository.findByUsername(userId).map(account - {Usernames result usernamesRepository.save(new Usernames(account,input.url,input.username));URI url ServletUriComponentsBuilder.fromCurrentRequest().path(/{id}).buildAndExpand(result.getId()).toUri();return ResponseEntity.created(url).build(); }).orElse(ResponseEntity.noContent().build());}GetMapping(value{usernamesId})Usernames readUsername(PathVariable String userId, PathVariable Long usernameId){this.validateUser(userId);return this.usernamesRepository.findOne(usernameId);}private void validateUser(String userId){this.accountRepository.findByUsername(userId).orElseThrow(() - new UserNotFoundException(userId));}} UserNotFoundException.java 在这里我们定义了在Controller类中用来解释找不到用户的自定义异常。 package com.michaelcgood.controller;import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {/*** */private static final long serialVersionUID 7537022054146700535L;public UserNotFoundException(String userId){super(Sorry, we could not find user userId .);
}}7 – SpringBootApplication 我们使用CommandLineRunner创建帐户并插入用户名。 每个帐户都有两个用户名。 package com.michaelcgood;import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;import com.michaelcgood.dao.AccountRepository;
import com.michaelcgood.dao.UsernamesRepository;
import com.michaelcgood.model.Account;
import com.michaelcgood.model.Usernames;import java.util.Arrays;SpringBootApplication
public class SpringBootActuatorExampleApplication {public static void main(String[] args) {SpringApplication.run(SpringBootActuatorExampleApplication.class, args);}BeanCommandLineRunner init(AccountRepository accountRepository,UsernamesRepository usernamesRepository) {return (evt) - Arrays.asList(ricksanchez,mortysmith,bethsmith,jerrysmith,summersmith,birdperson,squanchy,picklerick.split(,)).forEach(a - {Account account accountRepository.save(new Account(a,password));usernamesRepository.save(new Usernames(account,http://example.com/login, a 1));usernamesRepository.save(new Usernames(account,http://example2.com/login, the_a));});}
}8 –配置 在Spring文档中有说明 默认情况下所有敏感的HTTP端点都是安全的因此只有具有ACTUATOR角色的用户才能访问它们。 使用标准的HttpServletRequest.isUserInRole方法可以增强安全性。 我们尚未设置任何安全性和用户角色因为这只是一个示例。 因此为了便于演示我将禁用安全性要求。 否则我们将立即收到一个“未经授权”的错误如下图所示。 {timestamp:1505321635068,status:401,error:Unauthorized,message:Full authentication is required to access this resource.,path:/beans} application.properties 将此添加到application.properties以禁用身份验证。 management.security.enabledfalse9 –演示 要从服务器检索响应您可以在浏览器中访问URL或使用curl。 对于我的演示我正在使用curl。 REST查询存储库中的数据 查询属于帐户jerrysmith的用户名。 mikes-MacBook-Air:Spring-Boot-Actuator-Example mike$ curl localhost:8080/jerrysmith/usernames
[{id:7,url:http://example.com/login,username:jerrysmith1},{id:8,url:http://example2.com/login,username:the_jerrysmith}] 查询属于帐户picklerick的用户名 mikes-MacBook-Air:Spring-Boot-Actuator-Example mike$ curl localhost:8080/picklerick/usernames
[{id:15,url:http://example.com/login,username:picklerick1},{id:16,url:http://example2.com/login,username:the_picklerick}] 执行器查询 该查询的响应非常长因此被截断了。 豆子 mikes-MacBook-Air:Spring-Boot-Actuator-Example mike$ curl localhost:8080/beans
[{context:application,parent:null,beans:[{bean:springBootActuatorExampleApplication,aliases:[],scope:singleton,type:com.michaelcgood.SpringBootActuatorExampleApplication$$EnhancerBySpringCGLIB$$509f4984,resource:null,dependencies:[]},{bean:org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory,aliases:[],scope:singleton,type:org.springframework.core.type.classreading.CachingMetadataReaderFactory,resource:null,dependencies:[]},{bean:usernamesRestController,aliases:[],scope:singleton,type:com.michaelcgood.controller.UsernamesRestController,resource:file [/Users/mike/javaSTS/Spring-Boot-Actuator-Example/target/classes/com/michaelcgood/controller/UsernamesRestController.class],dependencies:[usernamesRepository,accountRepository]},{bean:init,aliases:[],scope:singleton,type:com.michaelcgood.SpringBootActuatorExampleApplication$$Lambda$11/889398176,resource:com.michaelcgood.SpringBootActuatorExampleApplication,
[...]指标 mikes-MacBook-Air:Spring-Boot-Actuator-Example mike$ curl localhost:8080/metrics
{mem:350557,mem.free:208275,processors:4,instance.uptime:213550,uptime:240641,systemload.average:1.6552734375,heap.committed:277504,heap.init:131072,heap.used:69228,heap:1864192,nonheap.committed:74624,nonheap.init:2496,nonheap.used:73062,nonheap:0,threads.peak:27,threads.daemon:23,threads.totalStarted:30,threads:25,classes:9791,classes.loaded:9791,classes.unloaded:0,gc.ps_scavenge.count:11,gc.ps_scavenge.time:139,gc.ps_marksweep.count:2,gc.ps_marksweep.time:148,httpsessions.max:-1,httpsessions.active:0,datasource.primary.active:0,datasource.primary.usage:0.0,gauge.response.beans:14.0,gauge.response.info:13.0,counter.status.200.beans:2,counter.status.200.info:1}9 –结论 恭喜您已经创建了一个可以用Actuator监视的RESTful Web服务。 REST实际上是不同客户端进行通信的最有机的方式因为它由于HTTP而起作用。 源代码在 Github上 翻译自: https://www.javacodegeeks.com/2017/10/building-spring-boot-restful-service-spring-boot-actuator.html