一、SpringMVC数据响应:响应
01-SpringMVC数据响应方式(理解)
1) 页面跳转
直接返回字符串
通过ModelAndView对象返回
2) 回写数据
直接返回字符串
返回对象或集合
02-返回字符串形式(应用)
请注意:
最下面的转发和重定向不是同一个index。
转发的index是在WEB-INF目录下,该目录不能够被外部访问,所以使用重定向也不行(重定向本质就是客户端访问的路径)
重定向的index是在web的根目录下的,也就是webapp目录下。
03、返回ModelAndView形式1(应用)
在Controller中方法返回ModelAndView对象,并且设置视图名称
public class UserController {
/**
* Model:模型(封装数据)
* View:视图(展示数据)
*/
@RequestMapping("/quick2")
public ModelAndView save2() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username","LiZhiXi"); //相当于request.setAttribute(键值对)
modelAndView.setViewName("success");//指定显示的页面(前后缀被配置了)
return modelAndView; //返回页面(View)
}
04、返回ModelAndView形式2(应用)
@RequestMapping("/quick3")
public ModelAndView save3(ModelAndView modelAndView ) {//springMVC帮你注入该对象引用
modelAndView.addObject("username","LiZhiXi");
modelAndView.setViewName("success");
return modelAndView; //返回页面(View)
}
/**
*将Model和View分开展示
*/
@RequestMapping("/quick4")
public String save4(Model model) {//Model
model.addAttribute("username","LiZhiXi"); //相当于request.setAttribute(键值对)
return "success"; //返回页面(View)
}
=========================不常用↓=================================
@RequestMapping("/quick5")
public String save5(HttpServletRequest request) {//springMVC帮你封装
request.setAttribute("username","LiZhiXi");
return "success"; //返回页面
}
05、响应数据乱码问题
produces :指定响应数据的格式,同时也可以设置数据编码。
(有点像response的乱码设置)
@RequestMapping(value = "/save",produces = "text/html;charset=utf-8")
@ResponseBody
private String save(Account account){
accountService.save(account);
return "保存成功";
}
二、SpringMVC数据响应:回写数据
1、直接返回字符串
①普通字符串
@RequestMapping("/quick6")
@ResponseBody //告诉SpringMVC不要进行视图跳转,直接回写响应体(响应体就是html正文)
public String save6(HttpServletRequest request) {//springMVC帮你封装
return "hello world"; //返回页面
}
=========================不常用↓=================================
@RequestMapping("/quick7")
public void save7(HttpServletResponse response) throws IOException {//springMVC帮你封装
response.getWriter().print("hello world");
}
②SpringMVC返回原始json字符串
在①中,返回的是简单的字符串,但是在实际开发当中,我们一般是将对象or集合 转换成 json格式的字符串 再回写给Ajax异步。
1、pom.xml导包
字符串转json格式的工具
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
2、Controller
注意提示:
这个被转换的对象(User)必须提供get方法,因为ObjectMapper翻译中文是“对象映射”,映射什么?将User对象的键值对属性映射到json格式字符串。
@RequestMapping("/quick8")
@ResponseBody
public String save8() throws JsonProcessingException {
User user = new User();
user.setName("刘德华");
user.setAge(30);
//创建工具类
ObjectMapper mapper = new ObjectMapper();
//将对象转换成json
String json = mapper.writeValueAsString(user);
return json;
}
输出:
"{\"name\":\"刘德华\",\"age\":30}"
2、SpringMVC返回对象or集合:1
SpringMVC中的适配器已经有提供给我们把对象or集合转json字符串的方法。我们只要在SpringMVC.xml配置一下适配器的转换参数
,并使用@ResponseBody
(告诉SpringMVC我是回写字符串,不是跳转视图
)
这样子return对象or集合就相当于回写了json格式的字符串。
好,我们看到配置Bean的时候看到是property,说明这是这个类的属性,我们点击查看一下适配器的方法:
输出:
{"name":"张学友","age":34}
2、SpringMVC返回对象or集合:2
(springmvc.xml)
记得写mvc命名空间
所以,以后配置springmvc.xml记得第一时间去配置这个:
当然,这个注解驱动还有其他的作用,反正好处多多,这里就不啰嗦了,上文有写。
所以,以后配置springmvc.xml记得第一时间去配置这个。
知识总结
三、SpringMVC获得请求数据
0、简介
1、获得基本类型参数
浏览器:
http://localhost/user/quick10?username=刘德华&age=11
controller:
@RequestMapping("/quick10")
@ResponseBody
public void save10(String username,int age) throws Exception {//请求参数值实际上是string类型的,但是SpringMVC可以帮我们转
System.out.println("username:"+username);
System.out.println("age:"+age);
}
输出:
username:刘德华
age:11
2、获得POJO类型参数
以前通过getPrimaterMap将空的User传进BeanUntils进行封装User的属性,但是这些都被SpringMVC底层封装了。
浏览器:
http://localhost/user/quick10?username=刘德华&age=11
controller:
@RequestMapping("/quick11")
@ResponseBody
public void save11(User user) throws Exception {//获取请求参数,并将参数值的Key与Bean的属性进行映射封装(setxxx)
System.out.println(user);
}
输出:
User{username='刘德华', age=11}
3、获得数组类型参数
为什么要使用Arrays.asList?
因为数组直接打印是地址,集合是值。
首先,该方法是将数组转化为list。有以下几点需要注意:
(1)该方法不适用于基本数据类型(byte,short,int,long,float,double,boolean)
(2)该方法将数组与列表链接起来,当更新其中之一时,另一个自动更新
(3)不支持add和remove方法
4、获得集合类型参数
1、自定义POJO:用来封装User的集合
public class VO {
private List<User> userList;
//get、setxxx
//toString
2、浏览器请求
<body>
<form action="${pageContext.request.contextPath}/user/quick12" method="post">
<input type="text" name="userList[0].username"> <!--userList是VO实体类的属性,框架通过VO的setxxx找到封装List<User>集合,list[0]代表第一个User对象,User.username = 值-->
<input type="text" name="userList[0].age">
<input type="text" name="userList[1].username">
<input type="text" name="userList[1].age">
<input type="submit" value="提交">
</form>
</body>
3、controller代码
@RequestMapping("/quick12")
@ResponseBody
public void save12(VO vo) throws Exception {//获取请求参数,并将参数值的Key与Bean的属性进行映射封装(setxxx)
System.out.println(vo);
}
4、输出
VO{userList=[User{username='wewqe', age=234324}, User{username='erfdxs', age=343}]}
5、获得集合类型参数:@RequestBody
①Springmvc.xml开放资源访问权限
<!--放行访问web应用资源限制-->
<mvc:resources mapping="/js/**" location="/js/"/>
②浏览器ajax请求
这里的ajax发送请求的请求参数是json类型的字符串
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
<script>
var userList = new Array();//创建数组
userList.push({username:"刘德华",age:11});//存储对象
userList.push({username:"张学友",age:12});
$.ajax({
type:"POST", //请求方式
url:"${pageContext.request.contextPath}/user/quick13", //请求路径
data:JSON.stringify(userList), //请求参数(将数组格式设置为json字符串格式)
contentType:"application/json;charset:utf-8" //设置服务器响应的数据类型
})
</script>
JSON.stringify()的作用是将 JavaScript 对象转换为 JSON 字符串,而JSON.parse()可以将JSON字符串转为一个对象
③controller
@RequestMapping("/quick13")
@ResponseBody
public void save13(@RequestBody List<User> userList) throws Exception {//使用@RequestBody不需要自定义POJO,可以直接封装User进集合
System.out.println(userList);
}
6、开放资源访问
springmvc.xml
<!--放行访问web应用资源限制-->
<!--①-->
<mvc:resources mapping="/js/**" location="/js/"/><!--mapping:表示浏览器访问的映射地址;location:表示存放映射资源的实际位置-->
<mvc:resources mapping="/img/**" location="/img/"/>
<!--②-->
<mvc:default-servlet-handler/>
<!--表示SpringMVC帮你找资源,找不到就交给默认的servlet去访问静态资源。(这个默认servlet不管你配不配置Tomcat都会创建,只是映射url没有设置)-->
为什么如果我们不开放资源,资源就访问不到呢?
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>【缺省】
</servlet-mapping>
springMVC的整个架构控制器就是前段控制器。
而,问题就出在前端控制器的配置的访问url的映射上:
缺省设置,前端控制器会拦截所有的请求,都把它们当做controller的方法来处理,没有这个controller方法就404。
啰嗦的解析:
当我们访问服务器的时候,它会先默认去寻找内部的servlet,但是我们使用SpringMVC不用servlet,而是使用前端控制器(也是servlet)。既然servlet没有,那就找前端控制器吧,而且你前端控制器配置访问资源路径是【缺省:意味着所有资源都可以访问到】,然后,前端控制器以为
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js">
${pageContext.request.contextPath}/js/jquery-3.3.1.js中pageContext.request.contextPath}/js/jquery-3.3.1.js是【虚拟路径(服务器)/虚拟路径(请求映射注解)/jquery-3.3.1.js的资源】即,controller中的方法名。
发现没有这个映射的controller方法就显示404.
解决:
<mvc:resources mapping="/js/**" location="/js/"/>
表示:默认寻找servlet发现没有,再去这个映射地址去寻找,没有去前端控制器寻找<mvc:default-servlet-handler/>
表示:SpringMVC帮你找资源,找不到就交给Tomcat服务器(Tomcat容器内找)
7、解决Post获取请求参数中文乱码
Web.xml配置解决乱码的拦截器
<!--配置拦截器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param><!--服务器初始化创建该对象-->
<param-name>encoding</param-name><!--CharacterEncodingFilter的属性名-->
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern> <!--表示拦截所有资源-->
</filter-mapping>
8、参数绑定注解@RequestParam
还有什么功能?
9、获得Restful风格的参数
10、自定义类型转换器
代码演示:
controller:
@RequestMapping("/quick15")
@ResponseBody
public void save15(Data data) {
System.out.println(data);
}
自定义转换器:
public class DateConverter implements Converter<String, Date> {//泛型:<被转换的类型,需要转换的类型>
@Override
public Date convert(String dateStr) {
//将日期字符串 转换成 日期对象
SimpleDateFormat format = new SimpleDateFormat(dateStr);
Date date = null;
try {
date = format.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
浏览器访问:【报错:2018-01-11格式错误】
http://localhost/user/quick15?date=2018-01-11
Springmvc.xml
<!--mvc的注解驱动-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!--声明类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters"><!--设置属性-->
<list>
<bean class="com.itheima.converter.DateConverter"/> <!--叫工厂Bean帮我造个自定义转换器-->
</list>
</property>
</bean>
浏览器访问:【成功获取:2018-01-11】
http://localhost/user/quick15?date=2018-01-11
11、获取Servlet相关的API
12、获取请求头
User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Cookie:
Idea-f60c4641=0293363a-894e-42ad-aa82-7c5d82a075c1;
Idea-661643a5=84c5cb46-98ab-4a2e-86d7-57484c264c08;
JSESSIONID=726F5BD7C7DA3F6B2675CEFB9188F66C
获取Cookie不是获取Cookie冒号后面的所有,而是指定Cookie冒号后面的键值对。
比如:获取JSESSIONID的键,返回726F5BD7C7DA3F6B2675CEFB9188F66C