域对象共享数据

109 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情

域对象共享数据

使用ServletAPI向request域对象共享数据

跟Servlet的request作用域一样,不例举了

使用ModelAndView向域对象共享数据

ModelAndView中有Model和View功能,Model用于想请求域共享数据,View用于设置视图实现页面跳转

public class TestScopeController {
    @RequestMapping("/test/mav")
    public ModelAndView testMAV(){
        ModelAndView mav = new ModelAndView();
       //向请求域中共享数据
        mav.addObject("testRequestScope", "Hello,Sentiment!");
        //设置逻辑视图
        mav.setViewName("success");
        return mav;
    }
}

success.html

获取请求域的testRequestScope数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Success!</h1>
    <p th:text="${testRequestScope}"></p>
</body>
</html>

访问后的效果

Model、ModelMap、Map

三个用法差不多放到了一起

@RequestMapping("/test/model")
public String testModel(Model model){
    model.addAttribute("testRequestScope","Hello,Model!");
    return "success";
}
​
@RequestMapping("/test/modelMap")
public String testModelMap(ModelMap modelMap){
    modelMap.addAttribute("testRequestScope","Hello,ModelMap!");
    return "success";
}
​
@RequestMapping("/test/map")
public String testMap(Map<String,Object> map){
    map.put("testRequestScope","Hello,Map!");
    return "success";
}

三种方法其实都是基于BindingAwareModelMap类的

public class BindingAwareModelMap extends ExtendedModelMap {}
public class ExtendedModelMap extends ModelMap implements Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{}

BindingAwareModelMap继承ExtendedModelMapExtendedModelMap中继承了ModelMap并实现了Model,而ModelMap继承于LinkedHashMap,LinkedHashMap又实现了Map

所以通过BindingAwareModelMap间接的实现了上述三个方法

Seesion、Application

用的是Servlet-api的形式,因为SpringMVC的方式相对而言更麻烦些

@RequestMapping("/test/session")
public String testSession(HttpSession httpSession){
    httpSession.setAttribute("testSeesionScope","Hello,Seesion!");
    return "success";
}
​
@RequestMapping("/test/application")
public String testApplication(HttpSession httpSession){
    httpSession.getServletContext().setAttribute("testApplicationScope","Hello,Application!");
    return "success";
}

调用thymeleaf时需要加上seesion或application

<p th:text="${seesion.testSeesionScope}"></p>
<p th:text="${application.testApplicationScope}"></p>

注:seesion是当前会话有效,所以当访问/test/session后,以后再访问其他页面后都会回显Hello,Seesion!,Application同理

视图

InternalResourceView

请求后会进行内部转发,但是不会经过thymeleaf渲染所以不常用

@Controller
public class TestViewController {
    @RequestMapping("/test/view/forward")
    public String testInterResourceView(){
        return "forward:/test/model";
    }
}

RedirectView

请求后会进行重定向

@RequestMapping("/test/view/redirect")
public String testRedirectView(){
    return "redirect:/test/model";
}

视图控制器

之前定义了一个控制器,在访问首页时触发:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
​
@Controller
public class ProtalMapping {
    @RequestMapping("/")
    public String protal(){
        return "index";
    }
}

但只为了实现这一个控制器而写了一个类未免有点小题大做,因此可以通过视图控制器<controller-view>方式来定义

<mvc:view-controller path="/" view-name="index"></mvc:view-controller>

这样在访问根路径时就会自动跳转到index.html,方便许多,但是又引入了一个新的问题:

当时用该控制器后,只有视图控制器所设置的请求会被处理,其他的请求都是404

此时就必须配置一个新的标签<mvc:annotation-driven/>就可以直接解决该问题