Spring Boot
作为 Java
中广受欢迎的框架,其 controller
的使用必须掌握了解,本篇的学习将从以下几个方面展开:
动态URL
组路由
参数解析
Restful controller
本篇假设你已经了解 Spring Boot
开发的基本流程,以下示例主要从 controller
角度学习。
1.动态URL
说到此,做过 web开发
的各位码农应该都见过类似:/user/id1
, /user/id2
这种,也就是 /user/{id}
这种,好在 Spring Boot
中,我们可以通过功能强大的注解解决这种问题,包括解析到具体 路由。
以下是编码示例:
Java
package com.example.springbootdemo2.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
@Controller
public class DynamicURLParamController {
@RequestMapping(value = "/dynamic/normal", method = RequestMethod.GET)
public @ResponseBody Object normal() {
Map<String, String> map = new HashMap<>();
map.put("handler", "normal");
return map;
}
@RequestMapping(value = "/dynamic/{id}/{action}", method = {RequestMethod.GET})
public @ResponseBody Object returnIdAndAction(@PathVariable(value = "id") Integer id, @PathVariable(value = "action") String action) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("action", action);
return map;
}
}
上面的示例中,我们先实现了一个静态路径访问的 URL: /dynamic/normal
,只要输入 http://ip:port/dynamic/normal, 就会返回一个 Map
结构的响应体。
接着我们在注解 @RequestMapping
中的 value
设置为 /dynamic/{id}/{action}
,访问 method
设置为 GET
,在具体的处理方法中我们通过注解 @PathVariable
解析赋值给对应的动态参数 id
和 action
,在具体的处理方法中就可以直接使用这里的动态字段了,比如有这样的应用场景,我们通过 id
获取到用户的信息,根据 action
做相应的动作。
2.组路由
组路由,显然我们对开放的 API接口 根据业务功能做一定分类分组,比如我们可以有这样几个组:
/auth
,认证用/register
,注册用/article
,文章的增删改查/userInfo
,用户信息的增删改查
上面枚举的只是几个常有的业务分组,实际的运用中根据具体的业务场景就是其他的功能分组了。
下面是编码示例:
Java
package com.example.springbootdemo2.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/group")
public class GroupRouterController {
@GetMapping("/subGroup")
public @ResponseBody String subGroup() {
return "This is the subGroup under the group.";
}
}
从代码中也可以看到,这里的分组其实简单,我们只需要在控制器类上加个注解 @RequestMapping
就可以区分不同的组,接着在具体的处理方法中继续写响应的路径,我们就可以通过 /group/subGroup
访问到 subGroup
这个方法并完成一定功能。
3.参数解析
在我们日常访问浏览器时,是不是会有这种访问路径:https://ip:port/aaa/bbb?username=xxx&query=yyy ,相信细心的你肯定遇到过,又或者是通过表单提交的,又或者是现如今更为普遍的通过 json
传递请求参数的。
所以我们这里的参数解析主要通过以下三个方面来解析相关参数:
- GET请求中,参数在URL上,有长度限制
- POST请求中,参数通过表单传递
- POST请求中,参数通过json传递
话不多说,上实现编码:
Java
package com.example.springbootdemo2.controller;
import com.example.springbootdemo2.param.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping(value = "/parse")
public class ParseParamsController {
// 1.解析多个query参数到指定字段
@GetMapping(value = "/query/simple") // /parse/query/simple?name=xxx&age=xx
public @ResponseBody Object parseGetQueryParams(@RequestParam("name") String name, @RequestParam("age") Integer age) {
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("age", age);
return map;
}
// 2.解析多个query参数到Map结构
@GetMapping(value = "/query/map")
public @ResponseBody Object parseGetQueryMap(@RequestParam Map<String, Object> map) {
return map;
}
// 3.解析多个query参数到List,前提是同字段
@GetMapping(value = "/query/list")
public @ResponseBody Object parseGetQueryList(@RequestParam("name") String[] names) {
return names;
}
@PostMapping(value = "/form")
public @ResponseBody Object parsePostFormParams(@RequestParam(value = "username") String username, @RequestParam(value = "age") Integer age) {
Map<String, Object> map = new HashMap<>();
map.put("username", username);
map.put("age", age);
return map;
}
@PostMapping("/json/map")
public @ResponseBody Object parsePostJsonParamsWithMap(@RequestBody Map data) {
return data;
}
@PostMapping("/json/object")
public @ResponseBody Object parsePostJsonParamsWithObject(@RequestBody User user) {
return user;
}
}
相关的 User 类
就是一个简单的 Bean:
Java
package com.example.springbootdemo2.param;
public class User {
private String name;
private int 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;
}
}
GET-query参数
我们在上面的代码中,我们首先是解析多个query参数到指定的字段,形如访问 /parse/query/simple?name=xxx&age=yy
,这里我们通过注解 @RequestParam
获取到指定字段。
接着我们也可以将query参数全部倒进一个 Map 结构中,同样用到 @RequestParam
注解,只是这里直接指明是 Map 结构,如果需要用到参数,就可以通过 map.get(xxx)
获取指定字段的值。
最后我们将query参数中的同字段解析到一个数组中,前提是query参数的字段是同一字段,好比是 /parse/query/list?name=aaa&name=bbb&name=ccc
,最后我们在 names 中的就是 String[] names = {"aaa", "bbb", "ccc"}
。
POST-Form表单
表单参数传递也是常见的方式之一,这里我们也是用 @RequestParam
注解获取到对应的参数,看看代码就知道了。
POST-Json
在如今的 web开发中,Rest风格的API 比较常见,这里尤以 Json 居多。注意,我们这里是通过注解 @RequestBody
来解析请求体的,这里分两种情况:
- 解析到 Map 结构,比较通用,但字段需要通过 get 方法获取
- 解析到我们预先写好的 Bean 中,这里是个简单的 User 类,只有两个私有字段,name和age
4.Restful controller
发现没有,我们在上面的编码中,其实用到很多注解,如果换个注解:@Controller
-> @RestController
的话,会响应的减少一些注解,因为 @RestCOntroller
做了更多的包装处理,依然还是编码实现:
Java
package com.example.springbootdemo2.controller;
import com.example.springbootdemo2.param.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class RestfulStyleController {
@GetMapping(value = "/rest/user/{id}")
public Object getUserInfoById(@PathVariable("id") String id) {
System.out.println("正在查找 id = " + id + "的用户");
Map<String, Object> info = new HashMap<>();
info.put("id", id);
info.put("name", "alice");
info.put("age", 25);
return info;
}
@PostMapping(value = "/rest/userAction/register")
public Object postUserInfoToRegister(User user) {
return "ok";
}
}
在上面的代码中,我们首先实现一个 GET 方法访问的路径,接着实现了一个 POST 方法访问的路径,在 Rest风格 中不同的是,我们可以减少一些如 @ResponseBody/@RequestBody
等注解,是不是又减少了一些工作量。
参考: