经典的高端网站建设公司着陆页设计,做一个这样的网站应该报价多少,泰安企业网站制作,西安做网站多钱目录 SpringBootWeb请求响应2. 响应2.1 ResponseBody2.2 统一响应结果2.3 案例2.3.1 需求说明2.3.2 准备工作2.3.3 实现步骤2.3.4 代码实现2.3.5 测试2.3.6 问题分析 SpringBootWeb请求响应
2. 响应
前面我们学习过HTTL协议的交互方式#xff1a;请求响应模式#xff08;有… 目录 SpringBootWeb请求响应2. 响应2.1 ResponseBody2.2 统一响应结果2.3 案例2.3.1 需求说明2.3.2 准备工作2.3.3 实现步骤2.3.4 代码实现2.3.5 测试2.3.6 问题分析 SpringBootWeb请求响应
2. 响应
前面我们学习过HTTL协议的交互方式请求响应模式有请求就有响应
那么Controller程序呢除了接收请求外还可以进行响应。
2.1 ResponseBody
在我们前面所编写的controller方法中都已经设置了响应数据。 controller方法中的return的结果怎么就可以响应给浏览器呢
答案使用ResponseBody注解
ResponseBody注解
类型方法注解、类注解位置书写在Controller方法上或类上作用将方法返回值直接响应给浏览器 如果返回值类型是实体对象/集合将会转换为JSON格式后在响应给浏览器
但是在我们所书写的Controller中只在类上添加了RestController注解、方法添加了RequestMapping注解并没有使用ResponseBody注解怎么给浏览器响应呢
RestController
public class HelloController {RequestMapping(/hello)public String hello(){System.out.println(Hello World ~);return Hello World ~;}
}原因在类上添加的RestController注解是一个组合注解。
RestController Controller ResponseBody
RestController源码
Target({ElementType.TYPE}) //元注解修饰注解的注解
Retention(RetentionPolicy.RUNTIME) //元注解
Documented //元注解
Controller
ResponseBody
public interface RestController {AliasFor(annotation Controller.class)String value() default ;
}结论在类上添加RestController就相当于添加了ResponseBody注解。
类上有RestController注解或ResponseBody注解时表示当前类下所有的方法返回值做为响应数据 方法的返回值如果是一个POJO对象或集合时会先转换为JSON格式在响应给浏览器
下面我们来测试下响应数据
RestController
public class ResponseController {//响应字符串RequestMapping(/hello)public String hello(){System.out.println(Hello World ~);return Hello World ~;}//响应实体对象RequestMapping(/getAddr)public Address getAddr(){Address addr new Address();//创建实体类对象addr.setProvince(广东);addr.setCity(深圳);return addr;}//响应集合数据RequestMapping(/listAddr)public ListAddress listAddr(){ListAddress list new ArrayList();//集合对象Address addr new Address();addr.setProvince(广东);addr.setCity(深圳);Address addr2 new Address();addr2.setProvince(陕西);addr2.setCity(西安);list.add(addr);list.add(addr2);return list;}
}在服务端响应了一个对象或者集合那私前端获取到的数据是什么样子的呢我们使用postman发送请求来测试下。测试效果如下 2.2 统一响应结果
大家有没有发现一个问题我们在前面所编写的这些Controller方法中返回值各种各样没有任何的规范。 如果我们开发一个大型项目项目中controller方法将成千上万使用上述方式将造成整个项目难以维护。那在真实的项目开发中是什么样子的呢
在真实的项目开发中无论是哪种方法我们都会定义一个统一的返回结果。方案如下 前端只需要按照统一格式的返回结果进行解析(仅一种解析方案)就可以拿到数据。 统一的返回结果使用类来描述在这个结果中包含 响应状态码当前请求是成功还是失败 状态码信息给页面的提示信息 返回的数据给前端响应的数据字符串、对象、集合
定义在一个实体类Result来包含以上信息。代码如下
public class Result {private Integer code;//响应码1 代表成功; 0 代表失败private String msg; //响应码 描述字符串private Object data; //返回的数据public Result() { }public Result(Integer code, String msg, Object data) {this.code code;this.msg msg;this.data data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;}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;}//增删改 成功响应(不需要给前端返回数据)public static Result success(){return new Result(1,success,null);}//查询 成功响应(把查询结果做为返回数据响应给前端)public static Result success(Object data){return new Result(1,success,data);}//失败响应public static Result error(String msg){return new Result(0,msg,null);}
}改造Controller
RestController
public class ResponseController { //响应统一格式的结果RequestMapping(/hello)public Result hello(){System.out.println(Hello World ~);//return new Result(1,success,Hello World ~);return Result.success(Hello World ~);}//响应统一格式的结果RequestMapping(/getAddr)public Result getAddr(){Address addr new Address();addr.setProvince(广东);addr.setCity(深圳);return Result.success(addr);}//响应统一格式的结果RequestMapping(/listAddr)public Result listAddr(){ListAddress list new ArrayList();Address addr new Address();addr.setProvince(广东);addr.setCity(深圳);Address addr2 new Address();addr2.setProvince(陕西);addr2.setCity(西安);list.add(addr);list.add(addr2);return Result.success(list);}
}使用Postman测试 2.3 案例
下面我们通过一个案例来加强对请求响应的学习。
2.3.1 需求说明
需求加载并解析xml文件中的数据完成数据处理并在页面展示 获取员工数据返回统一响应结果在页面渲染展示
2.3.2 准备工作
案例准备 XML文件 已经准备好(emp.xml)直接导入进来放在 src/main/resources目录下 工具类 已经准备好解析XML文件的工具类无需自己实现直接在创建一个包 com.itheima.utils 然后将工具类拷贝进来 前端页面资源 已经准备好直接拷贝进来放在src/main/resources下的static目录下
Springboot项目的静态资源(htmlcssjs等前端资源)默认存放目录为classpath:/static 、 classpath:/public、 classpath:/resources 在SpringBoot项目中静态资源默认可以存放的目录 classpath:/static/classpath:/public/classpath:/resources/classpath:/META-INF/resources/ classpath 代表的是类路径在maven的项目中其实指的就是 src/main/resources 或者 src/main/java但是java目录是存放java代码的所以相关的配置文件及静态资源文档就放在 src/main/resources下。 2.3.3 实现步骤 在pom.xml文件中引入dom4j的依赖用于解析XML文件 dependencygroupIdorg.dom4j/groupIdartifactIddom4j/artifactIdversion2.1.3/version
/dependency引入资料中提供的解析XML的工具类XMLParserUtils、实体类Emp、XML文件emp.xml 引入资料中提供的静态页面文件放在resources下的static目录下 创建EmpController类编写Controller程序处理请求响应数据
2.3.4 代码实现
Contriller代码
RestController
public class EmpController {RequestMapping(/listEmp)public Result list(){//1. 加载并解析emp.xmlString file this.getClass().getClassLoader().getResource(emp.xml).getFile();//System.out.println(file);ListEmp empList XmlParserUtils.parse(file, Emp.class);//2. 对数据进行转换处理 - gender, jobempList.stream().forEach(emp - {//处理 gender 1: 男, 2: 女String gender emp.getGender();if(1.equals(gender)){emp.setGender(男);}else if(2.equals(gender)){emp.setGender(女);}//处理job - 1: 讲师, 2: 班主任 , 3: 就业指导String job emp.getJob();if(1.equals(job)){emp.setJob(讲师);}else if(2.equals(job)){emp.setJob(班主任);}else if(3.equals(job)){emp.setJob(就业指导);}});//3. 响应数据return Result.success(empList);}
}统一返回结果实体类
public class Result {private Integer code ;//1 成功 , 0 失败private String msg; //提示信息private Object data; //数据 datepublic Result() {}public Result(Integer code, String msg, Object data) {this.code code;this.msg msg;this.data data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;}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;}public static Result success(Object data){return new Result(1, success, data);}public static Result success(){return new Result(1, success, null);}public static Result error(String msg){return new Result(0, msg, null);}
}2.3.5 测试
代码编写完毕之后我们就可以运行引导类启动服务进行测试了。
使用Postman测试 打开浏览器在浏览器地址栏输入 http://localhost:8080/emp.html 2.3.6 问题分析
上述案例的功能我们虽然已经实现但是呢我们会发现案例中解析XML数据获取数据的代码处理数据的逻辑的代码给页面响应的代码全部都堆积在一起了全部都写在controller方法中了。 当前程序的这个业务逻辑还是比较简单的如果业务逻辑再稍微复杂一点我们会看到Controller方法的代码量就很大了。 当我们要修改操作数据部分的代码需要改动Controller 当我们要完善逻辑处理部分的代码需要改动Controller 当我们需要修改数据响应的代码还是需要改动Controller
这样呢就会造成我们整个工程代码的复用性比较差而且代码难以维护。 那如何解决这个问题呢其实在现在的开发中有非常成熟的解决思路那就是分层开发。