Springboot入门体验

Springboot

IDEA里面配置好springboot的开发环境后,我们就可以进行一个简单的Springboot程序开发了。

创建controller对象

创建controller包,这个包专门处理来自前端的请求,并把对应的请求返回到前端。下面是我们的一个简单入门程序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.zxp.springbootstart.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "Hello World";
    }
}

其中,RequestMapping指定了映射的url,只要我们访问对应的这个hello,那么我们就会收到来自后端返回的Hello World

参数初始化

如果参数名和前端传递过来的参数名一致,例如下面这个GET请求

1
localhost:8080/simpletest?name=Bob&age=40

这个URL传递了两个参数,即nameage,只要我们的函数形参与传递过来的参数一致,那么就可以自动初始化好。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.zxp.springbootstart.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestController {
    @RequestMapping("/simpletest")
    public String simpletest(String name, Integer age) {
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        return "success";
    }
}

如果我们不希望一定把参数名称给写死,那么就可以使用一个注解,@RequestParam,这个注解会自动把前端传递过来的参数给初始化好

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.zxp.springbootstart.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RequestController {
    @RequestMapping("/simpletest")
    public String simpletest(@RequestParam("name") String userename, Integer age) {
        System.out.println("Name: " + userename);
        System.out.println("Age: " + age);
        return "success";
    }
}

多参数传递

假设传递了很多参数,例如name age address 等等,最好的做法是把这些参数全部都封装为一个类。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.zxp.springbootstart.pojo;

public class User {
    private String name;
    private Integer age;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }
}

这样我们在传递参数的时候只需要传递User即可。

数组集合参数

当有许多参数的名称一致时,例如前端传递了一个多选项的参数,我们可以使用数组或者集合来存储这些参数。

使用数组来进行保存

1
2
3
4
5
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby) {
    System.out.println(Arrays.toString(hobby));
    return "success";
}

也可以使用集合来进行保存

1
2
3
4
5
@RequestMapping("/listParam")
public String listParam(@RequestParam("hobby") List<String> hobby) {
    System.out.println(hobby);
    return "success";
}

时间参数

后端需要使用后端controller方法中,需要使用Date类型或LocalDateTime类型,来封装传递的参数。时间参数需要按照一定的参数进行传递

1
2
3
4
5
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
    System.out.println(updateTime);
    return "OK";
}

需要指定pattern,在前端传递时间参数的时候也需要按照一定的方式去传递时间参数。

Json

Json是键值对类型的数据,其键是字符串类型,下面一个就是一个json数据的示例

1
2
3
4
{
    "name": "Bob",
    "age": 20
}

在传递json参数的时候需要使用RequestBody来进行注解。

路径参数

在传递参数的时候,还可以传递一些路径参数,需要使用@PathVariable来接受参数

1
2
3
4
5
@RequestMapping("/path/{id}")
    public String path(@PathVariable Integer id) {
        System.out.println(id);
        return "success";
    }

在传递参数的时候就可以使用这样的URL

1
localhost:8080/path/10

那么在后端得到的数据就是10

统一响应结果

在返回响应时,如果每次都是用不同的类型返回,那么前端每次都得处理不同的数据格式,我们可以把返回结果封装为一个类来进行使用。

这里又可以分为三种情况

  1. 只需要响应状态
  2. 需要返回数据
  3. 响应错误

其中需要封装好三个变量

1
2
3
private int code;
private String msg;
private Object data;

响应案例

首先将网页等静态资源全部存储在static目录下,在这个案例中,我们需要掌握的技巧有:

  1. 如何动态的获取文件路径
  2. stream流式修改数据
  3. 响应数据
  • 动态获取地址

    1
    
    String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
    
  • 中间处理

    将前端传过来的数据进行替换

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    empList.stream().forEach(emp -> {
                        String gender = emp.getGender();
                        if ("1".equals(gender)) {
                            emp.setGender("man");
                        } else if ("2".equals(gender)) {
                            emp.setGender("woman");
                        }
    
                        String job = emp.getJob();
                        if ("1".equals(job)) {
                            emp.setJob("讲师");
                        } else if ("2".equals(job)) {
                            emp.setJob("班主任");
                        } else if ("3".equals(job)) {
                            emp.setJob("就业指导");
                        }
                    }
            );
    

    在前端传递过来的数据中,其中genderjob都是id来标志的,我们需要将这些数据进行人为替换后再将数据写回前端。

    写回前端时可以使用我们封装好的Result作为统一结果返回。

    1
    
     return Result.success(empList);
    

    开发规范

    在开发时要注意分层,每个层只完成自己的那一部分任务即可。如果把所有的逻辑全部写在controller层不太规范。

    一般的,我们可以将这个逻辑划分为三个部分,即后端处理来自前端的响应controller层;响应后完成server服务;中间需要进行数据的可以再封装一个dao层来专门管理数据。

    我们来改造一下这个代码

    首先在dao层处理所有的获取资源操作,实现一个dao接口

    1
    2
    3
    4
    
    public interface EmpDao{
        // 获取资源并将资源封装到集合里面
        public List<Emp> listEmp(){}
    }
    

    实现这个接口

    1
    2
    3
    4
    5
    6
    7
    8
    
    @Override
    public List<Emp> listEmp() {
        // 返回listEmp
        //1. 解析前端页面
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
    

    实现service代码,这里负责处理数据,也就是业务逻辑.

    1
    2
    3
    
    public interface EmpService {
        public List<Emp> listEmp();
    }
    

    controller层对数据进行响应。

    1
    2
    3
    4
    5
    6
    7
    
    private EmpService empService = new EmpServiceA();
    @RequestMapping("/listEmp")
    public Result listEmp() {
        // 得到处理的listemp
        List<Emp> list = empService.listEmp();
        return Result.success(list);
    }
    

    这样做其实还不够规范,可以看到我们每次都是去new一个私有对象然后再去获取里面的方法,如果后面修改名称的话,这样就会导致代码报错。下次来记录怎么解决这个问题。

Licensed under CC BY-NC-SA 4.0
花有重开日,人无再少年
使用 Hugo 构建
主题 StackJimmy 设计