Day72.获取请求参数、页面跳转、原生API、属性域(Model原理)、Thymeleaf数据回显

目录

一、获取请求参数

1、一名一值

 2、一名多值   List

3、实体类 (表单对应模型 )

4、实体类包含级联属性

二、获取请求头  @RequestHeader

三、获取指定Cookie  @CookieValue

四、页面跳转控制

五、获取原生 Servlet API 对象 

六、属性域 (ModelView原理) ★

关于底层,Model(模型) 的本质:

七、表单数据回显 (回顾Thymeleaf)

1、回显简单文本标签

2、回显单选框和下拉框

3、回显多选框


一、获取请求参数

使用 @RequestParam 注解标记handler方法的形参,当请求参数名和形参名一致可以省略

    @RequestMapping("/login2")
    public String login2(@RequestParam("username") String uname, String password){
        log.debug("username:" +uname +"password:" +password);
        return "result";
    }

请求参数必须  required (有则传入,没有不报错)默认required=true,请求参数必须提供

@RequestParam(value = "userName", required = false)

给请求参数设置默认值 defaultValue

@RequestParam(value = "userName", required = false, defaultValue = "missing")

1、一名一值

<h4>1.一名一值</h4>
<a href="/springmvc/user/login?username=atguigu&password=123456">登录1</a><br>
<a th:href="@{/user/login2(username=atguigu,password=123456)}">登录2</a><br>
<a th:href="@{/user/register(username=zhangsan,age=12,salary=123.45)}">注册1</a><br>
<a th:href="@{/user/register2(username='zhangsan',age=12)}">注册2</a>
@Controller
@Slf4j
@RequestMapping("/user")
public class UserController {
    // 使用@RequestParam注解标记handler方法的形参
    // SpringMVC 会将获取到的请求参数从形参位置给我们传进来
    //登录1 (不用)
    @RequestMapping("/login")
    public String login(String username,String password){
        log.debug("username:" +username +"password:" +password);
        return "result";
    }
    //登录2
    @RequestMapping("/login2")
    public String login2(@RequestParam("username") String uname, String password){
        log.debug("username:" +uname +"password:" +password);
        return "result";
    }
    //注册1
    @RequestMapping("/register")
    public String register(String username,Integer age,Double salary){
        log.debug("username:"+username +"age:"+age+"salary:"+salary);
        return "result";
    }
    //注册2
    @RequestMapping("/register2")
    public String register2(String username,Integer age,//@RequestParam  salary可以不是必须的,默认值为1000
                            @RequestParam(name = "salary",required = false,defaultValue = "1000") double salary){
        log.debug("username:"+username +"age:"+age+"salary:"+salary);
        return "result";
    }
}

 异常:当必须的参数没有提供,并且没有设置required

  • 响应状态码:400(在 SpringMVC 环境下,400通常和数据注入相关)
  • 说明信息:必需的 String 请求参数 'userName' 不存在

原因可以参考 @RequestParam 注解的 required 属性:默认值为true,表示请求参数默认必须提供。

 2、一名多值   List<String>

<h3>2.获取请求参数-一名多值</h3>
<form th:action="@{/user/getTeams}" method="post">
    请选择你最喜欢的球队:
    <input type="checkbox" name="team" value="Brazil"/>巴西
    <input type="checkbox" name="team" value="German"/>德国
    <input type="checkbox" name="team" value="French"/>法国
    <input type="checkbox" name="team" value="Holland"/>荷兰
    <input type="checkbox" name="team" value="Italian"/>意大利
    <input type="checkbox" name="team" value="China"/>中国
    <br/>
    <input type="submit" value="保存"/>
</form>
    //一名多值
    @RequestMapping("/getTeams")
    public String getTeams(@RequestParam("team") List<String> teamList){
        log.debug("teamList:"+teamList);
        return "result";
    }

3、实体类 (表单对应模型 )

<h4>3.实体类</h4>
<form action="emp/save" method="post">
    姓名:<input type="text" name="empName"/><br/>
    年龄:<input type="text" name="empAge"/><br/>
    工资:<input type="text" name="empSalary"/><br/>
    <input type="submit" value="保存"/>
</form>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
    private Integer empId;
    private String empName;
    private int empAge;
    private double empSalary;
}
    //实体类
    @RequestMapping("/addEmp")
    public String addEmp1111(Employee employee123){
        log.debug("Employee:"+employee123);
        return "result";
    }

4、实体类包含级联属性

    <h4>4.实体类含级联属性</h4>
    <form th:action="@{/user/addStudent}" method="post">
        学成名称: <input type="text" name="stuName"><br>
        学校编号: <input type="text" name="school.schoolId"><br>
        学校名称: <input type="text" name="school.schoolName"><br>
        课程1编号: <input type="text" name="subjectList[0].subjectId"><br>
        课程1名称: <input type="text" name="subjectList[0].subjectName"><br>
        课程2编号: <input type="text" name="subjectList[1].subjectId"><br>
        课程2名称: <input type="text" name="subjectList[1].subjectName"><br>
        课程1分数: <input type="text" name="scores['java']">
        课程1分数: <input type="text" name="scores['mysql']">
        <input type="submit" value="保存">
    </form>
学生
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String stuName;
    private School school;
    private List<Subject> subjectList;//List
    //private Subject[] subjectArray;//Array
    //private Set<Teacher> teacherSet;//Set ?? 不推荐使用
    private Map<String, Double> scores;//Map
}
学校
@Data
@AllArgsConstructor
@NoArgsConstructor
public class School {
    private Integer schoolId;
    private String schoolName;
}
课程
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Subject {
    private Integer subjectId;
    private String subjectNAme;
}
    //级联实体类
    @RequestMapping("/addStudent")
    public String addStudent(Student stu){
        log.debug("Student:"+stu);
        return "result";
    }

二、获取请求头  @RequestHeader

@RequestHeader 获取请求消息头中的具体数据。

name 或 value 属性:指定请求消息头名称。
defaultValue 属性:设置默认值。

    <h4>5.获取请求头</h4>
    <a th:href="@{/user/getHeaders}">获取请求头</a>
    //获取请求头  @RequestHeader(要获取的信息)
    @RequestMapping("/getHeaders")
    public String getHeaders(@RequestHeader("User-Agent") String userAgent,
                             @RequestHeader("Referer")String referer){
        log.debug("浏览器类型:" + userAgent);
        log.debug("从哪里来(上一个Url):" + referer);
        return "result";
    }

使用原生Servlet获取请求头: 

String agent = request.getHeader("User-Agent") 

三、获取指定Cookie  @CookieValue

@CookieValue  获取当前请求中的 Cookie 数据。由于cookie实际上存储的是session_id具体的数据是保存在session中,所以参数还要加上HttpSession

name 或 value 属性:指定Cookie 名称
defaultValue 属性:设置默认值

    <h4>6.获取Cookies信息</h4>
    <a th:href="@{/user/getCookies}">获取Cookies信息</a>
    //获取Cookies信息
    @RequestMapping("/getCookies")
    public String getCookies(@CookieValue(value = "JSESSIONID",defaultValue = "missing")
                                         String sessionId, HttpSession httpSession){
        log.debug("sessionId:" + httpSession);
        return "result";
    }

使用原生Servlet获取Cookie:

Cookie[] cookies = request.getCookies() ,再遍历集合获取内容

四、页面跳转控制

SpringMVC 框架会在前面附加 contextPath,所以我们不用添加应用路径

转发、重定向路径前添加 forward、redirect:后,路径不会再拼接前后缀(不会被thymeleaf解析)

    //请求转发
    //forward: 不会再追加前后缀(不会被thymeleaf解析)
    @RequestMapping("/dispatcher1")
    public String dispatcher1(){
        log.info("---- dispatcher1 默认");
        return "result";    //默认就是请求转发,自动添加前后缀
        //  /WEB-INF/templates/result.html
    }
    @RequestMapping("/dispatcher2")
    public String dispatcher2(){
        log.info("---- dispatcher2 forward:/WEB-INF/templates/result.html");
        return "forward:/WEB-INF/templates/result.html";
    }
    @RequestMapping("/dispatcher3")
    public String dispatcher3(){
        log.info("---- dispatcher3 forward:/index.html");
        return "forward:/index.html";
    }
    //重定向
    //redirect: 不会再追加前后缀(不会被thymeleaf解析)
    @RequestMapping("/redirect1")
    public String redirect1(){
        log.info("---- redirect1 不能访问WEB-INF ----");
        return "redirect:/WEB-INF/templates/result.html";
    }
    @RequestMapping("/redirect2")
    public String redirect2(){
        log.info("---- redirect2 可以访问除WEB-INF外服务器资源 ----");
        return "redirect:/index.html";
    }
    @RequestMapping("/redirect3")
    public String redirect3(){
        log.info("---- redirect3 可以重定向到互联网任意位置 ----");
        return "redirect:http://www.atguigu.com";
    }

 复习:转发和重定向的区别

  1. 重定向会由浏览器发起新的请求,而请求转发不会发起新的请求。
  2. 重定向可以访问任意互联网资源,而请求转发只能访问本项目资源。
  3. 重定向不能访问本项目的WEB-INF内的资源,而请求转发可以访问本项目的WEB-INF内的资源。
  4. 发起重定向的资源和跳转到的目标资源没在同一次请求中,所以重定向不能在请求域中使用;而发起请求转发的资源和跳转到的目标资源在同一次请求中,所以请求转发可以在请求域中使用

Day56.Servlet: Request、Response、获取参数、转发&重定向、书城项目二阶段_焰火青年·的博客-CSDN博客

五、获取原生 Servlet API 对象 

HttpServletRequest   HttpServletResponse() | HttpSession :通过参数获取

ServletContext (全局域) :自动装配通过session获取

注意:

1、session(会话域)、application(应用域) 中传递数据,使用原生API

2、request(请求域) 中传递数据,一般不使用原生API,而是使用下面的四种方式。

    //可以自动装配全局上下文对象,已存在于IoC容器中
    @Autowired//
    private ServletContext servletContext;

    //获取原生 ServletAPI
    @RequestMapping("/getServletAPI")
    public String getServletAPI(HttpServletRequest request,
                                HttpServletResponse response,
                                HttpSession session){//ServletContext 需要其他方式获取
        log.info("request");
        request.setAttribute("msg","username cannot be null");//请求域:当前请求
        session.setAttribute("name","zhangsan");//session会话域:当前会话
        response.addHeader("school","atguigu");//添加头信息

        ServletContext servletContext = session.getServletContext();
        servletContext.setAttribute("count",100);//全局域:当前应用

        return "result";
    }
result.html
    获取(接收)域信息
    <p th:text="${msg}"></p>
    <p th:text="${user}"></p>
    <p th:text="${application.count}"></p>

回顾:域对象

请求域每一次请求都有一个请求域对象,当请求结束的时候对应的请求域对象也就销毁了 

会话域会话域是从客户端连接上服务器开始,客户端关闭,这一整个过程中发生的所有请求都在同一个会话域中;而不同的客户端是不能共用会话域的。

应用域项目部署后只会有一个应用域对象所有客户端都是共同访问同一个应用域对象,在该项目的所有动态资源中也是共用一个应用域对象。

Day59.域对象、会话控制、Cookie、Session、书城四阶段_焰火青年·的博客-CSDN博客

六、属性域 (ModelView原理) ★ BindingAwareModelMap

我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域,也被称为暴露到请求域。

SpringMVC 传入的 Model、ModelMap、Map类型的参数,
其实本质上都是 BindingAwareModelMap 类型的。

1、使用 Model 类型的形参

@RequestMapping("/useModel")
public String useModel(Model model){
    //request.setAttribute("msg","username cannot be null"); //请求请求
    model.addAttribute("msg","username cannot be null(model)");
    return "result";
}

2、使用 Map 类型的形参

@RequestMapping("/useMap")
public String useMap(Map map){
    //request.setAttribute("msg","username cannot be null"); //请求请求
   map.put("msg","username cannot be null(map)");
    return "result";
}

3、使用 ModelMap 类型的形参

@RequestMapping("/useModelMap")
public String useModel(ModelMap modelMap){
    //request.setAttribute("msg","username cannot be null"); //请求请求
     modelMap.addAttribute("msg","username cannot be null(modelMap)");
    return "result";
}

4、使用 ModelAndView 对象

@RequestMapping("/useModelAndView")
public ModelAndView useModelAndView(){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("msg","username cannot be null(ModelAndView)");
    modelAndView.setViewName("result");
    return modelAndView;
}

关于底层,Model(模型) 的本质:

使用Model、Map、ModelMap来传递数据,方法的返回值类型是String。但 SpringMVC的底层都会使用 ModelAndView 来存储数据和视图

不是使用Model、Map、ModelMap、ModelAndView,底层都是在请求域传递数据,底层都调用了request.setAttribute(key,value)

七、表单数据回显 (回顾Thymeleaf)

Day57.表述层(MVC)、Thymeleaf: 逻辑视图、对象图(OGNL)、分支迭代..._焰火青年·的博客-CSDN博客

Day51.HTML、标签、表单、CSS_焰火青年·的博客-CSDN博客

准备实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Tiger {
    private Integer tigerId;
    private String tigerName;
    private Double tigerSalary;

    private Season season;//季节

    private List<Friend> friendList = new ArrayList<>();//朋友
}
public class Season {//季节
    private Integer seasonId;
    private String seasonName;

}
public class Friend {
    private Integer friendId;
    private String friendName;
}

1、回显简单文本标签

@Controller
@Slf4j
@RequestMapping("/tiger")
public class TigerController {
    //回显文本框
    @RequestMapping("/showTiger1")
    public String showTIger1(Model model){
        Tiger tiger = new Tiger();
        tiger.setTigerId(1);
        tiger.setTigerName("杰瑞");
        tiger.setTigerSalary(1000.1);

        model.addAttribute("tiger1",tiger);

        return "tiger";
    }
<h3>修改表单数据1:文本框</h3><!--文本框--><!--name:key,value:value-->
    <form>
        编号:<input type="text" th:value="${tiger1.tigerId}"><br>
        昵称:<input type="text" th:value="${tiger1.tigerName}"><br>
        薪水:<input type="text" th:value="${tiger1.tigerSalary}"><br>
        <input type="submit" th:value="提交">
    </form>

2、回显单选框和下拉框

关键在于页面显示,后台Controller中将数据放入Model然后转发跳转到前台页面,回显即可
单选框 th:checked 下拉列表 th:selected

//回显单选框、下拉列表
   @RequestMapping("/showTiger2")
    public String showTIger2(Model model){
       Tiger tiger = new Tiger();
       tiger.setTigerId(1);
       tiger.setTigerName("杰瑞");
       tiger.setTigerSalary(1000.1);
       tiger.setSeason(new Season(3,"Autumn"));

       //季节集合
       List<Season> seasonList = new ArrayList<>();
       seasonList.add(new Season(1,"Spring"));
       seasonList.add(new Season(2,"Summer"));
       seasonList.add(new Season(3,"Autumn"));
       seasonList.add(new Season(4,"Winter"));
       model.addAttribute("seasonList",seasonList);

       model.addAttribute("tiger1",tiger);

        return "tiger";
    }
<h3>修改表单数据2:单选框 | 下拉列表</h3><!--单选框-->
    <form>
        编号:<input type="text" th:value="${tiger1.tigerId}"><br>
        昵称:<input type="text" th:value="${tiger1.tigerName}"><br>
        薪水:<input type="text" th:value="${tiger1.tigerSalary}"><br>
        <!--单选框-->
        季节单选框:<input type="radio" th:each="season:${seasonList}"
                            th:value="${season.seasonId}"
                            th:text="${season.seasonName}"
                            th:checked="${season.seasonId}==${tiger1.season.seasonId}"> <br>
        <!--下拉列表-->
        季节下拉框:<select>
            <option th:each="season:${seasonList}"
                    th:value="${season.seasonId}"
                    th:text="${season.seasonName}"
                    th:selected="${season.seasonId}==${tiger1.season.seasonId}"></option> <br>
        </select>

        <input type="submit" th:value="提交">
    </form>

3、回显多选框

//回显多选框
    @RequestMapping("/showTiger3")
    public String showTiger3(Model model){
        Tiger tiger = new Tiger();
        tiger.setTigerId(1);
        tiger.setTigerName("杰瑞");
        tiger.setTigerSalary(1000.1);
        tiger.setSeason(new Season(3,"Autumn"));
        tiger.getFriendList().add(new Friend(1,"Monkey"));
        tiger.getFriendList().add(new Friend(4,"Mickey"));
        model.addAttribute("tiger1",tiger);

        //季节集合
        List<Season> seasonList = new ArrayList<>();
        seasonList.add(new Season(1,"Spring"));
        seasonList.add(new Season(2,"Summer"));
        seasonList.add(new Season(3,"Autumn"));
        seasonList.add(new Season(4,"Winter"));
        model.addAttribute("seasonList",seasonList);

        //朋友集合
        List<Friend> friendList = new ArrayList<>();
        friendList.add(new Friend(1,"Monkey"));
        friendList.add(new Friend(2,"Donkey"));
        friendList.add(new Friend(3,"Turkey"));
        friendList.add(new Friend(4,"Mickey"));
        model.addAttribute("friends",friendList);
        return "tiger";

    }
<h3>修改表单数据3:多选框</h3><!--下拉框-->
    <form>
        编号:<input type="text" th:value="${tiger1.tigerId}"><br>
        昵称:<input type="text" th:value="${tiger1.tigerName}"><br>
        薪水:<input type="text" th:value="${tiger1.tigerSalary}"><br>
        <!--单选框-->
        季节单选框:<input type="radio" th:each="season:${seasonList}"
                     th:value="${season.seasonId}"
                     th:text="${season.seasonName}"
                     th:checked="${season.seasonId}==${tiger1.season.seasonId}"> <br>
        <!--下拉列表-->
        季节下拉框:<select>
        <option th:each="season:${seasonList}"
                th:value="${season.seasonId}"
                th:text="${season.seasonName}"
                th:selected="${season.seasonId}==${tiger1.season.seasonId}"></option>moviemgr
        </select> <br>
        <!--多选框-->
        <input type="checkbox" th:each="friend:${friends}"
                th:value="${friend.friendId}"
                th:text="${friend.friendName}"
                th:checked="${tiger1.friendList.contains(friend)}"> <br>
        <input type="checkbox" th:each="friend:${friends}"
               th:value="${friend.friendId}"
               th:text="${friend.friendName}"
               th:checked="${#lists.contains(tiger1.friendList,friend)}"> <br>
        <input type="submit" th:value="提交">
    </form>
</form>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值