数据输出
将数据传输给页面
新项目的环境
新建一个工程moudle,创建一个demo测试一下环境是否正常
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--contextConfigLocation:指定SpringMVC配置文件位置
classpath:路径下的文件地址
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 字符编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--encoding:指定解决POST请求乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<!--顺手解决响应乱码-->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.jiang"></context:component-scan>
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
com.jiang.controller.HelloController
package com.jiang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Title:
* @author: JiangPeng
*/
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.println("Hello");
return "hello";
}
}
剩下的就是web-inf/pages/hello.jsp......
原生API输出
SpringMVC可以在参数上写原生API
- HttpServletRequest
- HttpSession
- HttpResponse
- Locale:国际化有关的区域信息对象
- InputStream、OutputStream、Reader、Writer
@RequestMapping("/handle03")
public String handle03(HttpSession session, HttpServletRequest request){
request.setAttribute("reqParam","我是请求域中的");
session.setAttribute("sessionParam","我是session域中的");
return "hello";
}
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
请求:${requestScope.reqParam}
session:${sessionScope.sessionParam}
</body>
</html>
Map、Model、ModelMap
在方法处传入Map、Model、或者ModelMap给这些参数
保存的所有数据都会放在域中
Map
@RequestMapping("/handle01")
public String handle01(Map<String,Object> map){
map.put("msg","hello你好");
return "hello";
}
我们测试在hello页面中能获取到哪些数据
pageContext:${pageScope.msg}<br>
request:${requestScope.msg}<br>
session:${sessionScope.msg}<br>
application:${applicationScope.msg}<br>
最终我们可以看到只有request域中获取到了数据:
pageContext:
request:hello你好
session:
application:
Model
@RequestMapping("/handle02")
public String handle02(Model model){
model.addAttribute("msg","model你好");
return "hello";
}
通过Model对象 来传递参数
在网页中仍然只能request域获取到
pageContext:
request:model你好
session:
application:
ModelMap
@RequestMapping("/handle03")
public String handle03(ModelMap modelMap){
modelMap.addAttribute("msg","modelmap你好");
return "hello";
}
仍然是只能request域获取到
pageContext:
request:modelmap你好
session:
application:
总结
- Map是Jdk中的接口
- Model是Spring中的接口
- ModelMap是一个类,但是来自Map
- 他们三个最终的实现都是 BindingAwareModelMap,所以结果也一样
ModelAndView
方法的返回值可以变为ModelAndView类型:
既可以包含视图信息(页面地址)也包含模型数据(给页面带的数据)
而且数据是放在请求域中的。
@RequestMapping("/handle04")
public ModelAndView handle04(){
// 之前我们return的叫viewName视图名,视图解析器会帮我们拼串得到最后的真实地址
// 现在我们是通过new ModelAndVie(”viewName“) 在viewName中写入我们之前return的字符串,即视图名
ModelAndView mv = new ModelAndView("hello");
mv.addObject("msg","hellomodelandview");
return mv;
//或者你也可以不通过有参构造传入viewName而是无参构造
ModelAndView mv = new ModelAndView();
mv.setViewName("hello");
mv.addObject("msg","hellomodelandview");
return mv;
}
运行后还是在request域中有数据
@SessionAttributes
给session域中保存数据
@SessionAttributes(value = {"msg","msg1"},types={String.class})
@Controller
public class OutputController {
@RequestMapping("/handle04")
public ModelAndView handle04(){
ModelAndView mv = new ModelAndView("hello");
mv.addObject("msg","hellomodelandview");
return mv;
}
}
本来只有request中有数据,我们在控制类中加上@SessionAttributes注解以后就可以给session域中获取数据
@SessionAttributes(value = "msg")
- 在给 BindingAwareModelMap保存的数据,同时给session中保存一份
- value指定的是保存数据时要给session存放的数据的key
- types是指定什么类型的数据保存,此时只要value是String类型的都保存到Session
但是@SessionAttributes不推荐使用,可能会有异常。
如果想给session保存数据还是推荐原生API
@ModelAttribute
在以前的hibernate使用,现在已经用mybatis不用这个了,不做笔记了
视图解析
相对路径访问页面
@RequestMapping("/hello")
public String hello(Model model){
model.addAttribute("msg","helloView");
return "hello";
}
我们在hello请求中 最后的页面会自动拼上前缀和后缀 /WEB-INF/pages/hello.jsp
那么假设我此时需要访问我项目根路径下的hello.jsp怎么访问?
就是通过../返回上一级,那么因为WEB-INF/pages是两个目录 所以需要 ../../hello
forward转发页面
@RequestMapping("/hello")
public String hello(Model model){
model.addAttribute("msg","helloView");
return "forward:/hello";
}
- forward:转发一个页面
- /hello.jsp:转发到当前项目下的hello.jsp,如果不加/就是相对路径转发,容易出问题
- 有前缀的返回值独立解析,不给你拼串
redirect重定向
@RequestMapping("/hello")
public String hello(Model model){
model.addAttribute("msg","helloView");
return "redirect:/hello.jsp";
}
- redirect:重定向的路径
- /hello.jsp代表的是从当前项目下开始,SpringMVC会自动拼接上项目名
- 原生的servlet重定向需要手动添加项目名
处理Json
@ResponseBody
导入jackson的包
@ResponseBody
@RequestMapping("/getJson")
public Collection<Employee> ajaxGetAll(){
Collection<Employee> all = employeeDao.getAll();
return all;
}
- @ResponseBody:响应体。
- 将返回的数据放在响应体中,如果是对象,自动将对象转换为json格式
@JsonIgnore
返回的json数据中,如果有的数据我不想让他返回就是用该注解
@JsonIgnore
private Department department;
那么我们在返回的Json数据中,就不会有该属性的json数据@
@JsonFormat
在Date上加该注解,自动帮我们转换成我们可以理解的日期格式
@JsonFormat(pattern="yyyy-MM-dd")
private Date birth = new Date();