Spring Boot Rest XML 示例 – 带有 XML 响应的 Web 服务

Spring Boot Rest XML example - Web service with XML Response - BezKodericon-default.png?t=M0H8https://www.bezkoder.com/spring-boot-rest-xml/

在本 Spring Boot 教程中,我将向您展示一个 Restful Web 服务示例,其中 Spring REST 控制器可以接收/使用 XML 请求正文并返回 XML 响应而不是 JSON。我们还使用 Spring Data JPA 与数据库(MySQL/PostgreSQL)进行交互。

更多实践:
– Spring Boot、Spring Data JPA – 构建 Rest CRUD API 示例
– Spring Boot + GraphQL + MySQL 示例

部署:
在 AWS 上部署 Spring Boot 应用程序 – Elastic Beanstalk
– Docker Compose:Spring Boot 和 MySQL 示例

Spring Boot XML REST 服务

呈现 XML 响应的方法有两种:

使用 Jackson XML 扩展 ( jackson-dataformat-xml) 来呈现 XML 响应很容易,只需添加以下依赖项:

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

使用具有依赖关系的 JAXB:

<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
</dependency>

所以 XML 可以通过@XmlRootElement在数据模型 lass 处注解来渲染:

@XmlRootElement
public class Tutorial {
  private String title;
  // .. getters and setters
}

在这个例子中,我们将使用第一种方式。

返回 XML 响应

MediaType.APPLICATION_XML_VALUE您可以通过使用作为注释的produces值来告诉控制器哪些方法应该返回 XML 响应。@RequestMapping

@RequestMapping(value="/tutorials/{id}", produces=MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
  // ...
}

如果您想让所有 Controller 方法都返回 XML 响应,则不必用produces=MediaType.APPLICATION_XML_VALUE. 只需通过实施WebMvcConfigurer和覆盖来实施内容协商configureContentNegotiation()

@Configuration
public class WebConfig implements WebMvcConfigurer {
  @Override
  public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
    configurer.defaultContentType(MediaType.APPLICATION_XML);
  }
}

Spring Boot Rest XML 示例概述

我们将构建一个为教程应用程序提供 CRUD API 的 Restful Web 服务:

  • 每个教程都有 ID、标题、描述、发布状态。
  • API 帮助创建、检索、更新、删除教程。
  • APIs 还支持自定义查找器方法,例如按已发布状态或按标题查找。
  • XML 是 HTTP 请求和响应的内容类型。

以下是 API:

方法网址行动
邮政/api/教程创建新教程
得到/api/教程检索所有教程
得到/api/tutorials/:id检索教程:id
/api/tutorials/:id更新教程:id
删除/api/tutorials/:id删除教程:id
删除/api/教程删除所有教程
得到/api/教程/已发布查找所有已发布的教程
得到/api/tutorials?title=[关键字]查找标题包含的所有教程keyword

– 我们使用 Spring Data JPA 的 CRUD 操作和查找方法JpaRepository
– 根据我们配置项目依赖和数据源的方式,数据库可以是 PostgreSQL 或 MySQL。

技术

  • 爪哇 8
  • Spring Boot 2.2.1(带有 Spring Web MVC、Spring Data JPA)
  • PostgreSQL/MySQL
  • Maven 3.6.1
  • 杰克逊数据格式 XML 2.10.1

项目结构

 

WebConfig实现WebMvcConfigurer。这是我们设置默认内容类型的地方。
Tutorial数据模型类对应实体和表教程
–是为 CRUD 方法和自定义查找器方法TutorialRepository扩展JpaRepository的接口。它将自动装配到TutorialController.
TutorialController是一个RestController,它具有 RESTful 请求的请求映射方法,例如:getAllTutorialscreateTutorialupdateTutorialdeleteTutorialfindByPublished …
– Spring Datasource、JPA 和 Hibernate 的配置应用程序.properties
– pom.xml包含 Spring Boot、ackson Dataformat XML 和 MySQL/PostgreSQL 的依赖项。

创建和设置 Spring Boot 项目

使用Spring Web 工具或您的开发工具(Spring Tool Suite、Eclipse、Intellij)创建一个 Spring Boot 项目。

然后打开pom.xml并添加这些依赖项:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.dataformat</groupId>
	<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

我们还需要再添加一个依赖项。
– 如果你想使用MySQL

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

– 或PostgreSQL

<dependency>
	<groupId>org.postgresql</groupId>
	<artifactId>postgresql</artifactId>
	<scope>runtime</scope>
</dependency>

配置 Spring Datasource、JPA、Hibernate

在 src/main/resources 文件夹下,打开 application.properties 并写入这些行。

– 对于 MySQL:

spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
spring.datasource.username= root
spring.datasource.password= 123456
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update

– 对于 PostgreSQL:

spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
spring.datasource.username= postgres
spring.datasource.password= 123
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update
  • spring.datasource.username&spring.datasource.password属性与您的数据库安装相同。
  • Spring Boot 使用 Hibernate 进行 JPA 实现,我们MySQL5InnoDBDialect为 MySQL 或PostgreSQLDialectPostgreSQL配置
  • spring.jpa.hibernate.ddl-auto用于数据库初始化。我们将 value 设置为 value,update以便在数据库中创建一个表,自动对应于定义的数据模型。对模型的任何更改也将触发对表的更新。对于生产,这个属性应该是validate

定义数据模型

我们的数据模型是具有四个字段的教程:id、title、description、published。
模型包中,我们定义了Tutorial类。

model/Tutorial.java

package com.bezkoder.spring.datajpa.xml.model;
import javax.persistence.*;
@Entity
@Table(name = "tutorials")
public class Tutorial {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  @Column(name = "title")
  private String title;
  @Column(name = "description")
  private String description;
  @Column(name = "isPublished")
  private boolean published;
  public Tutorial() {
  }
  public Tutorial(String title, String description, boolean published) {
    this.title = title;
    this.description = description;
    this.published = published;
  }
  public long getId() {
    return id;
  }
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
  public boolean isPublished() {
    return published;
  }
  public void setPublished(boolean isPublished) {
    this.published = isPublished;
  }
  @Override
  public String toString() {
    return "Tutorial [id=" + id + ", title=" + title + ", desc=" + description + ", published=" + published + "]";
  }
}

@Entity注解表明该类是一个持久的 Java 类。
@Table注释提供映射该实体的表。
@Id注释用于主键。
@GeneratedValue注解用于定义主键的生成策略。GenerationType.AUTO表示自动增量字段。
@Column注释用于定义数据库中映射注释字段的列。

创建存储库接口

让我们创建一个存储库以与数据库中的教程进行交互。
存储库包中,创建TutorialRepository扩展接口JpaRepository

repository/TutorialRepository.java

package com.bezkoder.spring.datajpa.xml.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.bezkoder.spring.datajpa.xml.model.Tutorial;
public interface TutorialRepository extends JpaRepository<Tutorial, Long> {
  List<Tutorial> findByPublished(boolean published);
  List<Tutorial> findByTitleContaining(String title);
}

现在我们可以使用 JpaRepository 的方法:save()findOne()findById()findAll()count()delete()deleteById()... 而不实现这些方法。

我们还定义了自定义查找器方法:
– findByPublished():返回所有published具有输入值的教程published
findByTitleContaining():返回所有标题包含输入的教程title

该实现由Spring Data JPA自动插入。

为 XML 类型配置内容协商

现在我们要在我们的 Spring Boot 项目中实现内容协商。

config/WebConfig.java

package com.bezkoder.spring.datajpa.xml.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
  @Override
  public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
    configurer.defaultContentType(MediaType.APPLICATION_XML);
  }
}

创建 Spring Rest API 控制器

最后,我们创建一个控制器,提供用于创建、检索、更新、删除和查找教程的 API。

controller/TutorialController.java

package com.bezkoder.spring.datajpa.xml.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.bezkoder.spring.datajpa.xml.model.Tutorial;
import com.bezkoder.spring.datajpa.xml.repository.TutorialRepository;
@CrossOrigin(origins = "http://localhost:8081")
@RestController
@RequestMapping("/api")
public class TutorialController {
  @Autowired
  TutorialRepository tutorialRepository;
  @GetMapping("/tutorials")
  public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {
    try {
      List<Tutorial> tutorials = new ArrayList<Tutorial>();
      if (title == null)
        tutorialRepository.findAll().forEach(tutorials::add);
      else
        tutorialRepository.findByTitleContaining(title).forEach(tutorials::add);
      if (tutorials.isEmpty()) {
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
      }
      return new ResponseEntity<>(tutorials, HttpStatus.OK);
    } catch (Exception e) {
      return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
  @GetMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
    Optional<Tutorial> tutorialData = tutorialRepository.findById(id);
    if (tutorialData.isPresent()) {
      return new ResponseEntity<>(tutorialData.get(), HttpStatus.OK);
    } else {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
  }
  @PostMapping("/tutorials")
  public ResponseEntity<Tutorial> createTutorial(@RequestBody Tutorial tutorial) {
    try {
      Tutorial _tutorial = tutorialRepository.save(new Tutorial(tutorial.getTitle(), tutorial.getDescription(), false));
      return new ResponseEntity<>(_tutorial, HttpStatus.CREATED);
    } catch (Exception e) {
      return new ResponseEntity<>(null, HttpStatus.EXPECTATION_FAILED);
    }
  }
  @PutMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
    Optional<Tutorial> tutorialData = tutorialRepository.findById(id);
    if (tutorialData.isPresent()) {
      Tutorial _tutorial = tutorialData.get();
      _tutorial.setTitle(tutorial.getTitle());
      _tutorial.setDescription(tutorial.getDescription());
      _tutorial.setPublished(tutorial.isPublished());
      return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
    } else {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
  }
  @DeleteMapping("/tutorials/{id}")
  public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
    try {
      tutorialRepository.deleteById(id);
      return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    } catch (Exception e) {
      return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
    }
  }
  @DeleteMapping("/tutorials")
  public ResponseEntity<HttpStatus> deleteAllTutorials() {
    try {
      tutorialRepository.deleteAll();
      return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    } catch (Exception e) {
      return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
    }
  }
  @GetMapping("/tutorials/published")
  public ResponseEntity<List<Tutorial>> findByPublished() {
    try {
      List<Tutorial> tutorials = tutorialRepository.findByPublished(true);
      if (tutorials.isEmpty()) {
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
      }
      return new ResponseEntity<>(tutorials, HttpStatus.OK);
    } catch (Exception e) {
      return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
    }
  }
}

@CrossOrigin用于配置允许的来源。
@RestController注释用于定义控制器并指示方法的返回值应绑定到 Web 响应体。
@RequestMapping("/api")声明控制器中所有 APIs 的 url 都以/api.
– 我们使用@Autowired注入TutorialRepositorybean 到局部变量。

运行和测试

使用命令运行 Spring Boot 应用程序:mvn spring-boot:run

教程表将在数据库中自动生成。
例如,如果您检查 MySQL,您会看到如下内容:

mysql> describe tutorials;
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | bigint(20)   | NO   | PRI | NULL    |       |
| description  | varchar(255) | YES  |     | NULL    |       |
| is_published | bit(1)       | YES  |     | NULL    |       |
| title        | varchar(255) | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+

创建教程:

 

mysql> select * from tutorials;
+----+-----------------------+--------------+--------+
| id | description           | is_published | title  |
+----+-----------------------+--------------+--------+
|  1 | Tut#1 Description     | 0            | Tut #1 |
|  2 | Tut#2 Description     | 0            | Tut #2 |
|  3 | Tut#3 Description     | 0            | Tut #3 |
|  4 | Description for Tut#4 | 0            | Tut #4 |
|  5 | Description for Tut#5 | 0            | Tut #5 |
+----+-----------------------+--------------+--------+

获取所有教程:

 

按 ID 获取教程:

更新一些教程:

 

mysql> select * from tutorials;
+----+-----------------------+--------------+---------------------+
| id | description           | is_published | title               |
+----+-----------------------+--------------+---------------------+
|  1 | Tut#1 Desc            | 0            | bezkoder.com Tut #1 |
|  2 | Tut#2 Description     | 0            | Tut #2              |
|  3 | Tut#3 Desc            | 1            | bezkoder.com Tut #3 |
|  4 | Description for Tut#4 | 0            | Tut #4              |
|  5 | Tut#5 Desc            | 1            | bezkoder.com Tut #5 |
+----+-----------------------+--------------+---------------------+

查找所有已发布的教程:

查找标题包含“zkoder”的所有教程:

 

删除教程:

 

mysql> select * from tutorials;
+----+-------------------+--------------+---------------------+
| id | description       | is_published | title               |
+----+-------------------+--------------+---------------------+
|  1 | Tut#1 Desc        | 0            | bezkoder.com Tut #1 |
|  2 | Tut#2 Description | 0            | Tut #2              |
|  3 | Tut#3 Desc        | 1            | bezkoder.com Tut #3 |
|  5 | Tut#5 Desc        | 1            | bezkoder.com Tut #5 |
+----+-------------------+--------------+---------------------+

使用 API 删除所有教程:DELETE http://localhost:8080/api/tutorials/

mysql> select * from tutorials;
Empty set (0.00 sec)

结论

今天我们构建了一个 Spring Boot Rest XML 示例,使用 Jackson XML 扩展来渲染 XML 和 Spring Data JPA 以与 MySQL/PostgreSQL 交互。您已经知道在请求正文中使用 XML 并返回 XML 响应的方法。

如果您想了解有关在请求和响应中处理 JSON 数据的 Spring Boot Webservice 的更多信息,请访问:
Spring Boot,Spring Data JPA – 构建 Rest CRUD API 示例

快乐学习!再见。

延伸阅读

部署:
在 AWS 上部署 Spring Boot 应用程序 – Elastic Beanstalk
– Docker Compose:Spring Boot 和 MySQL 示例

源代码

您可以在Github上找到本教程的完整源代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot 中的 OAuth 资源服务器配置需要在应用程序的配置文件中添加一些属性,并在应用程序中启用 OAuth 资源服务器。 1. 在配置文件中添加以下属性: - spring.security.oauth2.resource.jwt.key-value: 用于验证 JWT 令牌的公钥或私钥 - spring.security.oauth2.resource.user-info-uri: 用于获取用户信息的 URI 2. 在应用程序中启用 OAuth 资源服务器: - 在主类中添加 @EnableResourceServer 注解 - 在配置类中添加 @EnableAuthorizationServer 注解 3. 配置安全配置类,在这个类中添加配置信息 参考代码: ``` @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Value("${spring.security.oauth2.resource.jwt.key-value}") private String jwtKeyValue; @Value("${spring.security.oauth2.resource.user-info-uri}") private String userInfoUri; @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId("resource-server-rest-api").tokenStore(tokenStore()); } @Bean public TokenStore tokenStore() { return new JwtTokenStore(jwtTokenEnhancer()); } @Bean protected JwtAccessTokenConverter jwtTokenEnhancer() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(jwtKeyValue); return converter; } @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/api/**").authenticated() .and() .requestMatcher(new OAuthRequestedMatcher()); } private static class OAuthRequestedMatcher implements RequestMatcher { public boolean matches(HttpServletRequest request) { String auth = request.getHeader("Authorization"); // Determine if the client request contained an OAuth Authorization boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer"); boolean haveAccessToken = request.getParameter(" ### 回答2: Spring Boot中的OAuth资源服务器配置是通过添加相关依赖和配置文件来实现的。 首先,我们需要在项目的pom.xml文件中添加Spring Security和Spring Security OAuth2的依赖,例如: ``` <dependencies> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- Spring Security OAuth2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> </dependencies> ``` 然后,我们需要在项目的配置文件(例如application.yml)中配置相关的OAuth2资源服务器属性,例如: ``` spring: security: oauth2: resourceserver: jwt: issuer-uri: <身份验证服务器的URL> ``` 在上述配置中,我们需要指定身份验证服务器的URL,它将用于验证和解析传入的JWT令牌。 接下来,我们可以创建一个类来配置资源服务器的行为,例如: ```java @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/public/**").permitAll() .anyRequest().authenticated(); } } ``` 在上述示例中,我们使用@EnableResourceServer注解启用资源服务器,并指定了访问权限规则。在这个例子中,我们允许/public路径下的请求被所有人访问,其他任何请求都需要通过身份验证。 最后,我们可以使用@RestController注解创建一个简单的REST控制器来演示资源服务器的功能,例如: ```java @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, World!"; } } ``` 这样,我们就可以使用OAuth2的令牌来访问该控制器所暴露的资源。 综上所述,通过添加依赖、配置属性和编写相关配置类,我们可以在Spring Boot中配置OAuth资源服务器。 ### 回答3: 在Spring Boot中配置OAuth资源服务器包括以下步骤: 1. 添加必要的依赖:在pom.xml文件中添加Spring Security OAuth2依赖。例如,可以添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> </dependency> ``` 2. 创建一个配置类:创建一个@Configuration注解的配置类,并使用@EnableResourceServer注解启用资源服务器。例如: ``` @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/api/**").authenticated() .anyRequest().permitAll(); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId("my-resource-id"); } } ``` 3. 配置访问权限:使用HttpSecurity配置http的请求权限。在上述示例中,`/api/**`路径的请求需要进行身份验证。可以根据实际情况配置其他路径和权限。 4. 配置资源ID:使用ResourceServerSecurityConfigurer配置资源服务器的资源ID。资源ID可以是任何唯一标识符,用于标识受保护的资源。 以上是基本的OAuth资源服务器配置步骤。配置完成后,可以使用OAuth2的授权服务器进行认证,并使用访问令牌对受保护的资源进行访问控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值