前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC 中的Annotated Controllers

SpringMVC 中的Annotated Controllers

作者头像
大话swift
发布2019-09-12 12:50:18
6200
发布2019-09-12 12:50:18
举报
文章被收录于专栏:大话swift大话swift

看看第一个controller

代码语言:javascript
复制
@Controller
public class HelloController {

    @GetMapping("/hello")
    public String handle(Model model) {
        model.addAttribute("message", "Hello World!");
        return "index";
    }
}

上面透漏一下信息:是一个GET响应 查找web下的index模版,通过model将数据传递给模版引擎渲染

我们看到了能访问/hello,那么为啥呢?SpringMVC怎么知道有这个文件呢?--答案是通过组件扫描

代码语言:javascript
复制
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {

    // ...
}

上面的代码与xml配置等同

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.example.web"/>

    <!-- ... -->

</beans>

总体来说都是基于Spring的IOC容器方式,通过组件扫描将各组件加载称为bean

Request Mapping

采用@Request Mapping实现controller响应controllers的网络请求

下面是具体分类,来响应区分不同的网络方法

代码语言:javascript
复制
    @GetMapping
    @PostMapping
    @PutMapping
    @DeleteMapping
    @PatchMapping

下面是具体的实例参考

代码语言:javascript
复制
@RestController
@RequestMapping("/persons")
class PersonController {

    @GetMapping("/{id}")
    public Person getPerson(@PathVariable Long id) {
        // ...
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void add(@RequestBody Person person) {
        // ...
    }
}
URI patterns

可以使用@PathVariable匹配参数中添加变量参数来区分数据,比如

代码语言:javascript
复制
@GetMapping("/owners/{ownerId}/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
    // ...
}

同时你也能够在class和Method级别注解声明URI变量,比如

代码语言:javascript
复制
@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {

    @GetMapping("/pets/{petId}")
    public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
        // ...
    }
}

上面中controller下的所有Mapping响应都会加上/owners/{ownerId}前缀,例如上栗中的组合成为:/owners/{ownerId}/pets/{petId}

除此紫外我们还可在Mapping中添加正则匹配:

代码语言:javascript
复制
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String ext) {
    // ...
}
Consumable Media Types

在Mapping注解中我们还可以限制Content-Type

代码语言:javascript
复制
@PostMapping(path = "/pets", consumes = "application/json") 
public void addPet(@RequestBody Pet pet) {
    // ...
}

还可以设置header数据

代码语言:javascript
复制
@GetMapping(path = "/pets", headers = "myHeader=myValue") 
public void findPet(@PathVariable String petId) {
    // ...
}

动态注册Controller响应

代码语言:javascript
复制
@Configuration
public class MyConfig {

    @Autowired
    public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler) 
            throws NoSuchMethodException {

        RequestMappingInfo info = RequestMappingInfo
                .paths("/user/{id}").methods(RequestMethod.GET).build();

        Method method = UserHandler.class.getMethod("getUser", Long.class);

        mapping.registerMapping(info, handler, method); 
    }
}

请求参数

在方法中使用@RequestParam只标注的变量是url中的query数据

代码语言:javascript
复制
@Controller
@RequestMapping("/pets")
public class EditPetForm {
    @GetMapping
    public String setupForm(@RequestParam("petId") int petId, Model model) { 
        Pet pet = this.clinic.loadPet(petId);
        model.addAttribute("pet", pet);
        return "petForm";
    }
}

上栗中的urlquery为:/pets?petId=xxx

与此同时我还可以使用@RequestHeader将header的数据注入到响应的方法中

代码语言:javascript
复制
@GetMapping("/demo")
public void handle(
        @RequestHeader("Accept-Encoding") String encoding, 
        @RequestHeader("Keep-Alive") long keepAlive) { 
    //...
}

Session和Cookie注入

代码语言:javascript
复制
@GetMapping("/demo")
public void handle(@CookieValue("JSESSIONID") String cookie) { 
    //...
}

@RequestMapping("/")
public String handle(@SessionAttribute User user) { 
    // ...
}

请求数据转模型注入(@ModelAttribute

代码语言:javascript
复制
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet, BindingResult result) {
 if (result.hasErrors()) {
        return "petForm";
    }
 } 

这个需要请求参数与Model的属性名称相同,也是十分方便,同时也可做数据监测

文件上传

文件上传通常采用form表单需要multipart/form-data

代码语言:javascript
复制
@Controller
public class FileUploadController {

    @PostMapping("/form")
    public String handleFormUpload(@RequestParam("name") String name,
            @RequestParam("file") MultipartFile file) {

        if (!file.isEmpty()) {
            byte[] bytes = file.getBytes();
            // store the bytes somewhere
            return "redirect:uploadSuccess";
        }
        return "redirect:uploadFailure";
    }
}

同样的我们也可将form的文件转换为model

代码语言:javascript
复制
class MyForm {

    private String name;

    private MultipartFile file;

    // ...
}

@Controller
public class FileUploadController {

    @PostMapping("/form")
    public String handleFormUpload(MyForm form, BindingResult errors) {
        if (!form.getFile().isEmpty()) {
            byte[] bytes = form.getFile().getBytes();
            // store the bytes somewhere
            return "redirect:uploadSuccess";
        }
        return "redirect:uploadFailure";
    }
}

这个form文件上传会有两个字段:一个是表单名 另一个是文件名

今天就这么多,看英文自己翻译总结还是费点劲,下一篇阅读URL Linkes

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Request Mapping
    • URI patterns
      • Consumable Media Types
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档