请求响应 + 分层解耦

枚举类和反射:

使用枚举实现单例模式,防止反射攻击私有构造器

public enum EnumSingleton{
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}

public static void main(String[] args) {
    //通过反射获取枚举类
    //1、获取枚举类的类型
    Class<EnumSingleton> calzz =EnumSingleton.class;

    Constructor<EnumSingleton> constructor = calzz.getDeclaredConstructor(String.class,int.class);

    //爆破
    Constructor.setAccessible(true);
    EnumSingleton enumSingleton = constructor.newInstance();
    System.out.print("enumSingleton" + enumSingleton);//会报异常
}

请求响应

数组参数:

请求参数名与形参数组名称相同请求参数为多个,定义数组类型形参即可接收参数

@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
    System.out.print(Array.toString(hobby));
    return "OK";
}
集合参数:

请求参数名与形参集合名称相同请求参数为多个,@RequestParam绑定参数关系

@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
    System.out.print(hobby);
    return "OK"; 
}
日期参数:

使用@DateTimeFormat 注解完成日期参数格式转换

@RequestMapping("/dateParam")
public String dataParam(@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")LocalDateTime updateTime)
return "OK";
Json参数:

JSON数据键名与形参对象属性名相同,定义PIJO类型形参即可接收参数,需要使用@RequestBody标识

public class User{
    private String name;
    private Integer age;
    private Address address;
}
public class Address{
    private String province;
    private String city;
}

@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
    System.out.print(user);
    return "OK";
}
路径参数:

通过请求URL直接传递参数,使用{…}来表示该路径参数,需要使用@PathVariable获取路径参数

@RequestMapping("/Path/{id}")
public String pathParam(@PathVariable Integer id){
    System.out.print(id);
    return "OK";
}

//多个路径参数
@RequestMapping("/Path/{id}/{name}")
public String pathParam(@PathVariable Integer id,@PathVariable String name){
    System.out.print(id + ":" + name);
    return "OK";
}

请求响应总结:

  1. 简单参数

​ 定义方法形参,请求参数名与形参变量名一致

​ 如果不一致,通过@RequestParam手动映射

  1. 实体参数

​ 请求参数名与实体对象的属性名一致,就会自动接收封装

  1. 数组集合参数

​ 数组:请求参数名与数组名一致,直接封装

​ 集合:请求参数名与集合名一致,@RequestParam绑定参数关系

  1. 日期参数

​ @DateTimeFormat

  1. JSON参数

​ @RequestBody

  1. 路径参数

​ @PathVariable

@ResponseBody:
  • 类型:方法注释、类注释
  • 位置:Controller方法上/类上
  • 作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合,将会转换为JSON格式响应
  • 说明@RestController=@Controller+@ResponseBody
Result:

统一响应结果

public class Result{
    //响应码,1代表成功;0代表失败
    private Integer code;
    //提示信息
    private String msg;
    //返回数据
    private Object data;
    //……
}
响应的数据:
    {
        "code":1,
        "msg":"操作成功"
        "data":…
    }
例:

​ 获取员工数据,返回统一响应结果,在页面渲染展示

​ 加载并解析emp.xml文件中的数据,完成数据处理,并在页面展示

注意:Springboot项目的静态资源(html,css,js等前端资源)默认存放目录为:

​ classpath:/static、classpath:/public、classpath:/resources

emp.xml

<emps>
    <emp>
        <name>金毛狮王</name>
        <age>55</age>
        <image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/1.jpg</image>
        <!-- 1: 男, 2: 女 -->
        <gender>1</gender>
        <!-- 1: 讲师, 2: 班主任 , 3: 就业指导 -->
        <job>1</job>
    </emp>

    <emp>
        <name>白眉鹰王</name>
        <age>65</age>
        <image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/2.jpg</image>
        <gender>1</gender>
        <job>1</job>
    </emp>      
</emps>
步骤:
  1. 在 pom.xml 文件中引入dom4j的依赖,用于解析XML文件
        <dependency>
            <groupID>org.dom4j</groupID>
            <artifactID>dom4j</artifactID>
            <version>2.1.3</version>
        </dependency>
    
  2. 引入资料中提供的解析XML的工具类 XMLParserUtils、对应的实体类Emp、XML文件emp.XML

  3. 引入静态页面文件,放在resource下的static目录下

  4. 编写Controller程序,处理请求,响应数据

    @RestController
    public class EmpController {

    @RequestMapping("/listEmp")
    public Result list(){
        //1、加载并解析emp.xml
    
        //String file = "D:\\Code-Project\\project_practice\\springBoot02\\src\\main\\resources";
        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 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);
    }
    

    }

分层解耦:

三层架构:Controller(接受请求,响应数据)、Service(逻辑处理)、Dao(数据访问)
  • Controller:控制层,接受前端发送的请求,对请求进行处理,并响应数据
  • Service:业务逻辑层,处理具体的业务逻辑
  • Dao:数据访问层(Data Access Object)持久层,负责数据访问操作,包括数据的增、删、改、查
controller:

com.itheima.controller.EmpController

@RestController
public class EmpController {
    private EmpService empService = new EmpServiceA();

    @RequestMapping("/listEmp")
    public Result list(){

        //调用service,获取数据
        List<Emp> empList = empService.listEmp();

        //3、响应数据
        return Result.success(empList);
    }
}
service:

com.itheima.service.EmpService:

public interface EmpService {
    //获取员工列表
    public List<Emp> listEmp();
}

com.itheima.service.impl.EmpServiceA:

public class EmpServiceA implements EmpService {
    private EmpDao empDao = new EmpDaoA();
    @Override
    public List<Emp> listEmp() {
        //调用Dao,获取数据
        List<Emp> empList = empDao.listEmp();

        //2、对数据进行转换处理 - gender,job

        //遍历
        empList.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("就业指导");
            }
        });
        return empList;
    }
}
dao:

com.itheima.dao.EmpDao:

public interface EmpDao {
    //获取员工列表数据
    public List<Emp> listEmp();
}

com.itheima.dao.impl.EmpDaoA:

public class EmpDaoA implements EmpDao {

    @Override
    public List<Emp> listEmp() {
        //1、加载并解析emp.xml

        //String file = "D:\\Code-Project\\project_practice\\springBoot02\\src\\main\\resources";
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}   
分层解耦:
  • 内聚:软件中各个功能模块内部的功能联系
  • 耦合:衡量软件中各个层/模块之间的依赖、关联的程度
  • 软件设计原则:高内聚低耦合
  • 控制反转:Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想成为控制反转
  • 依赖注入::Dependency Injection,简称DI。容器为应用程序提供运行时所依赖的资源,称之为依赖注入
  • Bean对象:IOC容器中创建、管理的对象,称之为bean
IOC&DI入门:
  • @Component:将当前类交给IOC容器管理,成为IOC容器中的bean
  • @Autowired:运行时,IOC容器会提供该类型的bean对象,并赋值给该变量——依赖注入
  1. Service层 及 Dao层 的实现类,交给IOC容器管理
  2. 为Controller 及 Service 注入运行时依赖的对象
  3. 运行测试
    controller:
    @Component
    @RestController
    public class EmpController {
        @Autowired
        private EmpService empService ;
    }
    
    service:
    @Component
    public class EmpServiceA implements EmpService {
        @Autowired
        private EmpDao empDao;  
        ……
    }
    
    dao:
    @Component
    public class EmpDaoA implements EmpDao {    }       
    

IOC详解:

Bean的声明:

要把某个对象交给IOC容器管理,需要在对应的类上加如下注解:

注释 说明 位置
@Component 声明bean的基础注解 不属于以下三类时,用此注解
@Controller @Component的衍生注解 标注在控制器上
@Service @Component的衍生注解 标注在业务上
@Repository @Component的衍生注解 标注在数据访问类上(由于与mybatis整合,用的少)
注意事项:
  1. @RestController=@Controller+@ResponseBody,所以控制层不用再额外加 @Component 或者 @Controller

  2. 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为首字母小写的类名

    @Component(value = “daoA”)[value可以省略]

  3. 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller

Bean组件扫描:
  1. 前面声明的四大注解,想要生效,还需要被组件扫描注解 @ComponentScan 扫描
  2. @ComponentScan 注解虽然没有显示配置,但是实际上已经包含了启动类声明注解@SpringBootApplication中,默认扫描的范围是启动类所在包以及其子包

DI详解:

@Autowired 注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报错

可以通过以下方法解决:

  1. @Primary:设置bean的优先级,想让哪个bean生效,就在哪个bean上再加@Primary 注解
            @Primary
            @Service
            public class EmpServiceA implements EmpService{}
    
  2. @Qualifier:在@Autowired 上再加@Qualifier 指定bean的名字
            @Qualifier("empServiceA")
            @Autowired
            private EmpService empService;
    
  3. @Resource:不使用@Autowired,直接用@Resource 按名称注入(@Autowired按类型注入)
            @Resource(name = "empServiceA")
            private EmpService empService;
    

@Resource 与 @Autowired 的区别:

  1. @Autowired 是spring框架提供的注解,而@Resource 是JDK提供的注解
  2. @Autowired 默认是按照类型注入,而@Resource 默认是按名称注入
创作不易!转载请注明作者及文章链接或作者博客链接——
- 作者:pidanxia
- 链接:https://pidanxia.ink
(链接可为:**文章链接**或者**作者博客链接**)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇