响应数据
@ResponseBody
类型:方法注解、类注解
位置: Controller方法上/类上
作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合,将会转换为JSON格式响应
说明: @RestController = @Controller + @ResponseBody ;
package com.example.springboot01.controller;
import com.example.springboot01.pojo.Address;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author hyk~
*/
@RestController
public class ResponseController {
@RequestMapping("/hello")
public String hello(){
System.out.println("Hello");
return "hello";
}
@RequestMapping("/getAddr")
public Address getAddr(){
Address addr = new Address();
addr.setCity("长沙");
addr.setProvince("湖南");
return addr;
}
@RequestMapping("/listAddr")
public List<Address> listAddr(){
List<Address> list = new ArrayList<>();
Address addr1 = new Address();
addr1.setProvince("湖北");
addr1.setCity("武汉");
Address addr2 = new Address();
addr2.setCity("南京");
addr2.setProvince("江苏");
list.add(addr1);
list.add(addr2);
return list;
}
}
不易管理 难以维护
修改代码
编写 Result
类
Result
类是一个响应结果的封装类,用于统一封装接口的返回结果。它有以下几个属性:
code
: 用于表示操作的结果,1
表示成功,0
表示失败。msg
: 提示信息,如操作成功或失败的原因。data
: 实际返回的数据,可以是任何类型的对象(Object
)。
此外,Result
类提供了多个构造方法、getter和setter方法,以及一些静态方法,用于快速生成Result
对象:
Result.success(Object data)
: 返回成功的Result
对象,并携带数据。Result.success()
: 返回成功的Result
对象,但不携带数据。Result.error(String msg)
: 返回失败的Result
对象,并携带失败信息。
package com.example.springboot01.pojo;
/**
* 统一响应结果封装类
*/
public class Result {
private Integer code;//1 成功 , 0 失败
private String msg; //提示信息
private Object data; //数据 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(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);
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
ResponseController
类
package com.example.springboot01.controller;
import com.example.springboot01.pojo.Address;
import com.example.springboot01.pojo.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author hyk~
*/
@RestController
public class ResponseController {
@RequestMapping("/hello")
public Result hello(){
System.out.println("Hello");
//return new Result(1,"success","Hello");
return Result.success("Hello");
}
@RequestMapping("/getAddr")
public Result getAddr(){
Address addr = new Address();
addr.setCity("长沙");
addr.setProvince("湖南");
return Result.success(addr);
}
@RequestMapping("/listAddr")
public Result listAddr(){
List<Address> list = new ArrayList<>();
Address addr1 = new Address();
addr1.setProvince("湖北");
addr1.setCity("武汉");
Address addr2 = new Address();
addr2.setCity("南京");
addr2.setProvince("江苏");
list.add(addr1);
list.add(addr2);
return Result.success(list);
}
}
类之间的关联
- 使用关系:
ResponseController
中的方法通过调用Result.success()
静态方法,生成Result
对象。这些Result
对象封装了控制器的返回结果,统一了接口的响应格式。
作用总结
-
Result
类的作用:- 提供了一个统一的响应格式,使得所有接口的返回值结构一致,便于前端解析和处理。
- 可以通过
code
来判断操作是否成功,通过msg
提示信息,通过data
传递实际的数据。
-
ResponseController
类的作用:- 处理HTTP请求,生成相应的数据或信息,并通过
Result
类封装成统一格式的响应返回给客户端。
- 处理HTTP请求,生成相应的数据或信息,并通过
1. @ResponseBody
位置: Controller类上/方法上
作用: 将方法返回值直接响应,若返回值类型是 实体对象/集合 ,转SON格式响应
2.统一响应结果
Result (code、msg、data )
案例
获取员工数据,返回统一响应结果,在页面渲染展示
加载并解析emp.xml文件中的数据,完成数据处理,并在页面展示。
在pom.xml文件中引入dom4j的依赖,用于解析XML文件
引入资料中提供的解析XML的工具类XMLParserUtils、对应的实体类Emp,XML文件emp.xml
引入资料中提供的静态页面文件,放在resources下的static目录下
编写Controller程序,处理请求,响应数据
package com.example.springboot01.controller;
import com.example.springboot01.pojo.Emp;
import com.example.springboot01.pojo.Result;
import com.example.springboot01.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author hyk~
*/
@RestController
public class EmpController {
@RequestMapping("/listEmp")
public Result list(){
//1.加载并解析emp.xml文件
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
//2.对数据进行转换处理 -gender job
empList.stream().forEach(emp -> {
//处理gender
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);
}
}
复用性差 难以维护
三层架构
controller: 控制层,接收前端发送的请求,对请求进行处理,并响应数据
service: 业务逻辑层,处理具体的业务逻辑。
dao: 数据访问层(Data Access bject)(持久层),负责数据访问操作,包括数据的增、删、改、查
1.创建对应的包
2.编写dao数据访问层代码 数据访问操作
Empdao接口
public interface EmpDao {
//获取员工列表数据
public List<Emp> listEmp();
}
实现类
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> listEmp() {
//1.加载并解析emp.xml文件
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
return empList;
}
}
2.service业务逻辑层 业务逻辑处理
public interface EmpService {
// 获取员工列表
public List<Emp> listEmp();
}
public class EmpServiceA implements EmpService {
private EmpDao empDao = new EmpDaoA();
@Override
public List<Emp> listEmp() {
//1.调用dao 获取数据
List<Emp> empList = empDao.listEmp();
//2.对数据进行转换处理 -gender job
empList.stream().forEach(emp -> {
//处理gender
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("就业指导");
}
});
return empList;
}
}
3.controller控制层 接收请求 响应数据
@RestController
public class EmpController {
private EmpService empService = new EmpServiceA();
@RequestMapping("/listEmp")
public Result list(){
//调用Service,获取数据
List<Emp> empList = empService.listEmp();
//响应数据
return Result.success(empList);
}
}
易于管理,维护 复用性强
分层解耦
内聚:软件中各个功能模块内部的功能联系
耦合:衡量软件中各个层/模块之间的依赖、关联的程度
软件设计原则:高内聚低耦合。
控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转
依赖注入:Dependency lnjection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为bean。
IOC& DI入门
1.Service层及 Dao层的实现类,交给IOC容器管理
2.为Controller及Service注入运行时,依赖的对象
3.运行测试
示例代码
EmpServiceA类
package com.example.springboot01.service.impl;
import com.example.springboot01.dao.EmpDao;
import com.example.springboot01.dao.impl.EmpDaoA;
import com.example.springboot01.pojo.Emp;
import com.example.springboot01.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author hyk~
*/
@Component //将当前类交给IOC容器管理 成为IOC容器中的bean
public class EmpServiceA implements EmpService {
// private EmpDao empDao = new EmpDaoA();
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 —— 依赖注入
private EmpDao empDao;
@Override
public List<Emp> listEmp() {
//1.调用dao 获取数据
List<Emp> empList = empDao.listEmp();
//2.对数据进行转换处理 -gender job
empList.stream().forEach(emp -> {
//处理gender
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("就业指导");
}
});
return empList;
}
}
EmpDaoA类
package com.example.springboot01.dao.impl;
import com.example.springboot01.dao.EmpDao;
import com.example.springboot01.pojo.Emp;
import com.example.springboot01.utils.XmlParserUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author hyk~
*/
@Component //将当前类交给IOC容器管理 成为IOC容器中的bean
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> listEmp() {
//1.加载并解析emp.xml文件
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
return empList;
}
}
EmpController类
package com.example.springboot01.controller;
import com.example.springboot01.pojo.Emp;
import com.example.springboot01.pojo.Result;
import com.example.springboot01.service.EmpService;
import com.example.springboot01.service.impl.EmpServiceA;
import com.example.springboot01.utils.XmlParserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author hyk~
*/
@RestController
public class EmpController {
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 —— 依赖注入
private EmpService empService;
// private EmpService empService = new EmpServiceA();
@RequestMapping("/listEmp")
public Result list(){
//调用Service,获取数据
List<Emp> empList = empService.listEmp();
//响应数据
return Result.success(empList);
}
}
IOC容器详解
Bean的声明
要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一
bean的名字默认为类名的首字母小写
可以通过 value 修改
注意事项
声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写
使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能
用@Controller
Bean组件扫描
1.前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描
2.@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解
@SpringBootApplicatiol中,默认扫描的范围是启动类所在包及其子包。
声明bean的注解
@Component,@Controller, @Service,@Repository
@SpringBootApplication具有包扫描作用,默认扫描当前包及其子包
DI详解
Bean注入
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误
通过以下几种方案来解决:
@Primary
通过@Primary设置EmpServiceB类为优先类
@Qualifier
在@Autowired上通过@Qualifier来指定bean
@Resource
@Resource(name = "empServiceB")
private EmpService empService;
依赖注入的注解
默认按照类型自动装配,@Autowired
如果同类型的bean存在多个
@Primary
@Autowired +@Qualifier("bean的名称”)
@Resource(name="bean的名称”)
@Resource 与 @Autowired区别
@Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解
@Autowired 默认是按照类型注入,而@Resource默认是按照名称注入