首页 > 编程语言 > 详细

【日程二】初探Spring Web组件

时间:2020-08-23 20:52:56      阅读:106      评论:0      收藏:0      [点我收藏+]

? 在未来的计划中,该文档将会以 问题--答案 的形式驱动向前,同时在每个日程开头都会附上我们走过的路的地图,在每篇的文档末尾附上可使用的技能点

一、地图

技术分享图片

我们在前一篇创建了干净的Maven项目并亲手实践了官方文档的入门项目

二、问题

? 在看了前一篇的 Example后, 我们可能想知道它是怎样工作的。除了 Hello world! 我们还能实现哪些有意思的功能。

三、回答

1、观察Example

技术分享图片

根据MVC模型 一个应用由三部分组成 模型(model)-视图(view)-控制器(controller)

我们可以将视图理解为餐桌,模型就是晚餐,控制器是端盘子和点菜的服务生,在这里,Example类既是主启动类,又是服务员,他的菜只有一道,就是 Hello World!

2、探究更多的用法

? 由于Spring Web是基于Spring MVC的,我们可以查看Spring MVC的教程来得到更多了解 http://c.biancheng.net/spring_mvc/

也可以参阅官方的Rest教程 https://spring.io/guides/gs/rest-service/

Ⅰ、我想把代码写的更规范

删除Example 建立如下结构

技术分享图片

我们将主启动类与Controller分离

根据官方文档 ,主启动类应该这样写

package com.bao;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LearnApp {
    public static void main(String[] args) {
        SpringApplication.run(LearnApp.class,args);
    }
}

技术分享图片

此时点击代码旁的小绿三角就可以启动spring 应用了 ,不过现在的它不提供任何服务

我们在controller中统一编写controller类

package com.bao.controller;

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

@RestController
public class MyController {

    @RequestMapping("/")
    public String sayHello(){
        return "Hello world!";
    }
}

技术分享图片

在这里 @RestController 注解表明 我们返回给用户的结果是json格式的,这在浏览器中可以看到

意味着我们可以做如下的事

package com.bao.controller;

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

import java.util.ArrayList;
import java.util.List;

@RestController
public class MyController {

    @RequestMapping("/")
    public String sayHello(){
        return "Hello world!";
    }

    @RequestMapping("/intlist")
    public List<Integer> intList(){
        List<Integer> integers=new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        return integers;
    }
    
    class User {
        public User(String name, int id) {
            this.name = name;
            this.id = id;
        }
        public String name;
        public int id;
    }

    @RequestMapping("/user")
    public User getUser(){
        return new User("张三",1);
    }

}

技术分享图片

测试

技术分享图片

技术分享图片

技术分享图片

这就是@RestController的作用,它等价于@Controller + @Responsebody

@RequestMapping("/") 指定的路径 跟在 ip:port后边

@RequestMapping也可以写在类上边,可以指定该类的全局路径,类中的@RequestMapping会相对类上的路径

我们来研究一段来自 “微人事” 项目的源码

技术分享图片

在这里,微人事项目将该Controller作为 “薪水” 这一资源的控制器,实现了对它的增删查改 (CRUD)。它遵循了RESTful的规范,路径中并不出现任何动词,而是采用 @GetMapping @PostMapping @DeleteMapping @PutMapping 这四种特殊的注解标识访问路径的方法

有如下关系

@RequestMapping 不指定方法,则 GET POST DELETE PUT都可以访问

@RequestMapping(value = "/",method = RequestMethod.GET) 等价于 @GetMapping("/")

其他三种可以通过指定method参数来实现

同时还注意到有两个新注解 @PathVariable 和 @RequestBody, 他们都注解在方法的参数上。 很明显, 这与请求参数有关

另外 我们还发现 @Autowired注解 他的作用是自动注入需要的对象 具体可参考 Spring 教程 https://www.bilibili.com/video/av967936370?p=20

Ⅱ、请求可以带参数吗?方法如何获取到请求的参数?

? 当然是可以的,不过为了方便,我们需要下载一个工具 PostMan https://www.postman.com/downloads/

具体下载不再说明

? 我们来思考实现一个新需求 -- 实现对 用户 User 的增删查改(不带数据库)

我们为User 对象单独开一个包 一个实体类 和一个Controller

同时作为规范 我们补全 mapper 与 service 。我们得到如下的项目结构

技术分享图片

一般来再说,这个应用应当有如下结构,不过由于我们的项目目前只有一个Spring web组件 所以 我们只写 model 、 servcie 和controller 的内容

技术分享图片

在User中编写如下代码

package com.bao.model;

public class User {
    public String name;
    public int id;
    public String password;

    public User() {
    }

    public User(String name, int id, String password) {
        this.name = name;
        this.id = id;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    @Override
    public String toString() {
        return "User{" +
                "name=‘" + name + ‘\‘‘ +
                ", id=" + id +
                ", password=‘" + password + ‘\‘‘ +
                ‘}‘;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}


它包含 name id passowrd 三个属性,Getter Setter 方法、全参与无参构造 、toString重写

感觉有点太多? idea的快捷生成(Alt + insert)是一个办法

技术分享图片

不过我们还可以使用 Lombok 这一组件来帮助我们做这一件事

首先访问Maven仓库官网

技术分享图片

技术分享图片

进入最新的版本

技术分享图片

复制这段代码到我们项目的pom文件中来

技术分享图片

注意一定要放在标签中间

  <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
   </dependency>

放入前

技术分享图片

放入后

技术分享图片

这样我们的项目就有了两个依赖

我们来使用lombok实现简化需求

package com.bao.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    public String name;
    public int id;
    public String password;
}

技术分享图片

注意 lombok 使用需要idea同名插件支持 同时要启动注解支持 详情参阅百度 lombok idea 配置 lombok不是项目必须 可自由使用。

继续编写UserService

package com.bao.service;

import com.bao.model.User;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

    private static List<User> users;

    static {
        users=new ArrayList<>();
    }

    public List<User> getAllUser(){
        return users;
    }

    public int addUser(User user){
        users.add(user);
        return 1;
    }

    public int deleteUserById(int id){
        int size=users.size();
        for(int i=0;i<size;i++){
            if(users.get(i).getId()==id)
            {
                users.remove(i);
                return 1;
            }
        }
        return 0;
    }
    public int updateUser(User user){
        int size=users.size();
        for(int i=0;i<size;i++){
            if(users.get(i).getId()==user.getId())
            {
                users.remove(i);
                users.add(user);
                return 1;
            }
        }
        return 0;
    }
}

技术分享图片

编写Controller

package com.bao.controller;

import com.bao.model.User;
import com.bao.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;

    @GetMapping("/")
    public List<User> getAllUser(){
       return userService.getAllUser();
    }
    @PostMapping("/")
    public String addUser(@RequestBody User user){
        userService.addUser(user);
        return "添加成功";
    }
    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable int id){
        userService.deleteUserById(id);
        return "删除成功";
    }
    @PutMapping("/")
    public String updateUser(@RequestBody User user){
        userService.updateUser(user);
        return "更新成功";
    }
}

技术分享图片

写的很简单,这里主要是注意@PathVariable 与 @RequestBody 的使用

启动我们的应用

技术分享图片

打开postman,我们先来测试GET

技术分享图片

测试新增一个用户

技术分享图片

成功加入

技术分享图片

测试更新用户

技术分享图片

更新成功

技术分享图片

测试删除用户

技术分享图片

删除成功

技术分享图片

这里我们的要点有两个

一个是 @PathVariable 与 "/{id}"。它从路径中取出参数 并放入方法的参数中

一个是@RequestBody 这是它的postman请求体

技术分享图片

@RequestBody 要求Type为 JSON格式, 他会把 body字符串转换为相应的对象传入参数中,如果键对不上则值为null,同时他会要求对象有无参构造方法,因为转换的原理就是调用属性的Setter方法。

同时 Spring Web还支持 @RequestParam 和无注解参数,这在下一篇会讲。

下一篇
https://www.cnblogs.com/dataocean/p/13550546.html

技能点

技能点
@RestController
@RequestMapping("/")
@SpringBootApplication
Spring Boot 主启动类的编写
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
lombok 与 @Data @AllArgsConstructor @NoArgsConstructor
postman的使用
@PathVariable 与 "/{id}"
@RequestBody

【日程二】初探Spring Web组件

原文:https://www.cnblogs.com/dataocean/p/13550538.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!