Spring Controller 基本认识及应用

简介: Controller 在 spring 中代表的是控制层,是将访问者请求进行分发调用不同函数,来控制获取请求参数以及返回业务层处理完的数据给访问者的层面。它在 spring 中必须在 Controll

👏 Hi! 我是 Yumuing,一个技术的敲钟人

👨‍💻 每天分享技术文章,永远做技术的朝拜者

📚 欢迎关注我的博客:Yumuing's blog

注:本文是以前初学时期的笔记上传,如有错误,还望指出,一定改正,谢谢支持!有兴趣也可以关注我的博客:yumuing 博客

Controller 相关介绍

Controller 在 spring 中代表的是控制层,是将访问者请求进行分发调用不同函数,来控制获取请求参数以及返回业务层处理完的数据给访问者的层面。它在 spring 中必须在 Controller 类前添加 @Controller 注解,以注入容器中,并发挥作用。

在 Controller 中存在两种传递参数的方式,第一种是采用路径后添加 ? 参数的方式,第二种则是采用参数直接写入路径的方式,如下:

第一种:yumuing/params?username=yumuing&password=1234

第二种:yumuing/user/{userId}

在 Get 请求中,获取第一种参数的方式,主要是利用 @RequestParam 这个注解得到同名的参数,获取第二种参数的方式则是采用 @PathVariable 这个注解获取 @RequestMapping 中的大括号标记的同名参数,其中,@RequestParam 和 @PathVariable 都是作为方法参数书写的,必须注明参数类型(如 String ),@RequestMapping 则是方法整体注解,在添加新参数时,路径得使用 path 进行指定,而不是一个简单的字符串书写即可,来如下:

//第一种
@RequestMappingpath="/params",method=RequestMethod.GETpath = {
   "/params"},method = {
   RequestMethod.GET}path="/params",method=RequestMethod.GET
public void params@RequestParam(name="username",required=false,defaultValue="test"@RequestParam(name = "username", required = false,defaultValue = "test"@RequestParam(name="username",required=false,defaultValue="test"String username);
//第二种
@RequestMappingpath="/user/userId",method=RequestMethod.GETpath = "/user/{userId}",method = {
   RequestMethod.GET}path="/user/userId",method=RequestMethod.GET
public void params@PathVariable("userId"@PathVariable("userId"@PathVariable("userId" int userId);

当然,@RequestMapping 的参数还有很多,但必须注意的一点是尽可能使用 大括号(即 {},会更加直观,也防止部分一定要求需要大括号的参数出错,并且这个注解既可以一个函数,也可以注解一个类。当注解一个类时,类中所有的方法都会在这个基础上再进行过滤,参数类型基本包括如下:

  • path:路径参数,书写格式参照 url 后缀格式的字符串(即 ”/yumuing/user“ )参数指定了访问该方法的具体路径,不指定参数名时,默认为填写内容为 path 的参数内容,path也可以是一个未定的变量。
  • method:访问方法参数,主要包括 Get(RequestMethod.GET)、Post(RequestMethod.POST)、Delete(RequestMethod.DELETE)、Put(RequestMethod.PUT)等等,都是调用的方式进行填写的。
  • params:请求参数,不可与 RequestParam 中的参数重复定义,会发生冲突,没有优先级之分。书写格式为字符串,如 ”yumuing“

根据以上三个参数,我们就能够让一个 controller 通过请求 url、参数、访问方法来进行区分并处理对应请求,并分别调用不同的函数,返回所需结果。

如果,想要在浏览器中进行简单的打印验证,可以考虑在对应 Controller 函数前添加 @RequestBody,并指定返回参数为 String ,它将会只打印返回的 String 数据,而不去进行渲染等等操作。如果,不使用 @RequestBody 即默认返回 HTML 数据。

当然,@RequestBody 也可以作为函数参数在将方法指定为只能使用 Post 请求之后,只接受请求体内容。与其不同的 @RequestParam,则是接收并解析请求体中以 key-value 格式的数据。两者可以同时使用,也可单独使用。

//打印示例
@RequestMapping("/hello")
@ResponseBody
public String hello() {
   
    return "hello";
}

返回的结果基本分为两种,一是数据,二是模板,数据可以是一个简单的 int 类型,也可以是 json 类型,乃至其他类型,而模板即是传递给浏览器渲染的 jsp、html 等等格式的内容。

在 thymeleaf 中,模板文件默认放在 resources/templates 中,可以存在子目录。模板文件基本配置如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <!-- xmlns:th="http://www.thymeleaf.org"设置读取该模板文件 -->
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
     <!--具体内容  -->
    <!-- 示例内容 -->
     <p th:text="${name}"></p>
     <p th:text="${age}"></p>
    <!-- th:text="${age}"匹配对应内容 -->
</body>
</html>

最终响应到浏览器的模板数据如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
  <p>hhhh</p>
  <p>30</p>
</body>
</html>

Controller 访问模板文件示例:

@RequestMapping(path = "/test",method = RequestMethod.GET)
public ModelAndView test(){
   
    ModelAndView mav = new ModelAndView();
    mav.addObject("name","hhh");
    mav.addObject("age",30);
    mav.setViewName("/demo/view");
    return mav;
}

@RequestMapping(path = "/test02",method = RequestMethod.GET)
public String test02(Model model){
   
    model.addAttribute("name","hhhh");
    model.addAttribute("age",30);
    return "/demo/view";
}

第一种是将 model 和 view 数据都装一个对象里,最后把两者一起返回,而第二种是将 model 放到参数里,把模板文件返回。从代码阅读来看,第二种更为简洁直观,更推荐使用。注意第一种使用的是 addObject(),第二种用的是 addAttrubute(),两种不可混用,并且注意第一种返回数据为 ModelAndView ,第二种返回数据为 String,当然,如果函数参数没有携带 org.springframework.ui.Model 的对象,将不会被识别为返回模板文件,而是返回字符串。

接下来,我们就介绍 json 数据是该怎么样去通过 Controller 传输的。它基本是发生在一次异步请求中的,也就是说,每次请求数据,返回模板数据,而是返回 json 数据,以浏览器更新已有的模板文件,不会导致每次请求的数据量传输过大,影响用户体验。

thymeleaf 模板引擎配合下,Controller 只添加 @RequestMapping 注解默认传输模板文件,当添加 @ResponseBody 后,我们就能传输 json 数据,当然,返回数据类型不能是 String 类型,否则,就只会打印,而不会转成 json 格式数据,并打印出来了。如下:

@RequestMapping(path = "/emp",method = RequestMethod.GET)
@ResponseBody
public Map<String,Object> getEmp(){
   
    Map<String,Object> emp = new HashMap<>();
    emp.put("name","张三");
    emp.put("age",16);
    emp.put("code",778522);
    return emp;
}

访问 localhost:8888/yumuing/emp ,返回数据并打印在浏览器数据如下:

{
   "code":778522,"name":"张三","age":16}

bug 总结

请求参数定义多次,无法访问

屏幕截图_20230203_212649

出现原因:

  • 在 @RequestMapping 中已经定义 params,又在 @RequestParam 中定义 params,导致出现错误。
  • 如果参数前写了@RequestParam(xxx),并且没有添加 require = false ,那么前端必须有对应的xxx名字才行,不然,就会发生错误。
  • @RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。否则也会发生错误。
  • 访问静态文件时,路径为放置在 resource/static 目录下的相对路径,如 test.html 文件在/resourse/static/html/test.html,路径即为 localhost:端口号/html/test.html,除非配置了全局url 前缀。

错误效果如下:

访问页面显示

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Feb 03 21:33:35 HKT 2023

There was an unexpected error (type=Bad Request, status=400).

控制台输出

2023-02-03T21:33:35.418+08:00  INFO 24684 --- [nio-8888-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-02-03T21:33:35.418+08:00  INFO 24684 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-02-03T21:33:35.418+08:00  INFO 24684 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
2023-02-03T21:33:35.430+08:00  WARN 24684 --- [nio-8888-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.UnsatisfiedServletRequestParameterException: Parameter conditions "username, password" not met for actual request parameters: ]

解决方案:

  • 第一种:删去 @RequestMapping 中多余的定义即可。
  • 第二种:要么添加 require = false ,要么请求添加对应参数,要么后端不加该参数
  • 第三种:使用 Post 请求,或者删去这个注解
  • 第四种:书写正确路径即可

注:System.out.printf() 为控制台输出,return、HttpServletResponse等等都是页面输出。

找不到模板文件

控制台报错:

Error resolving template template might not exist or might not be accessible;

解决方案:

  • 修改 application.yml 文件中的配置为:

    保证能够读取 html 文件,注意前有一英文半角 ”点“ ,设置 cache 为不缓存,保证实时修改,实时生效,生产环境推荐,方便调试,部署环境改为缓存型。设置文件路径,/templates 后不要加斜杆。

    spring:
      thymeleaf:
        suffix: .html
        encoding: utf-8
        mode: HTML5
        cache: false
        prefix: classpath:/template
    
  • 修改 Controller 函数访问模板路径为为相对路径,如:/demo/view ,记得最前面有斜杠,最后面没有斜杠,不需要写后缀名,默认 html

本文测试代码均在我的博客 Spring Controller 基本认识及应用获取

求点赞转发

目录
相关文章
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
158 1
|
27天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
100 62
|
25天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
25天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
44 2
|
2月前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
44 3
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第7天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建 Spring Boot 项目并配置 Spring Security。接着,实现后端 API 以提供菜单数据。在前端部分,使用 Ant Design Pro Vue 脚手架创建项目,并配置动态路由和菜单。最后,启动前后端服务,实现高效、美观且功能强大的应用框架。
49 2
|
2月前
|
人工智能 缓存 Java
深入解析Spring AI框架:在Java应用中实现智能化交互的关键
【10月更文挑战第12天】Spring AI 是 Spring 框架家族的新成员,旨在满足 Java 应用程序对人工智能集成的需求。它支持自然语言处理、图像识别等多种 AI 技术,并提供与云服务(如 OpenAI、Azure Cognitive Services)及本地模型的无缝集成。通过简单的配置和编码,开发者可轻松实现 AI 功能,同时应对模型切换、数据安全及性能优化等挑战。
120 3
|
2月前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。
|
2月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
73 0
下一篇
无影云桌面