SpringMVC学习笔记(2)

请求参数绑定、响应数据和结果类型

一、请求参数绑定

处理提交数据

提交数据:http://localhost:8080/index.jsp?username=zhangsan&password=123

处理方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//使用Servlet原生API实现
@RequestMapping("/g1")
public String getParam1(HttpServletRequest request, Model model) {
String username = request.getParameter("username");
String password = request.getParameter("password");
String msg = username + ":" + password;
model.addAttribute("msg", msg);
return "hello";
}

//使用同名匹配规则
@RequestMapping("g2")
public String getParam2(String username, String password, Model model) {
String msg = username + ":" + password;
model.addAttribute("msg", msg);
return "hello";
}

//提交的参数名称和处理方法的参数名不一样
@RequestMapping("g3")
public String getParam3(@RequestParam("username") String name, @RequestParam("password") String password, Model model) {
String msg = name + ":" + password;
model.addAttribute("msg", msg);
return "hello";
}

//提交的是一个对象
//前端传递的参数名必须和对象名一致,否则为null
@RequestMapping("g4")
public String getParam4(User user) {
System.out.println(user);
return "hello";
}

//实体类
public class User {
private String username;
private String password;
/*getter and setter*/
}

请求参数绑定集合类型

List:表单里的name写 list[i].属性

Map:name写 map[‘key’].属性

自定义类型转换器

​ 如果字符串是2021-4-14这样的类型。SpringMVC不能自动进行类型转换,需要自定义类型转换器。

​ 写一个类实现 org.springframework.core.convert.converter.Converter 接口,并且实现 convert 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class StringToDateConverter implements Converter<String, Date> {
/**
* 字符串转成日期
* @param source 传进来的字符串
* @return date日期对象
*/
@Override
public Date convert(String source) {
if (source.isEmpty()) {
return null;
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
//把字符串转成日期
return df.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}

​ 在springmvc.xml注册自定义类型转换器

1
2
3
4
5
6
7
8
9
<!--配置自定义类型转换器-->
<bean class="org.springframework.context.support.ConversionServiceFactoryBean"
id="conversionService">
<property name="converters">
<set>
<bean class="com.hzj.utils.StringToDateConverter"/>
</set>
</property>
</bean>

二、响应数据和结果类型

转发和重定向

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping("/f1/t2")
public String test2() {
//转发 路径必须写成实际视图 url,不能写逻辑视图。
return "forward:/WEB-INF/jsp/test.jsp";
}

@RequestMapping("/f1/t3")
public String test3() {
//重定向 jsp 页面不能写在 WEB-INF 目录中,否则无法找到。
return "redirect:/index.jsp";//不用加项目名
}

数据显示到前端

第一种:通过ModelAndView

1
2
3
4
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response){
//返回一个模型视图对象
return new ModelAndView("test");
}

第二种:通过ModelMap

1
2
3
4
5
6
7
8
@RequestMapping("/hello")
public ModelAndView handleRequest(ModelMap modelMap){
//封装要显示到视图中的数据
//相当于request.addAttribute
modelMap.addAttribute("attributeName","attributeValue");
//返回一个模型视图对象
return new ModelAndView("test");
}

第三种:通过Model

1
2
3
4
5
6
7
8
@RequestMapping("/hello")
public ModelAndView handleRequest(Model model){
//封装要显示到视图中的数据
//相当于request.addAttribute
model.addAttribute("attributeName","attributeValue");
//返回一个模型视图对象
return new ModelAndView("test");
}

对比

  • Model 只有几个方法只适合于储存数据,简化了对Model对象的操作
  • ModelMap 继承了LinkedMap,除了自身实现了的一些方法,同样的继承LinkedMap的方法和特性
  • ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转

返回值分类

字符串

controller 方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

指定逻辑视图名,经过视图解析器解析为 jsp 物理路径:/WEB-INF/pages/success.jsp

void

1
2
3
4
5
6
7
8
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("testVoid执行了");
//请求转发
request.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(request, response);
//重定向
response.sendRedirect(request.getContextPath() + "/a.jsp");
}

ModelAndView

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
//创建ModelAndView对象
ModelAndView mv = new ModelAndView();
User user = new User("张三","123",12);
mv.addObject("user",user);
//要跳转的页面名字 会经过视图解析器
mv.setViewName("test");
return mv;
}

JSON

  • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。

要求和语法格式:

  • 对象表示为键值对,数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let user = {
name: "张三",
age: 3,
sex: "男"
}

//将JavaScript对象转换为JSON对象
let json = JSON.stringify(user);
console.log(json);
//控制台输出
//{"name":"张三","age":3,"sex":"男"}

//将JSON对象转换为JavaScript对象
let obj = JSON.parse(json);
console.log(obj);
//控制台输出
/*{name: "张三", age: 3, sex: "男"}
age: 3
name: "张三"
sex: "男"
__proto__: Object*/

ResponseBody响应json数据

  • 导入Jackson依赖
1
2
3
4
5
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.2</version>
</dependency>
  • 前端页面脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(function () {
$("#btn").click(function () {
// 发送ajax请求
$.ajax({
url: "testAjax",//请求路径
method: "POST",//请求方式
contentType: "application/json; charset=utf-8",
data: JSON.stringify({username: "jack", password: "123", age: 23}),
success: function (data) {//响应成功后的回调函数
$("#msg").html(data.username + "," + data.password + "," + data.age);
},
dataType: "json"//设置接收到的响应数据的格式
});
});
});
  • 对应的Controller
1
2
3
4
5
6
7
8
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax方法执行了...");
System.out.println(user);
user.setUsername("张三");
user.setAge(3);
return user;
}

@RestController 注解的类,该类下所有方法都不会走视图解析器。

@ResponseBody 注解的方法,该方法不会走视图解析器,会直接返回一个字符串。

乱码优化

  • 解决中文乱码: @RequestMapping 注解改为
1
@RequestMapping(value = "/testAjax",produces = "application/json;charset=UTF-8")

乱码统一解决

  • 在springmvc.xml中配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

FastJSON

  • 导入fastjson依赖
1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>

fastjson三个主要的类

  • [JSONObject代表json对象]

    • JSONObject实现了Map接口,猜想JSONObject底层操作是由Map实现的。
    • JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利
      用诸如size(),isEmpty()等方 法获取”键:值” 对的个数和判断是否为空。其本质是通过实现
      Map接口并调用接口中的方法完成的。
  • [JSONArray代表json对象数组]

    • 内部是有List接口中的方法来完成操作的。
  • [JSON代表JSONObject和JSONArray的转化]

    • JSON类源码分析与使用
    • 仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象, json字符串之间
      的相互转化。
  • Copyrights © 2020-2023 夕子学姐
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信