springboot中的controller注意事项说明

关于controller注意事项

spring boot的controller水深无比,经过学习,我总结一些tips,以便以后参照,减少错误:

1.controller主要有两个标签

@Controller和@RestController,两个标签无法同时发挥作用,前者标注的类只能返回静态文件,后者标注的类用于返回数据类型如json字符串

2.使用@Controller标签时

templates下的文件并不能被识别(自己试验过,发现和网上很多说法都不一样),只有static文件夹下文件能直接被读取,具体代码如下:

@RequestMapping(value="/", method= RequestMethod.GET)
public String home() {
    return "views/index.html";
}

这里static作为根目录被访问。

各种controller的写法

最近玩SpingBoot,以下是一些Controller的各种写法

我们将分为四部分

  • 1、Controller的类型(传统的 和 REST)
  • 2、路由(Routes)
  • 3、如何接收数据
  • 4、Controller示例

Controller 类型

你也许每天都在使用Spring ,但你知道controller有几种类型吗?其实controller是有两种的,一种就是传统的web的那种controller,而另外一种就是REST类型的controller。

@Controller 通常是被使用服务于web 页面的。默认,你的controller方法返回的是一个string 串,是表示要展示哪个模板页面或者是要跳转到哪里去。

@RestController 就是专门用在编写API的时候,特别那种返回一个JSON,或者是XML等等。然后方法返回的是可以是一个对象,是一个可以被序列化的对象。

当然了你也可以通过controller来实现返回JSON、XML这些。只是这里为了"REST",得另立门户,这样会更加的清晰明了。

路由(Routes)

这里的路由就是指http method。(GET,POST,PUT,PATCH,DELETE)。

HTTP Methods

在Spring boot中,http method可以被用类似“*Mapping”的格式来表示:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @PatchMapping
  • @DeleteMapping

然后这些注解中可以添加path,像下面这样:

例子: @GetMapping("/users")

一个比较典型的REST controller 一般是像下面这样来映射路由的:

@RestController
public class UsersController {   
 
   @GetMapping("/users")    
    public List<User> index() {...}  
  
    @GetMapping("/users/{id}")    
    public User show(...) {...}
    
    @PostMapping("/users")    
    public User create(...) {...}  
  
    @PutMapping("/users/{id}")   
    public User update(...) {...}    
 
    @DeleteMapping("/users/{id}")    
    public void delete(...) {...}
}

还有一种比较常见的做法是通过在controller类上添加一个@RequestMapping注解。这样相当于可以把上面的所有的mapping前缀添加到这里。

像下面这样(基于上面的例子修改):

@RestController
@RequestMapping("/users")
public class UsersController {
    
    @GetMapping
    public List<User> index() {...}
    
    @GetMapping("{id}")    
    public User show(...) {...}   
 
    @PostMapping
    public User create(...) {...} 
   
    @PutMapping("{id}")   
    public User update(...) {...}   
 
    @DeleteMapping("{id}")    
    public void delete(...) {...}
}

返回状态

Controller的方法可以去指定一个返回状态码。默认的是返回一个200 OK,如果是没有返回值(void)则返回 204 No Content。

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(...) {...}

路径变量

你可以通过添加@PathVariable注解来把路径上的值捕获下来:

// DELETE /users/123
@DeleteMapping("/users/{id}")
public void delete(@PathVariable long id) {...}

默认情况下,参数名必须要和路径上的变量名一样。但你也可以通过下面的方式来修改,就是你通过给@PathVariable赋值为路径变量名,然后参数名就可以是不一样的了:

// GET /users/me@example.com/edit
@GetMapping("/users/{email}/edit"
public String edit(@PathVariable("email") String userEmail) {...}

接收数据

查询字符参数

如果是通过?xxx=xxx&yyy=yyy来传递过来的参数,那么我们可以通过@RequestParam来获取:

// GET /users?count=10
@GetMapping("/users")
public List<User> index(@RequestParam int count) {...}

默认的话,变量名必须要和查询字符参数是一样的。你也可以通过下面的方式来修改:

// GET /users?num_per_page=50
@GetMapping("/users")
public List<User> index(@RequestParam("num_per_page") int numPerPage) {...}

提交HTML表单数据

如果我们想要创建一个用户。这时候,我么可能在前端,写下面这样一个form:

<form action="/users" method="POST">
  <input name="name"/>
  <input name="email"/>
  <button type="submit">Create User</button>
</form>

现在我们创建一个请求模型,用来匹配我们的前端form结构:

class UserCreateRequest {    
   private String name;    
   private String email;    
   /* Getters & Setters omitted */
}

然后我们就可以在controller对应的方法上来捕获form里的值,我们通过对参数添加一个@ModelAttribute注解就可以实现了:

@PostMapping("/users")
public User create(@ModelAttribute UserCreateRequest request) {...}

提交JSON

就像上面例子那样,我们创建一个用户,然后是一个JSON格式:

{ "name": "Som Eone", "email": "someone@example.com"}

然后请求模型还是沿用之前的:

class UserCreateRequest {undefined
private String name;
private String email; 
}

然后我们使用@RequestBody来捕获前端发送过来的JSON串,然后反序列化到我们的请求模型UserCreateRequest:

@PostMapping
public User create(@RequestBody UserCreateRequest request) {...}

Controller 举例

以下是使用上述所有注解创建Controller的示例。 没有具体逻辑,只是简单的展示上面说到的各个注解。

传统的controller

这类型的controller返回值表示要展示的页面或要跳转到哪个请求。

@Controller
@RequestMapping("/users")
public class UsersController {    
   @GetMapping
    public String index() {        
        return "users/index";
    }    
 
    @GetMapping("{id}")    
    public String show(@PathVariable long id) {        
         return "users/show";
    }   
 
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)    
    public String create(@ModelAttribute UserCreateRequest request) {
      return "redirect:/users";
    }    
 
    @PutMapping("{id}")    
    public String update(@PathVariable long id, @RequestBody UserUpdateRequest request) {        
       return "redirect:/users/" + id;
    }   
 
    @DeleteMapping("{id}")    
    public String delete(@PathVariable long id) {        
        return "redirect:/users";
    }
}

REST controller

这类型的controller返回值是一些对象,这些对象要被序列化成JSON、XML等其他格式,并不是表示要跳转到哪个HTML模板。

@RestController
@RequestMapping("/users")
public class UsersController {    
   @GetMapping
    public List<User> index() {        return new ArrayList<User>();
    }   
 
    @GetMapping("{id}")    
    public User show(@PathVariable long id) {        return new User();
    }  
 
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)    
    public User create(@RequestBody UserCreateRequest request) {
       return new User();
    }    
 
    @PutMapping("{id}")    
    public User update(@PathVariable long id, @RequestBody UserUpdateRequest request) {        
       return new User();
    }    
 
    @DeleteMapping("{id}")    
    public void delete(@PathVariable long id) {}
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解析springboot包装controller返回值问题

    1.springboot项目统一包装返回值,通常返回结果包含code.message.data,结构如下 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class ResponseResult<T> { private int code; private Strin

  • springboot controller 增加指定前缀的两种实现方法

    目录 controller 增加指定前缀 1.增加配置 2.过滤拦截 springboot服务端口.项目前缀的配置 在application.properties中配置 controller 增加指定前缀 1.增加配置 server.servlet.context-path: /api 这种是最常见的,加上这个配置后,所有的url,必须带上/api的前缀,才能访问到该url 2.过滤拦截 这种是加上/api也可以访问,不加/api也可以访问,适合项目重构修改的适合用 import org.apa

  • SpringBoot开发详解之Controller接收参数及参数校验

    目录 Controller 中注解使用 传输参数的几种Method 获取参数的几种常用注解 使用对象直接获取参数 使用@Valid对参数进行校验 总结 Controller 中注解使用 接受参数的几种传输方式以及几种注解: 在上一篇中,我们使用了JDBC链接数据库,完成了简单的后端开发.但正如我在上文中抛出的问题,我们能不能更好的优化我们在Controller中接受参数的方式呢?这一篇中我们就来聊一聊怎么更有效的接收Json参数. 传输参数的几种Method 在定义一个Rest接口时,我们通常会

  • springboot如何解决非controller类引用service的问题

    目录 解决非controller类引用service问题 解决办法 总的代码如下 在非controller层如何调用service层服务 通过init方法进行服务注入 调用方法形式如下 解决非controller类引用service问题 项目中遇到需要采用socket通信机制,由于这个方法没有写在控制类里面,调用service类的时候老是报java.lang.NullPointerException错误 解决办法 1.首先将@Autowired注解注入Service或者Mapper接口  @Au

  • springboot中的controller注意事项说明

    关于controller注意事项 spring boot的controller水深无比,经过学习,我总结一些tips,以便以后参照,减少错误: 1.controller主要有两个标签 @Controller和@RestController,两个标签无法同时发挥作用,前者标注的类只能返回静态文件,后者标注的类用于返回数据类型如json字符串 2.使用@Controller标签时 templates下的文件并不能被识别(自己试验过,发现和网上很多说法都不一样),只有static文件夹下文件能直接被读

  • 详解SpringBoot中Controller接收对象列表实现

    如果Spring Boot中对应的Controller要接收一个对象,该对象中又存放了一个List列表,那么页面该如何传递相关应的参数信息呢. 本篇文章给大家一个简单的示例,提供一种实现方式. 实体类 首先看实体类的结构(注意使用了Lombok): @Data public class Rules { private List<Rule> rules; } 对应Rule实体类代码如下: @Data public class Rule { /** * 类名 */ private String c

  • SpringBoot中打war包需要注意事项

    最近在做一个项目,遇到了项目打成 war 包的一个问题,项目创建时选择的时 jar 包方式,后因项目部署要求,需要打成 war 包部署,遇到很多坑,在此做一下记录 一.修改打包方式 原: <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> 改后: <version>0.0.1-SNAPSHOT</version> <packaging>war</p

  • 详解SpringBoot中异步请求和异步调用(看完这一篇就够了)

    一.SpringBoot中异步请求的使用 1.异步请求与同步请求 特点: 可以先释放容器分配给请求的线程与相关资源,减轻系统负担,释放了容器所分配线程的请求,其响应将被延后,可以在耗时处理完成(例如长时间的运算)时再对客户端进行响应.一句话:增加了服务器对客户端请求的吞吐量(实际生产上我们用的比较少,如果并发请求量很大的情况下,我们会通过nginx把请求负载到集群服务的各个节点上来分摊请求压力,当然还可以通过消息队列来做请求的缓冲). 2.异步请求的实现 方式一:Servlet方式实现异步请求

  • 关于springboot 中使用httpclient或RestTemplate做MultipartFile文件跨服务传输的问题

    大家好,因为近期做需求中遇到了文件上传这个东西,而且我这个还是跨服务去传输文件的所以我这边使用了httpclient和RestTemplate去做,但是最后还是用的httpclient.feign和RestTemplate在超大文件下会OOM所以适用于小文件传输我这边测试的在1G以下.httpclient好像是无限哈哈哈.(具体多少大家有时间可以去测一下) 1.被调用服务的Controller 1.这块使用@RequestParam("file")或者@RequestPart(&quo

  • 详解SpringBoot中实现依赖注入功能

    今天给大家介绍一下SpringBoot中是如何实现依赖注入的功能. 在以往spring使用中,依赖注入一般都是通过在Spring的配置文件中添加bean方法实现的,相对于这个方式SpringBoot的实现方式就显得非常便捷了.SpringBoot的实现方式基本都是通过注解实现的. 下面来看一下具体案例,这里我编写了三个测试类用于测试依赖注入到底是否可以正确实现. TestBiz接口: package example.biz; public interface TestBiz { public S

  • SpringBoot中自定义注解实现控制器访问次数限制实例

    今天给大家介绍一下SpringBoot中如何自定义注解实现控制器访问次数限制. 在Web中最经常发生的就是利用恶性URL访问刷爆服务器之类的攻击,今天我就给大家介绍一下如何利用自定义注解实现这类攻击的防御操作. 其实这类问题一般的解决思路就是:在控制器中加入自定义注解实现访问次数限制的功能. 具体的实现过程看下面的例子: 步骤一:先定义一个注解类,下面看代码事例: package example.controller.limit; import org.springframework.core.

  • SpringBoot中的Thymeleaf用法

    Thymeleaf Thymeleaf是最近SpringBoot推荐支持的模板框架,官网在thymeleaf.org这里. 我们为什么要用Thymeleaf来作为模板引擎呢?官网给了我们一个非常令人信服的解释: Thymeleaf is a modern server-side Java template engine for both web and standalone environments.> 基本写法就像下面这样: <table> <thead> <tr&g

  • 详解springboot中redis的使用和分布式session共享问题

    对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现session不同步或者丢失的问题. 实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat.Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中. 本文旨在

  • springboot 中文件上传下载实例代码

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. Spring Boot特点 1. 创建独立的Spring应用程序 2. 嵌入的Tomcat,无需部署WAR文件 3. 简化Maven配置 4. 自动配置Spr

随机推荐