yumuing博客:Java Golang springboot 后端微服务技术控

Spring Controller 基本认识及应用

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

测试代码

[hide]下载:https://wwrs.lanzouo.com/izYWq0prwjwb 密码:4xt1[/hide]

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@RequestParamname="username",required=false,defaultValue="test"@RequestParam(name="username",required=false,defaultValue="test"@RequestParam(name="username",required=false,defaultValue="test"Stringusername;
//第二种
@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"intuserId;

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

根据以上三个参数,我们就能够让一个 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 总结

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

出现原因:

错误效果如下:

访问页面显示

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: ]

解决方案:

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

找不到模板文件

控制台报错:

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

解决方案:

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »