处理提交出去的数据
ModelAndView
@RequestMapping("test3")
public ModelAndView test3(ModelAndView modelAndView) {
User user = new User(1212, "李四", "密码");
modelAndView.addObject("user", user);
modelAndView.setViewName("a");
return modelAndView;
}
ModelMap
@RequestMapping("test2")
public String test2(ModelMap modelMap) {
User user = new User(1212, "张飒", "密码");
modelMap.addAttribute("user", user);
return "a";
}
Model
@RequestMapping("test4")
public String test4(Model model) {
User user = new User(1212, "王五", "密码");
model.addAttribute("user", user);
return "a";
}
区别
- ModelAndView : 可以存储数据,也可以设置跳转的页面
- ModelMap : 继承了LinkedMap,有更强的功能
- Model : 只有几个方法,简单
@ModelAttribute
- 该注解可以使用在方法和方法参数上
注释在方法上
- 在同一个控制器中,注解了
@ModelAttribute
的方法实际上会在@RequestMapping
方法之前被调用
@Controller
public class UserController {
@RequestMapping("/test")
public void update() {
System.out.println("111111111");
}
@ModelAttribute
public void getStudent1() {
System.out.println("222222222");
}
}
无返回值注释在方法上
- 可以通过
@ModelAttribute
注释的方法较先执行的特性,使用Model对象设置参数 - 在控制器跳转的页面中可以取得 Model 中设置的参数
- 可以使用 @ModelAttribute 注释的方法来设置其他 @ReqeustMapping 方法的公用参数
@Controller
public class UserController {
@RequestMapping("/test")
public String test1() {
return "hh";
}
@ModelAttribute
public void test2(Model model) {
model.addAttribute("ooo","HELLO");
}
}
有返回值注释在方法上
- 没有返回值的使用Model对象model.addAttribute(String key, Object value);来设置参数
- 而有返回值的则需要直接返回参数即可,jsp使用${student}接收即可
@Controller
public class UserController {
@RequestMapping("/test")
public String update() {
return "hh";
}
@ModelAttribute
public Student getStudent1() {
return new Student(1,"张飒",18);
}
}
- 也可以给
@ModelAttribute
指定一个name,在jsp页面使用指定的name取值
@ModelAttribute 和 @RequestMapping 注解在同一个方法上
- 如果 @ModelAttribute 和 @RequestMapping 注解在同一个方法上,那么代表给这个请求单独设置 Model 参数
- 此时返回的值是 Model 的参数值,而不是跳转的地址
- 跳转的地址是根据请求的 url 自动转换而来的,就是@RequestMapping()中的参数
@ResponseBody
- 只能作用在方法和类上
- @ResponseBody的作用其实是将java对象转为json格式的数据
- 在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据
- 一般用于ajax异步请求数据
@RequestMapping("test1")
@ResponseBody
public String tets1(){
return "OK";
}
@RequestMapping("test2")
public @ResponseBody User test2(){
return new User("陌路邑人","mlyr",new Date());
}
@RequestMapping("test3")
@ResponseBody
public List<User> test3(){
User user = new User("???","1515",new Date());
User user2 = new User("###","212",new Date());
List<User> list = new ArrayList<>();
list.add(user);
list.add(user2);
return list;
}
但是,有个问题,当对象有时间类型的时候,他会把Date类型的数据转换为时间戳传出去
解决时间被转换为时间戳
第一种方式:@JsonFormat
- 在实体类上加上
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private String pwd;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
}
-
但是他需要
jackson-databind
依赖 -
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.1</version> </dependency>
第二种方式:全局配置
- 和第一种一样,都需要
jackson-databind
依赖
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描指定包下加有注解的放入spring容器中-->
<context:component-scan base-package="com.mlyr.k"/>
<mvc:annotation-driven>
<!--配置消息转换器器-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<!--配置日期json转换-->
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
- 这种的还有一种写法,自定义消息转换器
public class UserHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
//当前的转换器支持转换的类
@Override
protected boolean supports(Class<?> clazz) {
if (clazz == UserController.class) {
return true;
}
return false;
}
//用于或取数据调用
@Override
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
//用于输出数据调用
@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//获取输出流
OutputStream body = outputMessage.getBody();
//配置日期转换器
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
objectMapper.writeValue(body,obj);
}
}
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.mlyr.l"/>
<mvc:annotation-driven>
<!--配置消息转换器-->
<mvc:message-converters register-defaults="true">
<!--自定义的信息转换器-->
<bean class="com.mlyr.l.UserHttpMessageConverter">
<!--转换器支持的格式-->
<property name="supportedMediaTypes" >
<list>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
乱码处理
- 在web.xml中添加,字符编码
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 大佬写的全局乱码解决
package com.mlyr;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
/**
* @Description:
* @Author: 陌路邑人
* @CreateTime: 2021/3/3
* @Company:
*/
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse
response, FilterChain chain) throws IOException, ServletException {
//处理response的字符编码
HttpServletResponse myResponse = (HttpServletResponse) response;
myResponse.setContentType("text/html;charset=UTF-8");
// 转型为与协议相关对象
HttpServletRequest httpServletRequest = (HttpServletRequest)
request;
// 对request包装增强
HttpServletRequest myrequest = new
MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws
ServletException {
}
}
//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
//是否编码的标记
private boolean hasEncode;
//定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
public MyRequest(HttpServletRequest request) {
super(request);// super必须写
this.request = request;
}
// 对需要增强方法 进行覆盖
@Override
public Map getParameterMap() {
// 先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post请求
try {
// 处理post乱码
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get请求
Map<String, String[]> parameterMap =
request.getParameterMap();
if (!hasEncode) { // 确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 处理get乱码
values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
//取一个值
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回参数的第一个值
}
//取所有值
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
- 在web.xml中配置过滤器即可
<filter>
<filter-name>myFiter</filter-name>
<filter-class>com.mlyr.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFiter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>