SpringMVC笔记二

it2025-03-21  34

文章目录

一、SpringMVC参数的获取1.基本数据类型2.对象3.嵌套对象4.Servlet原生API和SpringMVC自带API5.获取格式不固定的数据类型:日期等6.数组的获取7.集合的获取8.包装集合的获取 二、SpringMVC响应的控制1.返回void2.返回String3.返回ModelAndView 三、Json数据的交互1.接收Json2.返回Json 四、RESTful风格1.简介2.使用案例

一、SpringMVC参数的获取

1.基本数据类型

使用案例:

@RequestMapping(value = "/list01.do") public String list01(int id, int sex, String name) { System.out.println(id); System.out.println(sex); System.out.println(name); System.out.println("方法已经被调用!"); return "success"; }

页面代码:

<form action="/list01.do" method="post"> <input name="id" value="1"><br> <input name="sex" value="1"><br> <input name="name" value="胡彦兵"><br> <input type="submit" value="submit"><br> </form>

说明:

1.方法声明的变量名要和前端页面传进来的参数名一致,否则获取不到

2.如果是可以不携带的参数,最好不要使用基本数据类型作为参数,因为基本数据类型无法为null,页面没有携带传入的时候无法解析,所以会报错,结果就是获取不到数据

2.对象

页面代码

<form action="/list02.do" method="post"> <input name="id" value="1"><br> <input name="uid" value="1"><br> <input name="name" value="胡彦兵"><br> <input type="submit" value="submit"><br> </form>

实体类

public class User { private int id; private int uid; private String name; //剩下的方法自己补全,不然要报错 }

使用案例

@RequestMapping(value = "/list02.do") public String list02(User user) { System.out.println(user); return "success"; }

说明:

由于Spring框架帮做了自动封装的事情,所以获取的时候只要获得相应的对象即可,但是要注意页面传入参数和实体类中参数的名字要一致,否则无法获得数据;

3.嵌套对象

页面代码

<form action="/list03.do" method="post"> <input name="id" value="1"><br> <input name="uid" value="1"><br> <input name="name" value="胡彦兵"><br> <input name="account.money" value="10000"> <input type="submit" value="submit"><br> </form>

实体类

public class User { private int id; private int uid; private String name; private Account account; //剩下的方法自己补全,不然要报错 } public class Account { private double money; }

使用案例

@RequestMapping(value = "/list03.do") public String list03(User user) { System.out.println(user); return "success"; }

4.Servlet原生API和SpringMVC自带API

API列表:

HttpServletRequest

HttpServletResponse

HttpSession

Writer

Reader

OutputStream

InputStream

Model

ModelAndView

ModelMap

获取方式:

​ 直接在方法声明上添加即可,因为这些API都是已经存在的对象,或者可以根据已经存在的对象获取,所以需要那个直接获取就好;

使用案例:

@RequestMapping("/request") public String request(HttpServletRequest request) { System.out.println("方法被调用!"); request.setAttribute("msg", "直接获取请求,添加数据到请求域"); return "list.jsp"; } @RequestMapping("/model") public String model(Model model) { System.out.println("方法被调用!"); model.addAttribute("msg", "model添加参数到请求域中"); return "list.jsp"; }

注意:

​ 1.无论你是那个model,利用这个model添加的参数都是添加到了请求域中,如果想要添加到会话域或者上下文域只能获取到对应的对象之后再去获取;

​ 2.model其实就是模型,也就是用来给请求域添加数据的;而View是页面,添加的参数是用来做跳转的;他们的对象都只有一个,或者说都是已经实例化好的被你调用了,他们两个组成了视图解析器,而渲染就是把model中的数据拿出来添加到view中的页面中,然后再由视图解析器把渲染好的页面返回给用户;

5.获取格式不固定的数据类型:日期等

概述:

之前我们说过如果想要获取数据,你可以直接在方法申明上直接写上就好,框架会通过getParamterMap获取所有的参数,然后根据你的参数名而把数据封装进去,但是有些数据的格式是不固定的,例如日期,所以想要获取到这样的数据类型就需要我们自定义参数类型转换器;

自定义类型转换器:

package com.ps.Converter; import org.springframework.core.convert.converter.Converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; //前面的表示要传入的参数类型,后面的表示要转换后的数据类型 public class DateConverter implements Converter<String, Date> { @Override public Date convert(String str) { SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); try { return sdf.parse(str); } catch (ParseException e) { e.printStackTrace(); return null; } } }

将自定义类型转换器配置到配置文件中:

<!--配置自定义类型转换器--> <bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="serviceFactoryBean"> <property name="converters"> <bean class="com.ps.Converter.DateConverter" id="dateConverter"></bean> </property> </bean> <!--必须配置这个,这个配置是让SpringMVC框架使用你的类型转换器,如果不这么写不会生效--> <mvc:annotation-driven conversion-service="serviceFactoryBean"></mvc:annotation-driven>

后台控制器:

@RequestMapping("/date") public String date(Date date, Model model) { //为什么还要格式化?这是因为如果不格式化,会使用Java默认是日期格式,为了方便观看所以选择这样 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); model.addAttribute("msg", sdf.format(date)); return "list.jsp"; }

6.数组的获取

后端控制器:

@RequestMapping("/array") public String array(String[] args, Model model) { System.out.println(Arrays.toString(args)); model.addAttribute("msg", Arrays.toString(args)); return "list.jsp"; }

页面代码:

<h1>array</h1> <form action="array" method="get"> <input type="text" name="args" value="1"><br> <input type="text" name="args" value="2"><br> <input type="text" name="args" value="3"><br> <input type="text" name="args" value="4"><br> <input type="submit" value="submit"> </form>

7.集合的获取

后端控制器:

@RequestMapping("/list") //由于SpringMVC本身不支持封装到集合中,如果想要实现只能使用@RequestParam注解 //name/value:用来配置请求参数的名字,也就是要和前端传入的参数名一致 //required:配置是否必须携带这个参数,默认是true也就是必须携带 public String list(@RequestParam List<String> args, Model model) { System.out.println(args.toString()); model.addAttribute("msg", args.toString()); return "list.jsp"; }

页面代码:

<h1>list</h1> <form action="list" method="get"> <input type="text" name="args" value="1"><br> <input type="text" name="args" value="2"><br> <input type="text" name="args" value="3"><br> <input type="text" name="args" value="4"><br> <input type="submit" value="submit"> </form>

8.包装集合的获取

后端控制器:

@RequestMapping("/accountList") public String accountList(Account account, Model model) { System.out.println(account.toString()); model.addAttribute("msg", account.toString()); return "list.jsp"; }

页面代码:

<h1>包装集合</h1> <form action="accountList" method="get"> <input type="text" name="list" value="1"><br> <input type="text" name="list" value="2"><br> <input type="text" name="list" value="3"><br> <input type="text" name="list" value="4"><br> <input type="text" name="userList[0].id" value="1"><br> <input type="text" name="userList[0].uid" value="2"><br> <input type="text" name="userList[1].id" value="3"><br> <input type="text" name="userList[1].uid" value="4"><br> <input type="submit" value="submit"> </form>

实体类:

public class User { private int id; private int uid; } public class Account { private List<String> list; private List<User> userList; }

二、SpringMVC响应的控制

1.返回void

概述:

​ 如果不返回任何参数,那么视图解析器会根据配置好的前缀和后缀以及这个方法的访问路径来进行拼接,拼接的结果作为参数返回给页面,而如果这个资源不存在就会报错404;

​ 所以,想要不报错,就只能选择servlet原生API返回一个正确的资源路径;

​ 但其实,不返回也可以,只要给这个方法加上@ResponseBody即可,这个注解的作用是,表示我的返回值不是页面,而是响应体中的数据,既然是void,那么就表示响应体没有返回值罢了;

配置代码:

@RequestMapping("/void") @ResponseBody public void returnVoid() { System.out.println("无返回值!"); } @RequestMapping("/void2") public void returnVoid2(HttpServletResponse response) throws IOException { System.out.println("无返回值!"); response.sendRedirect("list.jsp"); }

2.返回String

概述:

​ 返回String其实没有什么其他含义,要么就作为参数返回即使用@ResponseBody来使用,要么就返回页面信息,而这个就只简单描述返回页面信息的相关内容;

返回页面方式:

完整返回部分返回

部分返回:

即只返回页面的一部分内容,视图解析器再根据配置好的前后缀进行拼接,拼接后的结果就是完整的页面链接

完整返回:

完整返回是需要可以携带跳转类型的,在前面加上forward:或者redirect:进行选择跳转方式,需要注意的是如果选择这种方式必须携带跳转方式;

使用案例:

@RequestMapping("/String") public String returnString() { System.out.println("无返回值!"); return "redirect:/list.jsp"; } @RequestMapping("/String1") public String returnString1() { System.out.println("无返回值!"); return "forward:/list.jsp"; } @RequestMapping("/String2") public String returnString2() { System.out.println("无返回值!"); return "list"; }

配置文件内容:

<!--创建视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver"> <property name="suffix" value=".jsp"></property> <property name="prefix" value="/"></property> </bean>

3.返回ModelAndView

概述:

这个其实没什么好说的,就是返回视图解析器,通过视图解析器配置好需要配置的内容然后返回,如果你不想new,也可以使用参数直接接收;

使用案例:

@RequestMapping("/modelAndView") public ModelAndView returnMV(ModelAndView mv) { //配置返回到请求域中的参数 mv.addObject("msg", "model and view 返回"); //配置返回页面 mv.setViewName("list"); return mv; }

三、Json数据的交互

概述:

json是现在web段数据交互最常用的数据格式之一,而实际开发中也应该使用json来进行数据的交互,所以无论接收还是发送都应该选择json;

前提:

由于SpringMVC默认使用Jackson作为Json数据转换的工具,那么就需要导入对应的Jackson,否则无法解析和发送数据;

Jackson坐标:

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <!--由于我使用的SpringMVC版本是5.1.6,所以需要比较高的版本才能兼容--> <version>2.9.8</version> </dependency>

1.接收Json

前端页面:

<h1>Json</h1> <form id="jsonForm"> <input type="text" name="id" value="1"/> <input type="text" name="uid" value="2"/> <button type="button" onclick="jsonCommit()">提交</button> <div id="jsonRes"></div> </form> <script> function jsonCommit() { // 1. 创建异步请求对象 var req = new XMLHttpRequest(); // 2. 打开请求 req.open("POST", "Json", true); // 3. 设置请求的数据类型(必须) req.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); // 4. 异步读取响应 req.onreadystatechange = function () { // 2.1 判断响应状态 if (req.readyState == 4 || req.status == 200) { var data = req.responseText; document.getElementById("jsonRes").innerHTML = data; } }; // 5. 封装数据 var es = document.getElementById("jsonForm").getElementsByTagName("input"); var json = {}; for (var i = 0; i <= es.length; i++) { if (es[i] != undefined) { var name = es[i].name; var value = es[i].value; json[name] = value; } } // 6. 发送数据 var body = JSON.stringify(json); req.send(body); } </script>

后端控制器:

@RequestMapping("/Json") //因为我选择的是异步请求,所以要告诉浏览器不要页面跳转,我自己来,设置的参数为返回的数据内容 @ResponseBody //这个注解@RequestBody 是必须使用的,如果不适用SpringMVC框架不知道你要把数据封装进去,有了这个它会帮你把数据封装进去 public String Json(@RequestBody User user) { System.out.println(user.toString()); return user.toString(); }

总结:

需要使用:@RequestBody来告诉框架帮我们封装参数进去

2.返回Json

后端控制器代码:

@RequestMapping("/Json1") @ResponseBody public User Json1(@RequestBody User user) { return user; }

说明:

注解@ResponseBody在这里的作用是将user作为数据返回给页面,那么user是对象,所以会通过Jackson转成Json传递;

四、RESTful风格

1.简介

概述:

RESTful是一种url编码规范,主要作用就是让你使用不同的请求去做不同的事情,而对应到开发中就是让每个操作都有单独的URL可以使用;

增删改查传统/user/add/user/delete?id={id}/user/update?id={id}/user/get?id={id}RESTful/user POST/user/{id} DELETE/user/{id} PUT/user/{id} GET

特点:

url规范在url中可以绑定请求参数相同的url通过请求方式来区分

2.使用案例

前端代码:

<h1>POST请求</h1> <form method="post" action="user"> <input type="submit" value="submit"> </form> <h1>PUT请求</h1> <%--使用post请求封装put请求--%> <form method="post" action="user/1"> <%--这一行是规范,只能修改value的值--%> <input type="hidden" name="_method" value="PUT"> <input type="submit" value="submit"> </form> <h1>DELETE请求</h1> <%--使用post请求封装delete请求--%> <form method="post" action="user/1"> <%--这一行是规范,只能修改value的值--%> <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="submit"> </form>

后端控制器:

@RequestMapping(value = "/user",method = RequestMethod.POST) @ResponseBody public void save(){ System.out.println("save method"); } @RequestMapping(value = "/user/{id}",method = RequestMethod.GET) @ResponseBody //使用@PathVariable()来获取地址栏的参数 //如果注解中配置了参数名,那么必须和上面地址栏的参数名一致 //如果配置了参数名,那么方法声明中的参数就可以修改了 public void find(@PathVariable("id") int id){ System.out.println("find method"); } @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE) @ResponseBody public void delete(@PathVariable("id") int id){ System.out.println("delete method"); } @RequestMapping(value = "/user/{id}",method = RequestMethod.PUT) @ResponseBody public void update(@PathVariable("id") int id){ System.out.println("update method"); }

由于浏览器不支持,前端控制器无法解析,所以需要过滤器来解析并修改请求方式最终达到目的:

<!--配置请求过滤器,用于修改请求,使其访问到目标方法--> <filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
最新回复(0)