SpringBoot自定义内容返回 (增加yaml返回支持)

目录

1. 多端内容适配

1. 默认规则

2. 效果演示

3.增加yaml返回支持

4.测试


先来了解默认的适配规则

1. 多端内容适配

1. 默认规则

          1.SpringBoot 多端内容适配。

               a.基于请求头内容协商:(默认开启) 

                   ⅰ. 客户端向服务端发送请求,携带HTTP标准的Accept请求头

                         1. Accept: application/json、text/xml、text/yaml

                          2.服务端根据客户端请求头期望的数据类型进行动态返回

                b.基于请求参数内容协商:(默认关闭)

                       i.发送请求 GET /projects/spring-boot?format=json

                       ii.匹配到 @GetMapping("/projects/spring-boot") 

                       iii.根据参数协商,优先返回 json 类型数据【需要开启参数匹配设置

                       ⅳ.发送请求 GET /projects/spring-boot?format=xml,优先返回 xml 类型数据

2. 效果演示

默认返回json数据

@RestController
public class PersonController {
    @GetMapping("/person")
    public Person person() {
        Person person = new Person();
        person.setId(1l);
        person.setUserName("pjp");
        person.setAge(21);
        person.setEmail("175@qq.com");
        return person;
    }
}

请求同一个接口,可以返回json和xml不同格式数据

  1. 引入支持写出xml内容依赖
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
  1. 标注注解
@JacksonXmlRootElement  // 可以写出为xml文档
@Data
public class Person {
    private Long id;
    private String userName;
    private String email;
    private Integer age;
}

此时引入jackson-dataformat-xml依赖 没有标注@JacksonXmlRootElement 依然返回的是xml格式的数据

  1. 开启基于请求参数的内容协商
# 开启基于请求参数的内容协商功能。 默认参数名:format。 默认此功能不开启
spring.mvc.contentnegotiation.favor-parameter=true

没有标注@JacksonXmlRootElement 依然生效

# 开启基于请求参数的内容协商功能。 默认参数名:format。 默认此功能不开启
spring.mvc.contentnegotiation.favor-parameter=true
# 指定内容协商时使用的参数名。默认是 format
spring.mvc.contentnegotiation.parameter-name=type

3.增加yaml返回支持

导入依赖

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

把对象写出成YAML

ObjectMapper类(com.fasterxml.jackson.databind.ObjectMapper)是Jackson的主要类,它可以帮助我们快速的进行各个类型和Json类型的相互转换。

public static void main(String[] args) throws JsonProcessingException {
    Person person = new Person();
    person.setId(1l);
    person.setUserName("pjp");
    person.setAge(21);
    person.setEmail("175@qq.com");
    ObjectMapper mapper = new ObjectMapper();
    //将对象转换为Json字符串
    String s = mapper.writeValueAsString(person);
    System.out.println(s);
}
输出:
{"id":1,"userName":"pjp","email":"175@qq.com","age":21}
public static void main(String[] args) throws JsonProcessingException {
    Person person = new Person();
    person.setId(1l);
    person.setUserName("pjp");
    person.setAge(21);
    person.setEmail("175@qq.com");
    
       //去掉输出前的 ---
//        YAMLFactory yamlFactory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
    YAMLFactory yamlFactory = new YAMLFactory();

    ObjectMapper mapper = new ObjectMapper(yamlFactory);
    //将对象转换为YAML字符串
    String s = mapper.writeValueAsString(person);
    System.out.println(s);
}
输出:
---
id: 1
userName: "pjp"
email: "175@qq.com"
age: 21

编写配置

# 新增一种媒体类型
#spring.mvc.contentnegotiation.media-types.yaml=text/yaml 
#或者
spring.mvc.contentnegotiation.media-types.yaml=application/yaml

增加HttpMessageConverter组件,专门负责把对象写出为yaml格式

package com.pjp.config;

import com.pjp.component.MyYAMLMessageConverter;
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 MvcConfig implements WebMvcConfigurer {
    @Override
    //自己写一个配置 一个能把对象转为yaml的messageConverter
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //        WebMvcConfigurer.super.extendMessageConverters(converters);
        converters.add(new MyYAMLMessageConverter());
    }
}
package com.pjp.component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;

public class MyYAMLMessageConverter extends AbstractHttpMessageConverter<Object> {
    private ObjectMapper objectMapper = null;

    public MyYAMLMessageConverter() {
        //new MediaType媒体类型
        //告诉SpringBoot这个MessageConverter支持哪种媒体类型
        super(new MediaType("application", "yaml", Charset.forName("UTF-8")));
        YAMLFactory factory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
        this.objectMapper = new ObjectMapper(factory);
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        //在这里判断类型
        //当前 只要是对象类型,不是基本类型直接返回true
        String clazzName = clazz.getName();
        if (clazzName.equals(java.lang.Integer.class) ||
            clazzName.equals(java.lang.Byte.class) ||
            clazzName.equals(java.lang.Long.class) ||
            clazzName.equals(java.lang.Double.class) ||
            clazzName.equals(java.lang.Float.class) ||
            clazzName.equals(java.lang.Character.class) ||
            clazzName.equals(java.lang.Short.class) ||
            clazzName.equals(java.lang.Boolean.class)) {
            return false;
        }
        return true;
    }

    @Override//@RequestBody
    protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }

    @Override//@ResponseBody 把对象写出去
    protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        //通过OutputStream将自定义数据写出去
        //        OutputStream body = outputMessage.getBody();
        //        try {
        //            this.objectMapper.writeValue(body,o);
        //        }finally {
        //            body.close();
        //        }
        //新语法try-with 自动关闭流
        try (OutputStream body = outputMessage.getBody()) {
            this.objectMapper.writeValue(body, o);
        }
    }

}

4.测试

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot Admin 提供了默认的监控界面和监控指标,但是有时候我们需要根据项目需求进行自定义监控。下面介绍一下如何自定义 Spring Boot Admin 监控。 1. 自定义监控指标 Spring Boot Admin 默认提供了一些监控指标,比如内存使用情况、线程池信息等。但是如果我们需要监控其他的指标,可以通过自定义 Endpoint 的方式来实现。 自定义 Endpoint 需要实现 `org.springframework.boot.actuate.endpoint.Endpoint` 接口,示例代码如下: ```java @Component public class CustomEndpoint implements Endpoint<Map<String, Object>> { @Override public String getId() { return "my-endpoint"; } @Override public boolean isEnabled() { return true; } @Override public boolean isSensitive() { return true; } @Override public Map<String, Object> invoke() { // 获取自定义指标信息 Map<String, Object> customMetrics = new HashMap<>(); customMetrics.put("customMetric1", "value1"); customMetrics.put("customMetric2", "value2"); return customMetrics; } } ``` 在 `invoke()` 方法中返回自定义的指标信息即可。同时需要注意的是,`isEnabled()` 和 `isSensitive()` 方法需要根据实际情况返回是否启用和是否敏感信息。 2. 自定义监控页面 Spring Boot Admin 的监控页面是基于 [AdminLTE](https://adminlte.io/) 构建的,可以通过自定义 AdminLTE 主题来自定义监控页面。 首先需要创建一个自定义的 AdminLTE 主题,可以在 [AdminLTE ThemeRoller](https://adminlte.io/themes/AdminLTE/index.html#!/custom) 上进行配置和下载。下载后将主题文件放到 Spring Boot Admin 的静态资源目录下即可。 然后在 Spring Boot Admin 的配置文件中添加如下配置: ```yaml spring: boot: admin: ui: custom: brand: primary: "#3c8dbc" title: "Custom Title" ``` 其中 `brand` 和 `title` 分别代表自定义的品牌颜色和标题,根据实际情况进行调整即可。 以上就是自定义 Spring Boot Admin 监控的方法,可以根据实际项目需求进行自定义
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PJP__00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值