springboot页⾯跳转注解_结合参数接收响应转换原理讲解
SpringBoot常⽤注解
⼀、常⽤注解回顾
1.1 @RequestBody与@ResponseBody
//注意并不要求@RequestBody与@ResponseBody成对使⽤。
public @ResponseBody AjaxResponse saveArticle(@RequestBody ArticleVO article)
如上代码所⽰:
@RequestBody修饰请求参数,注解⽤于接收HTTP的body,默认是使⽤JSON的格式
@ResponseBody修饰返回值,注解⽤于在HTTP的body中携带响应数据,默认是使⽤JSON的格式。如果不加该注解,spring响应字符串类型,是跳转到模板页⾯或jsp页⾯的开发模式。说⽩了:加上这个注解你开发的是⼀个数据接⼝,不加这个注解你开发的是⼀个页⾯跳转控制器。
那么我们有⼀个问题:如果我们想接收或XML数据该怎么办?我们想响应excel的数据格式该怎么办?我
们后⽂来回答这个问题。
1.2. @RequestMapping注解
@RequestMapping注解是所有常⽤注解中,最有看点的⼀个注解,⽤于标注HTTP服务端点。它的很多属性对于丰富我们的应⽤开发⽅式⽅法,都有很重要的作⽤。如:
value: 应⽤请求端点,最核⼼的属性,⽤于标志请求处理⽅法的唯⼀性;
method: HTTP协议的method类型, 如:GET、POST、PUT、DELETE等;
consumes: HTTP协议请求内容的数据类型(Content-Type),例如application/json, text/html;
produces: HTTP协议响应内容的数据类型。下⽂会详细讲解。
params: HTTP请求中必须包含某些参数值的时候,才允许被注解标注的⽅法处理请求。
headers: HTTP请求中必须包含某些指定的header值,才允许被注解标注的⽅法处理请求。
@RequestMapping(value = "/article", method = POST)
springboot结构@PostMapping(value = "/article")
上⾯代码中两种写法起到的是⼀样的效果,也就是PostMapping等同于@RequestMapping的method等于POST。同理:
@GetMapping、@PutMapping、@DeleteMapping也都是简写的⽅式。
1.3. @RestController与@Controller
@Controller注解是开发中最常使⽤的注解,它的作⽤有两层含义:
⼀是告诉Spring,被该注解标注的类是⼀个Spring的Bean,需要被注⼊到Spring的上下⽂环境中。
⼆是该类⾥⾯所有被RequestMapping标注的注解都是HTTP服务端点。
@RestController相当于 @Controller和@ResponseBody结合。它有两层含义:
⼀是作为Controller的作⽤,将控制器类注⼊到Spring上下⽂环境,该类RequestMapping标注⽅法为HTTP服务端点。
⼆是作为ResponseBody的作⽤,请求响应默认使⽤的序列化⽅式是JSON,⽽不是跳转到jsp或模板页⾯。
1.4. @PathVariable 与@RequestParam
PathVariable⽤于URI上的{参数},如下⽅法⽤于删除⼀篇⽂章,其中id为⽂章id。如:我们的请求URL为“/article/1”,那么将匹配DeleteMapping并且PathVariable接收参数id=1。⽽RequestParam⽤于接收普通表单⽅式或者ajax模拟表单提交的参数数据。
@DeleteMapping("/article/{id}")
public @ResponseBody AjaxResponse deleteArticle(@PathVariable Long id) {
@PostMapping("/article")
public @ResponseBody AjaxResponse deleteArticle(@RequestParam Long id) {
⼆、接收复杂嵌套对象参数
有⼀些朋友可能还⽆法理解RequestBody注解存在的真正意义,表单数据提交⽤RequestParam就好了,为什么还要搞出来⼀个RequestBody注解呢?RequestBody注解的真正意义在于能够使⽤对象或者嵌套对象接收前端数据。
仔细看上⾯的代码,是⼀个paramData对象⾥⾯包含了⼀个bestFriend对象。这种数据结构使⽤RequestParam就⽆法接收
了,RequestParam只能接收平⾯的、⼀对⼀的参数。像上⽂中这种数据结构的参数,就需要我们在java服务端定义两个类,⼀个类是ParamData,⼀个类是BestFriend.
public class ParamData {
private String name;
private int id;
private String phone;
private BestFriend bestFriend;
public static class BestFriend {
private String address;
private String sex;
}
}
注意上⾯代码中省略了GET、SET⽅法等必要的java plain model元素。
注意成员变量名称⼀定要和JSON属性名称对应上。
注意接收不同类型的参数,使⽤不同的成员变量类型
完成以上动作,我们就可以使⽤@RequestBody ParamData paramData,⼀次性的接收以上所有的复杂嵌套对象参数了,参数对象的所有属性都将被赋值。
三、Http数据转换的原理
⼤家现在使⽤JSON都⽐较普遍了,其⽅便易⽤、表达能⼒强,是绝⼤部分数据接⼝式应⽤的⾸选。那么如何响应其他的类型的数据?其中的判别原理⼜是什么?下⾯就来给⼤家介绍⼀下:
当⼀个HTTP请求到达时是⼀个InputStream,通过HttpMessageConverter转换为java对象,从⽽进⾏参数接收。
当对⼀个HTTP请求进⾏响应时,我们⾸先输出的是⼀个java对象,然后由HttpMessageConverter转换为OutputStream输出。
当我们在Spring Boot应⽤中集成了jackson的类库之后,如下的⼀些HttpMessageConverter将会被加载。
实现类
功能说明
StringHttpMessageConverter
将请求信息转为字符串
FormHttpMessageConverter
将表单数据读取到MultiValueMap中
XmlAwareFormHttpMessageConverter
扩展与FormHttpMessageConverter,如果部分表单属性是XML数据,可⽤该转换器进⾏读取
ResourceHttpMessageConverter
读写io.Resource对象
BufferedImageHttpMessageConverter
读写BufferedImage对象
ByteArrayHttpMessageConverter
读写⼆进制数据
SourceHttpMessageConverter
读写ansform.Source类型的对象
MarshallingHttpMessageConverter
通过Spring的org.springframework,xml.Marshaller和Unmarshaller读写XML消息
Jaxb2RootElementHttpMessageConverter
通过JAXB2读写XML消息,将请求消息转换为标注的XmlRootElement和XmlType连接的类中
MappingJacksonHttpMessageConverter
利⽤Jackson开源包的ObjectMapper读写JSON数据
RssChannelHttpMessageConverter
读写RSS种⼦消息
AtomFeedHttpMessageConverter
和RssChannelHttpMessageConverter能够读写RSS种⼦消息
根据HTTP协议的Accept和Content-Type属性,以及参数数据类型来判别使⽤哪⼀种HttpMessageConverter。当使⽤RequestBody或ResponseBody时,再结合前端发送的Accept数据类型,会⾃动判定优先使⽤MappingJacksonHttpMessageConverter作为数据转换器。但是,不仅JSON可以表达对象数据类型,XML也可以。如果我们希望使⽤XML格式该怎么告知Spring呢,那就要使⽤到produces属性了。
@GetMapping(value ="/demo",produces = MediaType.APPLICATION_XML_VALUE)
这⾥我们明确的告知了返回的数据类型是xml,就会使⽤Jaxb2RootElementHttpMessageConverter作为默认的数据转换器。当然实现XML数据响应⽐JSON还会更复杂⼀些,还需要结合@XmlRootElement、@XmlElement等注解实体类来使⽤。同理consumes属性你是不是也会⽤了呢。
四、⾃定义HttpMessageConverter
其实绝⼤多数的数据格式都不需要我们⾃定义HttpMessageConverter,都有第三⽅类库可以帮助我们实现(包括下⽂代码中的Excel格式)。但有的时候,有些数据的输出格式并没有类似于Jackson这种类库帮助我们处理,需要我们⾃定义数据格式。该怎么做?下⾯代码只是帮助我们理解的⼀个例⼦,不要⽤于⽣产:
@Service
public class TeamToXlsConverter extends AbstractHttpMessageConverter {
private static final MediaType EXCEL_TYPE = MediaType.valueOf("application/vnd.ms-excel");
TeamToXlsConverter() {
super(EXCEL_TYPE);
}
@Override
protected Team readInternal(final Class extends Team> clazz, final HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
protected boolean supports(final Class> clazz) {
return (Team.class == clazz);
}
@Override
protected void writeInternal(final Team team, final HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
try (final Workbook workbook = new HSSFWorkbook()) {
final Sheet sheet = ateSheet();
int rowNo = 0;
for (final TeamMember member : Members()) {
final Row row = ateRow(rowNo++);
.Name());
}
workbook.Body());
}
}
}
实现AbstractHttpMessageConverter接⼝
指定该转换器是针对哪种数据格式的?如上⽂代码中的"application/vnd.ms-excel"
指定该转换器针对那些对象数据类型?如上⽂代码中的supports函数
使⽤writeInternal对数据进⾏输出处理,上例中是输出为Excel格式。
期待您的关注
本⽂转载注明出处(必须带连接,不能只转⽂字):字母哥博客。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论