前面介绍了Spring Boot的优点,然后介绍了如何快速创建Spring Boot 项目。不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html

今天来说一说Spring的@Controller和@RestController控制器, 他们是如何响应客户端请求,如何返回json数据。

这个系列课程的完整源码,也会提供给大家。大家关注我的微信公众号(架构师精进),回复:springboot源码 获取这个系列课程的完整源码。或者点此链接直接下载完整源码

一、@Controller和@RestController 两种控制器

Spring中有Controller,RestController的两种控制器,都是用来表示Spring某个类的是否可以接收HTTP请求。

但是不同的是:

1、Controller:标识一个Spring类是Spring MVC controller处理器。

2、RestController:  主要用于Restfull接口,返回客户端数据请求。

所以RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。

二、@Controller的用法

1、创建pojo 包,并创建User 对象

package com.weiz.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import java.util.Date; public class User {
private String name; @JsonIgnore
private String password; private Integer age; @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh",timezone = "GMT+8")
private Date birthday; @JsonInclude(JsonInclude.Include.NON_NULL)
private String desc; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public String getDesc() {
return desc;
} public void setDesc(String desc) {
this.desc = desc;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}

2、创建UserController 控制器

package com.weiz.controller;

import com.weiz.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import java.util.Date; @Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/getUser")
@ResponseBody
public User getUser(){
User u = new User();
u.setName("weiz");
u.setAge(18);
u.setBirthday(new Date());
u.setPassword("weiz"); return u;
}
}

3、运行查看数据返回,在浏览器中输入:http://localhost:8080/user/getUser,返回数据可以看到控制器自动将user对象转换为json数据格式。

三、@RestController的用法

其实 RestController是Controller和ResponseBody的结合体,两个标注合并起来的作用。

所以,将上面的UserController 修改如下即可:

package com.weiz.controller;

import com.weiz.pojo.JSONResult;
import com.weiz.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.Date; //@Controller
@RestController // RestController = Controller + ResponseBody
@RequestMapping("/user")
public class UserController {
@RequestMapping("/getUser")
//@ResponseBody
public JSONResult getUser(){
User u = new User();
u.setName("weiz222");
u.setAge(20);
u.setBirthday(new Date());
u.setPassword("weiz222"); return u;
}
}

四、统一返回

其实 RestController 给客户端返回数据时,一般会用jackson序列化返回。而不是直接返回整个pojo类对象。下面就简单介绍下如何统一返回json数据格式:

1、pojo类相关增加序列化格式配置,如上面的User对象的定义

2、增加Json通用的封装类JsonUtils ,下面这个就是比较常用的json数据封装类。

package com.weiz.utils;

import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; /**
*
* @Title: JSONResult.java
* @Package com.weiz.utils
* @Description: 自定义响应数据结构
* 这个类是提供给门户,ios,安卓,微信商城用的
* 门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)
* 其他自行处理
* 200:表示成功
* 500:表示错误,错误信息在msg字段中
* 501:bean验证错误,不管多少个错误都以map形式返回
* 502:拦截器拦截到用户token出错
* 555:异常抛出信息
* Copyright: Copyright (c) 2016
*
* @author weiz
* @date 2016年4月22日 下午8:33:36
* @version V1.0
*/
public class JSONResult { // 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper(); // 响应业务状态
private Integer status; // 响应消息
private String msg; // 响应中的数据
private Object data; private String ok; // 不使用 public static JSONResult build(Integer status, String msg, Object data) {
return new JSONResult(status, msg, data);
} public static JSONResult ok(Object data) {
return new JSONResult(data);
} public static JSONResult ok() {
return new JSONResult(null);
} public static JSONResult errorMsg(String msg) {
return new JSONResult(500, msg, null);
} public static JSONResult errorMap(Object data) {
return new JSONResult(501, "error", data);
} public static JSONResult errorTokenMsg(String msg) {
return new JSONResult(502, msg, null);
} public static JSONResult errorException(String msg) {
return new JSONResult(555, msg, null);
} public JSONResult() { } public JSONResult(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
} public JSONResult(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
} public Boolean isOK() {
return this.status == 200;
} public Integer getStatus() {
return status;
} public void setStatus(Integer status) {
this.status = status;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} public Object getData() {
return data;
} public void setData(Object data) {
this.data = data;
} /**
*
* @Description: 将json结果集转化为LeeJSONResult对象
* 需要转换的对象是一个类
* @param jsonData
* @param clazz
* @return
*
* @author weiz
* @date 2016年4月22日 下午8:34:58
*/
public static JSONResult formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, JSONResult.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
} /**
*
* @Description: 没有object对象的转化
* @param json
* @return
*
* @author weiz
* @date 2016年4月22日 下午8:35:21
*/
public static JSONResult format(String json) {
try {
return MAPPER.readValue(json, JSONResult.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
*
* @Description: Object是集合转化
* 需要转换的对象是一个list
* @param jsonData
* @param clazz
* @return
*
* @author weiz
* @date 2016年4月22日 下午8:35:31
*/
public static JSONResult formatToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
} public String getOk() {
return ok;
} public void setOk(String ok) {
this.ok = ok;
} }

3、如何调用

最后

以上,就把Spring Boot中的Controller及如何返回json数据介绍完了。

这个系列课程的完整源码,也会提供给大家。大家关注我的微信公众号(架构师精进),回复:springboot源码 获取这个系列课程的完整源码。

SpringBoot入门系列(二)如何返回统一的数据格式的更多相关文章

  1. SpringBoot入门系列(十一)统一异常处理的实现

    前面介绍了Spring Boot 如何整合定时任务已经Spring Boot 如何创建异步任务和定时任务.不清楚的朋友可以看看之前的文章:<Spring Boot 入门系列文章> 接下来主 ...

  2. SpringBoot入门系列(十二)统一日志收集

    前面介绍了Spring Boot 异常处理,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html. 今 ...

  3. mybatis入门系列二之输入与输出参数

    mybatis入门系列二之详解输入与输出参数   基础知识   mybatis规定mapp.xml中每一个SQL语句形式上只能有一个@parameterType和一个@resultType 1. 返回 ...

  4. C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  5. [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...

  6. Maven入门系列(二)--设置中央仓库的方法

    原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布 ...

  7. SpringBoot入门教程(二)CentOS部署SpringBoot项目从0到1

    在之前的博文<详解intellij idea搭建SpringBoot>介绍了idea搭建SpringBoot的详细过程, 并在<CentOS安装Tomcat>中介绍了Tomca ...

  8. C语言高速入门系列(二)

    C语言高速入门系列(二) -----转载请注明出处coder-pig 本节引言: 在前面一节中我们对C语言进行了初步的了解,学会了使用IDE进行代码的编写,编译执行! 在这一节中我们会对C语言的基本的 ...

  9. SpringBoot入门(二)——起步依赖

    本文来自网易云社区 在前一篇我们通过简单几步操作就生成了一个可以直接运行的Web程序,这是因为SpringBoot代替我们做了许多工作,概括来讲可以分为起步依赖和自动配置.这一篇先来看看起步依赖. 项 ...

  10. SpringBoot入门系列(转)

    SpringBoot入门系列:第一篇 Hello World http://blog.csdn.net/lxhjh/article/details/51711148

随机推荐

  1. [SDOI2015]道路修建(线段树)

    题意:给定2行n列的四连通带权网格图,支持修改边权和查询第[l,r]列的最小生成树 题解:这是一道好题,要么SDOI2019中n=2的20pts怎么会“我抄我自己”?(当然NOIP2018“我抄我自己 ...

  2. 【lca+输入】Attack on Alpha-Zet

    Attack on Alpha-Zet 题目描述 Space pirate Captain Krys has recently acquired a map of the artificial and ...

  3. 【shell】概述

    功能简介 批量自动初始化系统(update,软件安装,时区设置,安全策略...) 批量自动部署软件(LAMP,LNMP,Nginx,LVS,Tomcat) 管理应用程序(KVM,集群管理扩容,MySQ ...

  4. VScode中Python的交互式命令环境使用笔记

    前言 时间比较久了,忘记了具体配置了,不讲搭建了,提供参https://www.zhihu.com/question/49799276,或自行谷歌,常用的插件Python和Code Runner. 本 ...

  5. CCS|ANSI|中华人民共和国标准化法|国标|ISO|IEC|Ieeexplore|

    国家的标准的有效期,标龄是5年.强制性标准是是指为保障人体的健康.人身.财产安全的标准和法律.行政法规定强制执行的标准,如药品标准.食品卫生标准. CCS:分类法简写图 国际标准,比如美国国家标准AN ...

  6. java高并发之线程池

    Java高并发之线程池详解   线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对 ...

  7. Elasticsearch Rest模式和RPC模式性能比较

    Elasticsearch 有两种链接模式,即Rest方式(对应端口9200)和RPC方式(对应端口9300)这两种访问效率到底差多少,在同样的业务逻辑下,测试了一波. 用的JMeter进行压力测试 ...

  8. Weave实现跨主机容器互联

    安装与启动 直接从github下载二进制文件安装. docker_host1(服务器1): 下载weave # sudo wget -O /usr/local/bin/weave https://ra ...

  9. curl操作和file_get_contents() 比较

    1 . curl需要php开启php_curl开启扩展 $ch = curl_init(); $timeout = 5; curl_setopt ($ch, CURLOPT_URL, 'http:// ...

  10. Adam项目展示微软研究院人工智能领域新突破

    编者按:在美国时间7月14日举行的2014年微软教育峰会上,Adam项目面对牵上台的3只小狗,一一准确地报出了它们的品种.Adam项目代表了微软研究院在机器学习和人工智能领域的前沿进展.它可不仅仅认得 ...