Spring Boot 2+Thymeleaf企业应用实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.3 Spring MVC的常用注解

前面讲述了Spring框架的常用注解,而Spring Boot默认集成了Spring MVC。这一节,我们会讲解一些Spring MVC的常用注解,在本书中会经常使用这些注解,它们可完成大部分的Web功能。

4.3.1 Controller注解

Spring MVC提供了Controller等注解,用于修饰Java类,被修饰的类会充当MVC中的控制器角色,它们不需要继承其他类,也不需要实现接口。Controller注解使用了@Component修饰,换言之,使用了Controller修饰的类,会被@ComponentScan检测,并且会作为Spring的bean被放到容器中。代码清单4-20即使用了Controller等注解。

代码清单4-20:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\ctl\MyController.java

@Controller
public class MyController {

    @RequestMapping(value = "/hello")
    @ResponseBody
    public String hello() {
      return "hello";
    }
}

访问应用的“/hello”路径,将会得到“hello”字符串。除了Controller注解外,还有一个RestController注解,这是一个组合注解,它由@Controller与@ResponseBody组成。使用了@RestController修饰的类,默认情况下其每个控制器方法都等于使用了@ResponseBody修饰,方法的返回值会被写到响应体中。以下代码等同于代码清单4-20。

@RestController
public class MyRestController {
    @RequestMapping(value = "/rhello")
    public String rhello() {
        return "rest hello";
    }
}

启动服务器(codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\ctl\ControllerApp.java),在浏览器中访问:http://localhost:8080/hellohttp://localhost:8080/rhello,可看到具体效果。

4.3.2 RequestMapping注解

RequestMapping注解可修饰类或方法,主要用于映射请求与处理方法。当使用它来修饰一个类并设置了URL时,可以理解为,为各个请求设置了URL前缀,请见代码清单4-21。

代码清单4-21:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\rm\RmApp.java

@SpringBootApplication
@RestController
@RequestMapping("/oa")
public class RmApp {

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

    @RequestMapping("/hello")
    public String hello() {
      return "hello";
    }
}

在该代码清单中,Spring Boot的启动类与控制器为同一个。在类一级使用@RequestMapping配置访问前缀为“/oa”,如果要请求“hello”方法,则访问路径:http://localhost:8080/oa/hello。RequestMapping注解主要有以下属性。

path与value:两个属性互为别名,用于配置映射的URI。在配置RequestMapping时,如果不设置属性名(如RequestMapping(“hello”)),则等同于配置了path属性。

method:映射的HTTP方法,例如GET、POST、PUT、DELETE等。

params:为映射的请求配置参数标识,例如配置为“params = 'action=save'”,则要通过“http://localhost:port/hello?action=save”访问该映射的方法。在表单中,可以为表单提交按钮设置name属性,例如<input type="submit" name="add"/>,则表单会被提交到params值为add的方法。

consumes:配置请求的数据类型,可配置为XML或JSON等数据格式。

produces:配置响应的数据类型,例如配置为“application/json”,则表示返回JSON数据。

为了让我们减少配置,Spring MVC还提供了几个注解,这些注解默认配置了@ReqeustMapping的method属性。例如@GetMapping注解,其效果等同于@RequestMapping (method = “RequestMethod.GET”);还有@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping,这几个注解默认都设置了不同的method属性。

4.3.3 PathVariable注解

@PathVariable主要用来修饰方法参数,表示该方法参数是请求URI的变量。请求URI中的变量,会自动转化为方法的参数类型,请见代码清单4-22。

代码清单4-22:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\pv\PvApp.java

@RequestMapping(value = "/hello/{name}")
@ResponseBody
public String hello(@PathVariable String name) {
    return "hello, " + name;
}

以上代码中的方法参数“name”使用了@PathVariable修饰,这样,在处理请求URI时,会自动将地址中的{name}变量转化为方法的name参数。默认情况下,URI中的变量名称为name,因此该变量会与方法中名称为name的参数绑定,当然,我们也可以显式指定,请见以下代码:

@RequestMapping(value = "/test/{myName}")
@ResponseBody
public String test(@PathVariable("myName") String abc) {
    return "test, " + abc;
}

在以上代码片断中,为@PathVariable配置了属性值,这个属性值显式绑定了 “abc”参数与 “myName”变量。

4.3.4 MatrixVariable注解

前面的@PathVariable注解主要用来获取单一的URI参数,如果想通过URI来传输一些复杂的参数,则可以考虑使用@MatrixVariable注解。使用时需要遵守一定的规范,参数的名称与值使用key-value的形式,多个参数间使用分号(;)隔开,如果一个参数拥有多个值,则值与值之间使用逗号隔开。这种URI的参数表现形式,称为矩阵变量,请见以下的URI:

/car/{id}; color=red; year=2012

该URI传入了id参数,并且传入color与year两个参数,值分别为red与2012。对于上面的URI,在控制器中如何获取呢?首先,需要开启Spring MVC对矩阵变量的支持。在Spring Boot中,新建配置类,请见代码清单4-23。

代码清单4-23:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\mv\MyWebConfig.java

@Configuration
public class MyWebConfig extends WebMvcConfigurationSupport {

    @Override
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
      final RequestMappingHandlerMapping requestMappingHandlerMapping = super
              .requestMappingHandlerMapping();
      requestMappingHandlerMapping.setRemoveSemicolonContent(false);
      return requestMappingHandlerMapping;
    }
}

在代码清单4-23中,将容器中RequestMappingHandlerMapping的removeSemicolonContent属性设置为false,即可开启对矩阵变量的支持。接下来,新建启动类与控制器,在方法中获取矩阵变量,请见代码清单4-24。

代码清单4-24:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\mv\MvApp.java

@SpringBootApplication
@Controller
public class MvApp {

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

    @GetMapping(value = "/car/{id}")
    @ResponseBody
    public String pathA(@PathVariable Integer id,
          @MatrixVariable String color,
          @MatrixVariable String year) {
      System.out.println(id);
      System.out.println(color);
      System.out.println(year);
      return "test";
    }
}

运行代码清单4-24,在浏览器中访问:http://localhost:8080/car/100; color=red; year=2012,则可以看到控制台会输入相应的变量。矩阵变量还有其他的表现形式,但在日常开发中并不常用,本章就不深入讨论了。

4.3.5 RequestParam注解

如果要获取请求中的参数,则可以使用@RequestParam注解。当一个请求参数被放到请求体中时,就可以使用这种方式获取它,最常见的就是表单的提交。新建一个控制器方法,用于获取请求参数,请见代码清单4-25。

代码清单4-25:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\rp\RpApp.java

@RequestMapping(value = "/login")
@ResponseBody
public String login(@RequestParam String userName) {
    System.out.println(userName);
    return "success";
}

为了简单起见,本章不对表现层进行配置。新建一个最简单的HTML文件(该文件不需要在服务器中运行,可以直接在浏览器打开),向控制器提交表单,请见代码清单4-26。

代码清单4-26:codes\04\4.3\mvc-ants\form.html

<form method="post" action="http://localhost:8080/login">
    <input type="text" name="userName"/>
    <input type="submit" value="提交"/>
</form>

@RequestParam注解还可以用来修饰Map或者MultiValueMap, MultiValueMap继承于Map接口,我们所得实例为LinkedMultiValueMap。注意,该Map实现并非线程安全的。在Map中将会存放所有的请求参数,请见以下代码片断:

@RequestMapping(value = "/multi")
@ResponseBody
public String multi(@RequestParam Map<String, String> values) {
    System.out.println(values.get("myName"));
    System.out.println(values.get("passwd"));
    return "success";
}

4.3.6 文件上传

文件上传是常见的功能,使用RequestParam注解就可以在表单中实现文件上传。获取文件内容的控制器方法,请见代码清单4-27。

代码清单4-27:codes\04\4.3\mvc-ants\src\main\java\org\crazyit\boot\c4\file\FileApp.java

@RequestMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file)
      throws IOException {
    byte[] content = file.getBytes();
    System.out.println(content);
    return "success";
}

在控制器中,使用@RequestParam修饰MultipartFile参数,在方法体中直接输出文件的byte数组。接下来,编写一个静态的HTML页面,实现文件上传。再次强调,前一小节以及本小节的HTML页面,都不需要运行在服务器中,直接在浏览器中打开即可。文件上传的HTML页面内容,请见代码清单4-28。

代码清单4-28:codes\04\4.3\mvc-ants\file.html

<form method="post" action="http://localhost:8080/upload" enctype="multipart/form-data">
    <input type="file" name="file"/>
    <input type="submit" value="提交"/>
</form>

直接使用浏览器打开HTML页面,选择文件并提交表单后,则可以看到控制台的输出。

4.3.7 RestController注解

RestController注解的目的是为了让我们更加简便地使用@Controller与@ResponseBody这两个注解,查看@RestController源码就可以知道,这个注解本身就使用了@Controller与@ResponseBody来修饰。ResponseBody注解可以修饰控制器方法,方法的返回值将会被写到HTTP的响应体中,所返回的内容,将不放到模型中,也不会被解释为视图的名称。例如以下代码片断,将会直接返回字符串:

@RestController
public class RcApp {

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

除了本节所介绍的注解外,还有RequestAttribute、SessionAttribute等注解也较为常用,这些注解,会配合页面、AJAX等知识点,或在具体的案例中一并讲述。这里我们能掌握Controller、RequestMapping、参数传递等注解即可,更深入的知识,可在后面章节,配合具体的功能予以学习。