SpringMVC数据处理
一、前段接受后端的数据输出
SpringMVC除了在方法上传入原生的request和session外还能怎么把数据带给页面。
1)可以在方法处传入Map、或者Model或者ModelMap。给这些参数里面保存的所有数据都会放在请求域(requestScope)中。可以在页面中获取。
pageContext: ${pageScope.msg}
request: ${requestScope.msg}
session: ${sessionScope.msg}
application: ${applicationScope.msg}
Map:
@Controller
public class helloController {
@RequestMapping("/handle01")
public String test01(Map<String, Object> map) {
map.put("msg", "你好");
return "/right.jsp";
}
}
right.jsp页面:
request: ${requestScope.msg}
Model:
这是一个接口
@RequestMapping("/handle02")
public String test02(Model model) {
model.addAttribute("msg", "你好坏!");
return "/right.jsp";
}
前端页面:
request: ${requestScope.msg}
ModelMap:
@RequestMapping("/handle03")
public String test03(ModelMap modelMap) {
modelMap.addAttribute("msg", "你真棒!");
return "/right.jsp";
}
request: ${requestScope.msg}
实际上这三种的类型都是差不多的,它们的所属类型都是BindingAwareModelMap。
相当于BindingAwareModelMap中保存的东西都会被放在请求域中;
Map(interface),这是jdk中的一个接口
Model(interface),这是Spring中的一个接口
ModelMap是一个类
它们之间的关系:
2)方法的返回值可以变为ModelAndView类型,获得的数据也是放在requestScope中:
@RequestMapping("/handle04")
public ModelAndView test04() {
//之前的返回值就就是视图名:视图名,视图解析器是帮忙拼串的
//也就是跳转的地址
ModelAndView mav = new ModelAndView("/right.jsp");
mav.addObject("msg", "你好哦!");
return mav;
}
或者:
@RequestMapping("/handle04")
public ModelAndView test04() {
//之前的返回值就就是视图名:视图名,视图解析器是帮忙拼串的
//也就是跳转的地址
ModelAndView mav = new ModelAndView();
mav.setViewName("/right.jsp");
mav.addObject("msg", "你好哦!");
return mav;
}
request: ${requestScope.msg}
把数据放在requestScope中,当页面请求一来,就可以直接从内存取出数据,请求一完,数据就没有了。
如果把数据放在sessionScope中,时间一长就会爆满。
把数据放到applicationScope中的话,不仅自己能够看到,别人也能够看到。
所以鉴于以上考虑,SpringMVC就把大部分的数据都放到了requestScope中。
3)SpringMVC提供了一种可以临时给sessionScope中保存数据的方式:
使用一个注解:@SessionAttributes,这个注解只能标注在类上面。
@SessionAttributes(value=”msg”):给BindingAwareModelMap及其ModelAndView中保存的数据,同时给sessionScope中也保存一份。
value指定保存数据时要给session中放的数据的key
types指定保存数据的类型
后面推荐@SessionAttributes就不要使用了,给session中放数据请使用原生API
@Controller
@SessionAttributes(value=“msg”)
//也可以设置多个值,SessionAttributes(value={”msg”, “info”}, types={String.class})
public class helloController
request: ${requestScope.msg}
session: ${sessionScope.msg}
4)ModelAttribute方法入参标注该注解之后,入参的对象就会放到数据模型中。
这个注解之后使用的机会也不多。
使用的场景:并不是全字段修改,只会修改部分字段。
1)不修改的字段可以在页面进行展示但是不要提供修改输入框。
2)为了简单,Controller直接在参数位置来写对象。
3)SpringMVC为我们自动封装对象(没有戴的值是null)
4)如果接下来调用了一个全字段更新的dao操作,会将其他的字段可能变为null
如何能保证全字段更新的时候,只更新了页面携带的数据。
1)修改dao,代价太大,不推荐
2)对象是如何封装的
1)SpringMVC创建一个对象。
2)将请求里面所有与改对象对应的数据一一设置过来。
所以SpringMVC要封装请求参数的对象不该是自己new出来的。而应该是从数据库中拿到的准备好的对象。
再来使用这个对象封装请求参数。
ModelAttribute注解的作用:
可以标在参数位置和方法位置。
如果是标在方法位置:这个方法就会提前于目标方法先运行。
如果是标在参数位置:目标方法就不会再新创建一个对象,而是用的之前保存的对象。
二、后端接受前端的数据进行处理
1.后端接受前端提交的表单
如果我们的请求参数是一个POJO
SpringMVC会自动地为这个POJO进行赋值
1)将POJO中的每一个属性,从request参数中尝试获取出来,并封装即可
2)还可以级联封装,属性的属性
<form action="updateBook" method="post">
<input type="hidden" name="id" value="100"/>
书名:三体;<br/>
作者:<input type="text" name="author"/><br/>
价格:<input type="text" name="price"/><br/>
库存:<input type="text" name="stock"/><br/>
销量:<input type="text" name="sales"/><br/>
<input type="submit" value="修改图书"/>
</form>
@RequestMapping("/updateBook")
public String updateBook(Book book) {
System.out.println("页面表单提交的信息:" + book);
//....之后的一系列操作
return "success.jsp";
}
级联封装:
<form action="/test/book" method="post">
<input type="hidden" name="id" value="100"/>
书名:三体;<br/>
作者:<input type="text" name="author"/><br/>
价格:<input type="text" name="price"/><br/>
库存:<input type="text" name="stock"/><br/>
销量:<input type="text" name="sales"/><br/>
<hr/>
省份:<input type="text" name="address.province"/><br/>
城市:<input type="text" name="address.city"/><br/>
街道:<input type="text" name="address.street"/><br/>
<input type="submit" value="修改图书"/>
</form>
@RequestMapping("/book")
public String testBook(Book book) {
System.out.println("提交过来的表单的信习是:" +book);
return "/success.jsp";
}
2.后端获取前端的请求URL中的信息
@PathVariable映射URL绑定的占位符
通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的参数中。
//路径上可以有占位符: 占位符语法就是可以在任意路径的地方写一个{变量名}
@RequestMapping("/user/{id}")
public String pathVariableTest(@PathVariable("id") String id) {
System.out.println("路径上的占位符是:" + id);
return "success.jsp";
}
3.后端获取请求中带有的参数
<a href="/handleTest01?username=goodone">handleTest01</a><br/>
@RequestMapping("/handleTest01")
public String handleTest01(String username) {
System.out.println("这个变量的值是 " + username);
return "/success.jsp";
}
默认方式获取请求参数:
直接给方法入参上写一个和参数名相同的变量,这个变量就来接受请求参数的值。
带了就是有值,没有就是null
4.使用@RequestParam(“user”)
<a href="/handleTest01?user=goodone">handleTest01</a><br/>
@RequestMapping("/handleTest01")
public String handleTest01(@RequestParam(“user”)String username) {
System.out.println("这个变量的值是 " + username);
return "/success.jsp";
}
注意如果是标注了@RequestParam的话,参数默认是必须要带的。
@RequestParam有三个参数:
value:指定要获取的参数的key
required:这个参数是否必须的
defaultValue:可以指定一个默认值
5.使用@RequestHeader可以获得请求头
<a href="/handleTest03">handleTest03</a><br/>
@RequestMapping("/handleTest03")
public String handleTest03(@RequestHeader("User-Agent")String userAgent) {
System.out.println("you are running handleTest03");
System.out.println("获取的请求头:" + userAgent);
return "/success.jsp";
}
同样的,如果@RequestHeader中没有这个请求头的话,就会报错。
value:指定要获取的参数的key
required:这个参数是否必须的
defaultValue:可以指定一个默认值
6.@CookieValue:获取某个Cookie的值
以前后去某个cookie:
Cookie[] cookies = request.getCookies();
for (Cookie c:cookies) {
if(c.getName().equals(“JSESSIONID”)) {
String cv = c.getValue();
}
}
在SpringMVC中:
<a href="/handleTest04">handleTest04</a><br/>
@RequestMapping("/handleTest04")
public String handleTest04(@CookieValue("JSESSIONID")String jid) {
System.out.println("cookie中的JESSIONID中的值:" + jid);
return "/success.jsp";
}
7.传入原生API
SpringMVC开放了原生API,可以直接在参数上 写原生的web API
HttpServletRequest、HttpSession
@RequestMapping("/handleTest05")
public String handleTest05(HttpSession session, HttpServletRequest request) {
request.setAttribute("reqParam", "我是请求域中的");
session.setAttribute("sessionParam", "我是Session域中的");
return "/success.jsp";
}
requestScope:${requestScope.reqParam}<br/>
session:${sessionScope.sessionParam}<br/>
常用的原生API接口:
HttpServletRequest、HttpServletResponse、HttpSession、Reader、Writer
Reader从request中拿到的字符流
Ajax:
<script>
$.get(“${ctp}/getstuinfo”, {lastName:”safefe”, agr:18});
</script>
public void doPost(HttpServletRequest request, HttpServletSession session) {
String lastName = request.getParameter(“lastName”);
String age = request.getParameter(“age”);
}
文件上传:
1.文件上传准备:enctype=”multipart/form-data”
2.导入jar包:fileupload, commons-io
3.只要SpringMVC配置文件中编写一个配置,配置文件上传解析器(MultipartResolver)
4.文件上传请求处理