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月前
|
人工智能 自然语言处理 监控
发布即颠覆?实测smardaten 2.0 :当 AI 遇上无代码软件开发,真的能重新定义 “对话即开发”
发布即颠覆?实测smardaten 2.0 :当 AI 遇上无代码软件开发,真的能重新定义 “对话即开发”
|
数据采集 小程序 API
通义千问Qwen2.5-Coder 全系列来咯!强大、多样、实用
千问团队开源了强大的 Qwen2.5-Coder 系列模型,涵盖 0.5B 到 32B 六种尺寸,旨在推动开放代码模型的发展。该系列模型在代码生成、修复和推理等方面表现出色,支持多种编程语言,并在多个基准测试中达到 SOTA 水平。此外,Qwen2.5-Coder 还提供了丰富的应用场景,如代码助手、Artifacts 和 Interpreter,满足不同开发者的需求。
4584 106
|
8月前
|
人工智能 数据可视化 JavaScript
2.1k star! 抓紧冲,DeepChat:连接AI与个人世界的智能助手的开源项目
DeepChat是一款开源跨平台智能助手工具,采用Apache-2.0协议,已获2.1k星标。它支持Windows/macOS/Linux,兼容20+主流AI服务,如OpenAI、Gemini等,还支持本地部署的开源模型。其核心功能包括全模型兼容架构、智能搜索增强、可视化工具平台(MCP)、多模态呈现及隐私安全设计。DeepChat适用于程序员助手、内容创作、学习研究、数据分析和智能办公五大场景。项目优势在于智能搜索决策、零配置工具链和企业级扩展性,是探索AI应用的理想选择。项目地址:https://github.com/ThinkInAIXYZ/deepchat。
596 0
|
存储 安全 Java
SpringBoot异步任务获取HttpServletRequest
通过上述方法,我们可以在Spring Boot应用中的异步任务获取 `HttpServletRequest`,从而实现更为灵活和高效的异步处理逻辑。
815 64
|
Java iOS开发 MacOS
8 种 Java- 内存溢出之四 -Metaspace
8 种 Java- 内存溢出之四 -Metaspace
|
Linux 网络安全 数据安全/隐私保护
Jetson 学习笔记(十三):SSH远程登录控制(终端控制和图形界面)-成功通过
这篇文章介绍了如何通过SSH命令行和VNC图形界面远程登录和控制NVIDIA Jetson Nano设备。
2201 0
Jetson 学习笔记(十三):SSH远程登录控制(终端控制和图形界面)-成功通过
|
机器学习/深度学习 人工智能
LabVIEW使用OpenVINO加速必备工具包下载与安装教程
LabVIEW使用OpenVINO加速必备工具包下载与安装教程
578 0
LabVIEW使用OpenVINO加速必备工具包下载与安装教程
|
Rust 开发者
揭秘Rust编程:模块与包的终极对决,谁将主宰代码组织的新秩序?
【8月更文挑战第31天】在软件工程中,模块化设计能显著提升代码的可读性、可维护性和可重用性。Rust 作为现代系统编程语言,其模块和包管理机制为开发者提供了强有力的工具来组织代码。本文通过对比模块和包的概念及使用场景,探讨了 Rust 中的最佳实践。
220 2
|
XML JSON Java
SpringBoot3---核心特性---2、Web开发II
SpringBoot3---核心特性---2、Web开发II
|
存储 机器人
01 ROS基本概念及命令
这篇文章介绍了ROS(机器人操作系统)的基本概念,如节点、ROS Master、参数、通信机制(话题和消息、服务)、功能包、命名空间和命名重映射,以及一些基本的ROS命令行工具的使用,例如rosnode、rostopic、rossrv、rosservice、rosparam和roslaunch。
559 0