RESTful入门案例

1. 环境准备

  • 创建一个Web的Maven项目
  • pom.xml添加Spring依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zhn</groupId>
    <artifactId>springmvc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
        </dependency>
        <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <port>80</port>
                <path>/</path>
            </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • 创建对应的配置类
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
        protected Class<?>[] getRootConfigClasses() {
            return new Class[0];
        }
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMvcConfig.class};
        }
        protected String[] getServletMappings() {
            return new String[]{"/"};
    }
    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}
@Configuration
@ComponentScan("com.zhn.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
  • 编写模型类User和Book
public class User {
    private String name;
    private int age;
    //getter...setter...toString省略
}
public class Book {
    private String name;
    private double price;
    //getter...setter...toString省略
}
  • 编写UserController和BookController
@Controller
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(@RequestBody User user) {
        System.out.println("user save..."+user);
        return "{'module':'user save'}";
    }
    @RequestMapping("/delete")
    @ResponseBody
    public String delete(Integer id) {
        System.out.println("user delete..." + id);
        return "{'module':'user delete'}";
    }
    @RequestMapping("/update")
    @ResponseBody
    public String update(@RequestBody User user) {
        System.out.println("user update..." + user);
        return "{'module':'user update'}";
    }
    @RequestMapping("/getById")
    @ResponseBody
    public String getById(Integer id) {
        System.out.println("user getById..." + id);
        return "{'module':'user getById'}";
    }
    @RequestMapping("/findAll")
    @ResponseBody
    public String getAll() {
        System.out.println("user getAll...");
        return "{'module':'user getAll'}";
    }
}
@Controller
public class BookController {
    @RequestMapping(value = "/books",method = RequestMethod.POST)
    @ResponseBody
    public String save(@RequestBody Book book){
        System.out.println("book save..." + book);
        return "{'module':'book save'}";
    }
    @RequestMapping(value = "/books/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable Integer id){
        System.out.println("book delete..." + id);
        return "{'module':'book delete'}";
    }
    @RequestMapping(value = "/books",method = RequestMethod.PUT)
    @ResponseBody
    public String update(@RequestBody Book book){
        System.out.println("book update..." + book);
        return "{'module':'book update'}";
    }
    @RequestMapping(value = "/books/{id}",method = RequestMethod.GET)
    @ResponseBody
    public String getById(@PathVariable Integer id){
        System.out.println("book getById..." + id);
        return "{'module':'book getById'}";
    }
    @RequestMapping(value = "/books",method = RequestMethod.GET)
    @ResponseBody
    public String getAll(){
        System.out.println("book getAll...");
        return "{'module':'book getAll'}";
    }
}

2. 思路分析

需求:将之前的增删改查替换成RESTful的开发方式。
1.之前不同的请求有不同的路径,现在要将其修改为统一的请求路径
修改前: 新增: /save ,修改: /update,删除 /delete…
修改后: 增删改查: /users
2.根据GET查询、POST新增、PUT修改、DELETE删除对方法的请求方式进行限定
3.发送请求的过程中如何设置请求参数?

3 修改RESTful风格

@Controller
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
    @RequestMapping(value = "/users",method = RequestMethod.POST)
    @ResponseBody
    public String save() {
        System.out.println("user save...");
        return "{'module':'user save'}";
    }
}
  • 将请求路径更改为/users
  • 使用method属性限定该方法的访问方式为POST
    • 如果发送的不是POST请求,比如发送GET请求,则会报错

删除

@Controller
public class UserController {
    //设置当前请求方法为DELETE,表示REST风格中的删除操作
    @RequestMapping(value = "/users",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(Integer id) {
        System.out.println("user delete..." + id);
        return "{'module':'user delete'}";
    }
}

访问成功,但是删除方法没有携带所要删除数据的id,所以针对RESTful的开发,如何携带数据参数?
传递路径参数
前端发送请求的时候使用: http://localhost/users/1 ,路径中的1就是我们想要传递的参数。
后端获取参数,需要做如下修改:

  • 修改@RequestMapping的value属性,将其中修改为/users/{id},目的是和路径匹配
  • 在方法的形参前添加@PathVariable注解
@Controller
    public class UserController {
    //设置当前请求方法为DELETE,表示REST风格中的删除操作
    @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable Integer id) {
        System.out.println("user delete..." + id);
        return "{'module':'user delete'}";
    }
}

思考如下两个问题:
(1)如果方法形参的名称和路径{}中的值不一致,该怎么办?

(2)如果有多个参数需要传递该如何编写?

@Controller
public class UserController {
    //设置当前请求方法为DELETE,表示REST风格中的删除操作
    @RequestMapping(value = "/users/{id}/{name}",method =
    RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable Integer id,@PathVariable String name)
    {
        System.out.println("user delete..." + id+","+name);
        return "{'module':'user delete'}";
    }
}

修改

@Controller
public class UserController {
    //设置当前请求方法为PUT,表示REST风格中的修改操作
    @RequestMapping(value = "/users",method = RequestMethod.PUT)
    @ResponseBody
    public String update(@RequestBody User user) {
        System.out.println("user update..." + user);
        return "{'module':'user update'}";
    }
}
  • 将请求路径更改为/users
  • 访问并携带参数:

    根据ID查询
@Controller
public class UserController {
    //设置当前请求方法为GET,表示REST风格中的查询操作
    @RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
    @ResponseBody
    public String getById(@PathVariable Integer id){
        System.out.println("user getById..."+id);
        return "{'module':'user getById'}";
    }
}

将请求路径更改为/users

@Controller
public class UserController {
    //设置当前请求方法为GET,表示REST风格中的查询操作
    @RequestMapping(value = "/users" ,method = RequestMethod.GET)
    @ResponseBody
    public String getAll() {
        System.out.println("user getAll...");
        return "{'module':'user getAll'}";
    }
}

将请求路径更改为/users

小结

RESTful入门案例,我们需要学习的内容如下:
(1)设定Http请求动作(动词)

@RequestMapping(value="",method = RequestMethod.POST|GET|PUT|DELETE)

(2)设定请求参数(路径变量)

@RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
@ReponseBody
public String delete(@PathVariable Integer id){
}