5、数据传输
5.1、接收前端数据
1)参数名一致
提交的参数名和处理方法中的参数名一致,都是name
提交数据 : http : //localhost:8888/mvc_05/user/t1?name=hello
处理方法 :
@Controller
@RequestMapping(value = "/user")
public class ParameterController {
@RequestMapping("/t1")
public String test1(String name){
System.out.println("接收到的数据:"+name);
return "hello";
}
}
后台:接收到的数据:hello
- RestFul风格
2)参数名不一致
提交数据 : http : //localhost:8888/mvc_05/user/t3?username=hello
处理方法 :
@RequestMapping("/t3")
public String test3(String name){
System.out.println("接收到的数据:"+name);
return "hello";
}
后台:接收不到数据,显示name=null
;因为前台参数名是username
,后台是用name
接收,不一致;但不会报异常
解决方法:
-
@RequestParam("username")
在处理方法的参数名前加
@RequestParam(value = "username")
,其中value
可以省略,简写为@RequestParam("username")
,username
就是前端传递的参数名
@RequestMapping("/t4")
public String test4(@RequestParam(value = "username") String name){
System.out.println("接收到的数据:"+name);
return "hello";
}
-
@PathVariable("username")
RestFul风格
@RequestMapping("/t5/{username}")
public String test5(@PathVariable("username") String name){
System.out.println("接收到的数据:"+name);
return "hello";
}
3)接收对象
要求提交的参数名和对象的属性名一致,后台处理方法的参数使用对象即可
如果对象中的属性 匹配不到提交的参数,就为null或0(根据属性的类型)
不适合RestFul风格
- 实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private int age;
}
-
提交数据:http : //localhost:8888/mvc_05/user/t6?id=2&name=hello&age=8
-
处理方法:参数直接为对象
@RequestMapping("/t6")
public String test6(User user) {
System.out.println("接收到的数据:" + user);
return "hello";
}
- 后台:接收到的数据:User(id=2, name=hello, age=8)
5.2、向前端传输数据
1)ModelAndView
ModelAndView本身包含有视图
处理方法的返回类型必须为ModelAndView
方法内部定义ModelAndView,并返回
@RequestMapping("/t5/{username}")
public ModelAndView test5(@PathVariable("username") String name) {
System.out.println("接收到的数据:" + name);
ModelAndView mav = new ModelAndView();
mav.addObject("msg",name);
mav.setViewName("hello");
return mav;
}
2)ModelMap
ModelMap不包含视图
ModelMap从处理方法的参数中传入,不能在方法内自已定义;由框架底层对象创建,调用的是底层对象的重载方法;有put方法
处理方法返回类型为String,就是视图
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
@RequestMapping("/t7/{username}")
public String test7(@PathVariable("username") String name, ModelMap map) {
System.out.println("接收到的数据:" + name);
//ModelMap map = new ModelMap(); 不能自已定义
map.addAttribute("msg", name);
map.put("info", "Hello");
return "hello";
}
3)Model (建议使用)
与ModelMap类似;更简洁,没有put方法
@RequestMapping("/t8/{username}")
public String test8(@PathVariable("username") String name, Model model) {
System.out.println("接收到的数据:" + name);
model.addAttribute("msg", name);
model.addAttribute("info", "Hello");
return "hello";
}
5.3、乱码问题
1)产生原因
数据的发送端与接收端对数据的编码格式不一致
- form表单
<form action="${pageContext.request.contextPath}/e/t1" method="post">
<input type="text" name="name">
<input type="submit">
</form>
- 接收方法
@PostMapping("/e/t1")
public String test1(String name, Model model){
System.out.println(name);
model.addAttribute("msg",name);
return "hello";
}
2)解决方案
使用过滤器
配置过滤器时,使用
/*
,可以过滤所有路径,包括.jsp等;不要用/
,不能过滤.jsp等静态资源
(1)自定义过滤器
- EncodingFileter.java
public class EncodingFileter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
- web.xml中配置过滤器
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.tuwer.filter.EncodingFileter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<!--使用/*,可以过滤所有路径,包括.jsp等;不要用/,不能过滤.jsp等静态资源-->
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)使用SpringMVC过滤器
CharacterEncodingFilter
<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>
(3)使用通用过滤器
- GenericEncodingFilter.java
package com.tuwer.filter;
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;
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException, IOException {
//处理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>encoding</filter-name>
<filter-class>com.tuwer.filter.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>