自定义 HttpMessageConverter (http 信息转换器)
- HTTP 请求和响应的传输是字节流,意味着浏览器和服务器通过字节流进行通信。但是,使用 Spring,controller类中的方法返回纯 String 类型或其他 Java 内建对象。如何将对象转换成字节流进行传输
- HttpMessageConverter是用来处理request 和response里的数据的。Spring为我们内置了大量的HttpMessageConverter,例如,MappingJackson2HttpMessageConverterStringHttpMessageConverter等。它会根据数据类型 来找对应的转换器进行数据转换。
package com.example.springboot.mvc;
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 org.springframework.util.StreamUtils;
import java.io.IOException;
import java.nio.charset.Charset;
/**
* @Author: hyh
* @Date: 2021/11/19 16:52
**/
// 定义自己的转换器 必须重写三个方法
public class MyConverter extends AbstractHttpMessageConverter<Zdy> {
// 我们可以定义自己的数据类型: xxx-zdy
public MyConverter() {
super(new MediaType("application", "xxx-zdy", Charset.defaultCharset()));
}
// 定义MyConverter 这个转换器 只处理 Zdy 这个实体类
@Override
protected boolean supports(Class clazz) {
return Zdy.class.isAssignableFrom(clazz);
}
@Override
protected Zdy readInternal(Class<? extends Zdy> clazz,
HttpInputMessage inputMessage) throws IOException,
HttpMessageNotReadableException {
// 取 输入的信息 转为 UTF-8 的字符串
String s = StreamUtils.copyToString(inputMessage.getBody(),
Charset.defaultCharset());
// 将信息塞到对象里返回然后交由接口去处理
return new Zdy(s);
}
@Override
protected void writeInternal(Zdy o, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
String s = "My Message";
// 接口返回 直接返回 My Message
outputMessage.getBody().write(s.getBytes());
}
}
package com.example.springboot.mvc;
import lombok.Data;
/**
* @Author: hyh
* @Date: 2021/11/19 17:08
**/
// 编写一个自定义实体类
@Data
public class Zdy {
private String s;
public Zdy(String s) {
this.s = s;
}
}
package com.example.springboot.mvc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import java.util.List;
/**
* @Author: hyh
* @Date: 2021/11/15 15:12
**/
@Configuration
@EnableWebMvc // 开启 webmvc
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//addResourceLocations 指的是文件放置的目录,addResourceHandler指的是对外暴露的访问
//路径。
registry.addResourceHandler("/assets/**")
.addResourceLocations("class:/assets/");
}
@Bean
public MyInterceptor interceptor(){
return new MyInterceptor();
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("WEB-INF/class/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
// 拦截所有请求
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor());
}
// 配置转换器的 bean
@Bean
public MyConverter myConverter(){
return new MyConverter();
}
// 重写 转换器 添加自己的转换器
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters
) {
converters.add(myConverter());
}
}
package com.example.springboot.mvc;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @Author: hyh
* @Date: 2021/11/15 16:27
**/
@Controller
public class ControllerH {
// 通过ModelAttribute 注解获取参数 msg
@GetMapping("index")
public void index(@ModelAttribute("msg") String msg){
}
// 跳转主页面 可以配置在是视图配置里
@RequestMapping("/index")
public String toIndex(){
return "index";
}
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file){
// 编写上传逻辑
return "ok";
}
// 编写自定义方法 参数类型写自己定义的类型
@RequestMapping(value = "/zdy",produces = "application/xxx-zdy")
@ResponseBody
public Zdy zdy(Zdy zdy){
// 编写逻辑
return zdy;
}
}
// 前台的ajax 请求
function req(){
$.ajax({
url:"zdy",
data: "hello",
type:"POST",
contentType: " application/xxx-zdy",//2
success: function (data){
$("#resp") .htm1 (data)
}
});
}
最后页面输出: My Message
下面是 具体的信息转换图: