Spring Boot中的内容协商

简介: Spring Boot中的内容协商

Spring Boot中的内容协商

今天我们来探讨一下Spring Boot中的内容协商(Content Negotiation)。内容协商是一个重要的Web服务功能,它允许服务器根据客户端请求中的头信息返回不同格式的数据,例如JSON、XML等。通过内容协商,开发者可以为同一个资源提供多种表示形式。

一、内容协商的基本概念

内容协商是HTTP协议中的一部分,允许客户端和服务器就响应的最佳表示形式达成一致。在HTTP请求中,客户端可以通过Accept头指定希望接收的响应格式,服务器则会根据这一信息决定返回哪种格式的数据。

二、Spring Boot中的内容协商配置

在Spring Boot中,内容协商通过ContentNegotiationConfigurer进行配置。我们可以在配置类中设置默认的媒体类型和支持的媒体类型。

首先,创建一个配置类:

package cn.juwatech.config;

import org.springframework.context.annotation.Configuration;
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(ContentNegotiationConfigurer configurer) {
   
        configurer
            .favorParameter(true)
            .parameterName("mediaType")
            .ignoreAcceptHeader(false)
            .defaultContentType(org.springframework.http.MediaType.APPLICATION_JSON)
            .mediaType("json", org.springframework.http.MediaType.APPLICATION_JSON)
            .mediaType("xml", org.springframework.http.MediaType.APPLICATION_XML);
    }
}

三、控制器中的内容协商

接下来,我们在控制器中编写示例代码,展示如何根据请求的媒体类型返回不同格式的数据。

package cn.juwatech.controller;

import cn.juwatech.model.User;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

@RestController
public class UserController {
   

    @GetMapping(value = "/users", produces = {
   MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
    public List<User> getUsers() {
   
        return Arrays.asList(
            new User(1, "John Doe", "john.doe@example.com"),
            new User(2, "Jane Smith", "jane.smith@example.com")
        );
    }
}

四、模型类

为了使上述代码正常工作,我们需要创建一个简单的模型类User

package cn.juwatech.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class User {
   

    private int id;
    private String name;
    private String email;

    public User() {
   
    }

    public User(int id, String name, String email) {
   
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public int getId() {
   
        return id;
    }

    public void setId(int id) {
   
        this.id = id;
    }

    public String getName() {
   
        return name;
    }

    public void setName(String name) {
   
        this.name = name;
    }

    public String getEmail() {
   
        return email;
    }

    public void setEmail(String email) {
   
        this.email = email;
    }
}

五、测试内容协商

现在,我们可以通过不同的方式来测试内容协商功能。

  1. 使用浏览器:

    • 访问http://localhost:8080/users?mediaType=json,浏览器会显示JSON格式的数据。
    • 访问http://localhost:8080/users?mediaType=xml,浏览器会显示XML格式的数据。
  2. 使用curl命令行工具:

    • 请求JSON格式的数据:
      curl -H "Accept: application/json" http://localhost:8080/users
      
    • 请求XML格式的数据:
      curl -H "Accept: application/xml" http://localhost:8080/users
      

六、使用自定义消息转换器

有时,我们需要自定义消息转换器以支持特殊的媒体类型。以下是一个示例,展示如何在Spring Boot中注册自定义消息转换器。

首先,创建自定义消息转换器类:

package cn.juwatech.converter;

import cn.juwatech.model.User;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class CustomMessageConverter extends AbstractHttpMessageConverter<User> {
   

    public CustomMessageConverter() {
   
        super(new MediaType("application", "x-custom-type", StandardCharsets.UTF_8));
    }

    @Override
    protected boolean supports(Class<?> clazz) {
   
        return User.class.equals(clazz);
    }

    @Override
    protected User readInternal(Class<? extends User> clazz, HttpInputMessage inputMessage) throws IOException {
   
        // 实现读取逻辑
        return null;
    }

    @Override
    protected void writeInternal(User user, HttpOutputMessage outputMessage) throws IOException {
   
        // 实现写入逻辑
        String output = "Custom User Output: " + user.getName();
        outputMessage.getBody().write(output.getBytes(StandardCharsets.UTF_8));
    }
}

接下来,在配置类中注册这个自定义消息转换器:

package cn.juwatech.config;

import cn.juwatech.converter.CustomMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {
   

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
   
        converters.add(new CustomMessageConverter());
    }
}

七、测试自定义消息转换器

为了测试自定义消息转换器,我们可以更新控制器中的方法,使其支持自定义的媒体类型:

@GetMapping(value = "/custom-user", produces = "application/x-custom-type")
public User getCustomUser() {
   
    return new User(1, "John Doe", "john.doe@example.com");
}

现在,我们可以通过以下命令测试自定义消息转换器:

curl -H "Accept: application/x-custom-type" http://localhost:8080/custom-user

总结

通过本文,我们了解了在Spring Boot中实现内容协商的基本方法,包括配置内容协商、使用不同的媒体类型返回数据以及自定义消息转换器。内容协商是构建灵活、高效的RESTful服务的重要组成部分,能够帮助我们更好地满足不同客户端的需求。

相关文章
|
5月前
|
人工智能 开发框架 安全
浅谈 Agent 开发工具链演进历程
模型带来了意识和自主性,但在输出结果的确定性和一致性上降低了。无论是基础大模型厂商,还是提供开发工具链和运行保障的厂家,本质都是希望提升输出的可靠性,只是不同的团队基因和行业判断,提供了不同的实现路径。本文按四个阶段,通过串联一些知名的开发工具,来回顾 Agent 开发工具链的演进历程。
1025 71
|
2月前
|
Java 应用服务中间件 微服务
SpringBoot
Spring Boot是Spring框架的扩展,旨在简化Spring应用的初始搭建和开发过程。它通过自动配置、内嵌服务器、起步依赖等特性,减少繁琐的配置,实现快速开发与部署,提升开发者效率,是现代Java开发尤其是微服务架构的重要工具。
 SpringBoot
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
14301 60
|
存储 安全 Java
SpringBoot异步任务获取HttpServletRequest
通过上述方法,我们可以在Spring Boot应用中的异步任务获取 `HttpServletRequest`,从而实现更为灵活和高效的异步处理逻辑。
892 64
|
监控 Java
MaxGCPauseMillis参数
MaxGCPauseMillis参数
|
XML 安全 Java
Spring Boot中使用MapStruct进行对象映射
本文介绍如何在Spring Boot项目中使用MapStruct进行对象映射,探讨其性能高效、类型安全及易于集成等优势,并详细说明添加MapStruct依赖的步骤。
564 0
|
Linux 网络安全 数据安全/隐私保护
Jetson 学习笔记(十三):SSH远程登录控制(终端控制和图形界面)-成功通过
这篇文章介绍了如何通过SSH命令行和VNC图形界面远程登录和控制NVIDIA Jetson Nano设备。
2701 0
Jetson 学习笔记(十三):SSH远程登录控制(终端控制和图形界面)-成功通过
|
Rust 开发者
揭秘Rust编程:模块与包的终极对决,谁将主宰代码组织的新秩序?
【8月更文挑战第31天】在软件工程中,模块化设计能显著提升代码的可读性、可维护性和可重用性。Rust 作为现代系统编程语言,其模块和包管理机制为开发者提供了强有力的工具来组织代码。本文通过对比模块和包的概念及使用场景,探讨了 Rust 中的最佳实践。
246 2
|
安全 前端开发 Java
WebMvcConfigurationSupport 和 WebMvcConfigurer 区别你知道吗
WebMvcConfigurationSupport 和 WebMvcConfigurer 的使用过程中你是否踩坑了它们的区别是什么快来看看吧
1196 0
|
存储 数据安全/隐私保护
一键云端,AList 整合多网盘,轻松管理文件多元共享
一键云端,AList 整合多网盘,轻松管理文件多元共享
3234 0

热门文章

最新文章