day55_springmvc

今日内容

零、 复习昨日

零、 复习昨日

1 maven项目编译后代码在target

2 发现代码都没有错,该写的都有,但是已启动服务器404,查看target,如果编译会后资源不全面,那就删除重新编译

3 重新看一下,如何使用mavne创建javaweb项目

一、参数绑定 【重点】

所谓参数绑定,就是前端发请求中的数据,可以直接在Controller的方法参数中接收.

即前端请求数据和后端方法参数绑定.

1.1 基本类型参数绑定[重点]

基本类型指,常用的几种类型: 基本类型+String+Date

前端页面

<h2>基本类型数据绑定h2>
<a href="/base.do?id=1&username=张三&score=10.0">请求携带数据-基本类型a>
<hr>
<form action="/base.do" method="get">
    id<input type="text" name="id"><br>
    username<input type="text" name="username"><br>
    score<input type="text" name="score"><br>
    birthday<input type="text" name="birthday"><br>
    <input type="submit" value="基本类型">
form>

后端接收

@Controller
public class DataController {

    /**
     * 基本类型自动封装
     * 要求是: 前端请求的参数名,后端方法的参数名要一致
     * 【特殊的】 日期,前端发送的日期格式如果是yyyy-MM-dd,springmvc无法默认绑定参数,
     *            springmvc默认支持yyyy/MM/dd
     * 两种方案解决:
     *  1. 前端改,发出的日期格式就是yyyy/MM/dd即可
     *  2. 后端改,给日期参数加@DateTimeFormat(pattern = "yyyy-MM-dd")
     */
    @RequestMapping("/base")
    public String base(int id, String username, double score, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
        System.out.println("id = " + id);
        System.out.println("username = " + username);
        System.out.println("score = " + score);
        System.out.println("birthday = " + birthday);
        return "ok";
    }

}

1.2 对象[重点]

场景: 注册/添加/更新

实体类

public class User {

    private int id;
    private String username;
    private String password;
    private double score;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    // setget
}

前端

<h2>对象数据绑定h2>
<form action="/obj.do" method="get">
    id<input type="text" name="id"><br>
    username<input type="text" name="username"><br>
    score<input type="text" name="score"><br>
    birthday<input type="date" name="birthday"><br>
    <input type="submit" value="对象类型">
form>

后端

    /**
     * 自动绑定: 要求前端的请求中的参数要和对象的属性名一致
     */
    @RequestMapping("/obj")
    public String obj(User user){
        System.out.println("user = " + user);
        return "ok";
    }

1.3 数组

场景: 批量删除需要同时接收多个id, (前端是复选框的)

前端

<h2>数组绑定h2>
<form action="/array.do" method="get">
     <input type="checkbox" name="ids" value="1">1
     <input type="checkbox" name="ids" value="2">2
     <input type="checkbox" name="ids" value="3">3
     <input type="checkbox" name="ids" value="4">4
    <input type="submit" value="数组类型">
form>

后端

    /**
     * 自动绑定: 要求前端的请求中的参数要和方法参数名(数组名)一致
     */
    @RequestMapping("/array")
    public String array(int[] ids){
        System.out.println("ids = " + Arrays.toString(ids));
        return "ok";
    }

1.4 List集合

List集合使用场景与数组是一样的

前端

<h2>List绑定h2>
<form action="/list.do" method="get">
    <input type="checkbox" name="skill" value="Java">Java
    <input type="checkbox" name="skill" value="HTML">HTML
    <input type="checkbox" name="skill" value="Linux">Linux
    <input type="submit" value="List类型">
form>

SpringMVC默认是不支持直接封装List的,解决方案

    1. 加注解@RequestParam,就可以【推荐】
    1. 间接的封装List — 创建一个实体类,定义List属性

方案一

@RequestMapping("/list")
public String list(@RequestParam List<String> skill){
    System.out.println("skill = " + skill);
    return "ok";
}

方案二

public class User {

    private int id;
    private String username;
    private double score;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    private List<String> skill;  // 定义集合属性
    
	// setget    
}
    @RequestMapping("/list")
// 在封装对象数据时,封装list
    public String list(User user){
        System.out.println("user-skill = " + user.getSkill());
        return "ok";
    }

1.5 Map集合

Map是键值对,键和值一一映射.

跟Java对象很类似,属性和属性值一一对应.

所以什么时候需要/可以使用Map来接收参数?

  • 凡是可以用对象接收的都可以使用Map
  • 需要接收两个参数时,可以map

SpringMVC默认不支持直接将参数封装进Map,需要使用@RequestParam

前端

<h2>Map绑定h2>
<form action="/map.do" method="get">
    id<input type="text" name="id"><br>
    username<input type="text" name="username"><br>
    score<input type="text" name="score"><br>
    birthday<input type="date" name="birthday"><br>
    <input type="submit" value="Map类型">
form>
<h2>模糊查询-Map绑定h2>
<form action="/map.do" method="get">
    address<input type="text" name="address"><br>
    floor<input type="text" name="floor"><br>
    deco<input type="text" name="deco"><br>
    <input type="submit" value="模糊-Map类型">
form>
name就是map的key
输入框的值就是map的value

后台

    @RequestMapping("/map")
    public String map(@RequestParam Map<String,Object> map){
        System.out.println("map = " + map);
        return "ok";
    }

1.6 @RequestParam

当封装数据失败时使用该注解,该注解放在参数上

场景一:

前端参数和后端方法参数要一致才能封装数据,当不一致时可以使用@RequestParam来手动指定前端数据封装给参数

day55_springmvc_第1张图片

场景二:

默认情况下,后端方法的参数列表一旦设置了该参数,就必须传值,不传值就会报错

但是设置@RequestParam(required = false)时就可以不用传值也不报错

day55_springmvc_第2张图片

场景三:

当后端参数没有传值时,赋值默认值@RequestParam(defaultValue = “666666”)

day55_springmvc_第3张图片

二、数据乱码

之前自己写过全局编码格式拦截器

现在springmvc提供了编码格式拦截器,直接用即可

    
    <filter>
        <filter-name>encodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>encodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

三、页面跳转

之前学过的servlet中跳转页面的功能

  • 请求转发:
    • forward
    • req.getDispatcherServlet().forward(req,resp)
    • 请求路径不变
    • 是服务器内部请求
    • 一次请求
    • 请求域的数据可以共享
  • 重定向
    • redirect
    • resp.sendRedirect();
    • 请求路径改变
    • 是浏览器行为
    • 两次请求
    • 请求域的不能共享

请求转发

注意: 默认在使用就是请求转发

在Controller的方法的返回值中写forward:路径即可完成跳转

例如: forward:/view/ok.html forward:/test.do

注意: 跳转后的路径要写完整

 /**
     * 演示请求转发至其他页面
     * @return
     */
    @RequestMapping("/forward")
    public String forward(){
        System.out.println("执行请求转发" );
        return "forward:/view/ok.html";
    }

    /**
     * 演示请求转发至其他请求
     * @return
     */
    @RequestMapping("/forward2")
    public String forward2(){
        System.out.println("执行请求转发" );
        return "forward:/test.do";
    }

重定向

在Controller的方法的返回值中写redirect:路径即可完成跳转

例如: redirect:/view/ok.html redirect:/test.do

注意: 跳转后的路径要写完整

   /**
     * 演示重定向至其他页面
     * @return
     */
    @RequestMapping("/redirect")
    public String redirect(){
        System.out.println("执行重定向" );
        return "redirect:/view/ok.html";
    }

    /**
     * 演示重定向至其他请求
     * @return
     */
    @RequestMapping("/redirect2")
    public String redirect2(){
        System.out.println("执行重定向" );
        return "redirect:/test.do";
    }

其他的请求转发和重定向的特点和之前学习的servlet是一样的,复习.

四、数据共享

数据共享是指: 数据域,即

  • request域
    • 只有在一次请求中有效,即请求转发后能取出
  • session域
    • 一次会话有效,只要会话不结束,无论请求转发还是重定向都能取出
package com.qf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 演示域对象(Request,Session)
 */
@Controller
public class ScopeController {

    @RequestMapping("/req")
    public String requestAndSession(HttpServletRequest request, HttpSession session) {

        // 存入
        request.setAttribute("req","req-Value");
        session.setAttribute("se","se-Value");

        return "forward:/req2.do";
    }


    @RequestMapping("/req2")
    public String requestAndSession2(HttpServletRequest request, HttpSession session) {

       // 取出
        String v1 = (String) request.getAttribute("req");
        System.out.println("v1 = " + v1);
        String v2 = (String) session.getAttribute("se");
        System.out.println("v2 = " + v2);

        return "ok";
    }
}

五、静态资源处理

目前,前端控制器(DispatcherServlet)类映射的是==*.do==,前端的静态资源例如:html,js,css,图片 等都是不影响加载的

但是,如果前端控制器(DispatcherServlet)类映射的是==/==,那就是所有请求都要经过前端控制器,静态资源也不例外. 那么此时静态资源是无法完成映射.

此时就需要静态资源处理!!!

web.xml文件

    
    <servlet>
        <servlet-name>dispatcherServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:springmvc.xmlparam-value>
        init-param>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServletservlet-name>
        
        <url-pattern>/url-pattern>
    servlet-mapping>

项目中定义一个css文件夹,定义一个css文件,在index.jsp页面中引入静态资源css,查看效果即可

day55_springmvc_第4张图片

springmvc.xml文件

    
    <mvc:resources mapping="/**" location="/"/>

ps:

 也行

六、拦截器 【重点】

6.1 作用

  • 之前用来做编码格式过滤
  • 登录认证
  • 等等

6.2 定义拦截器

  • 自定义类
  • 实现接口
  • 重写方法
  • springmvc.xml配置
package com.qf.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 拦截器类
 */
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 目前Controller,执行前,执行拦截
     * 一般用于: 校验
     * @return  返回true,即认为放行,返回false不放行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("前 pre" );
        // 写项目时,这里通过数据判断,来决定是返回true放行,还是返回false不放行
        return true;
    }

    /**
     * 在目标Controller方法执行完,但是afterCompletion方法前执行
     * 对目标方法的返回再处理,可以对响应再定制.
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("post" );
    }

    /**
     * 目标Controller的方法全部执行完执行
     * 一般: 资源回收
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("after" );
    }
}

以上方法是按需重写,一般来说用的是前置方法preHandle()

    
    <mvc:interceptors>
        <mvc:interceptor>
            
            
            <mvc:mapping path="/**"/>
            
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/test.do"/>
            
            <bean class="com.qf.interceptor.MyInterceptor"/>
        mvc:interceptor>
    mvc:interceptors>

七、异常处理

以前处理异常

  • 抛出
  • 视图捕获

全靠自己在每个方法中处理异常

springmvc框架提供了一个全局的异常处理机制,可以处理Controller的所有异常

这种方法,集中管理异常


  • 建类
  • 实现接口
  • 重写方法
  • 配置
@Component // 配置到spring容器
public class MyExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        ModelAndView mv = new ModelAndView( );

        if (ex instanceof ArithmeticException) {
            mv.setViewName("redirect:/view/500.html");
        } else if (ex instanceof AuthException) {
            mv.setViewName("redirect:/view/auth.html");
        }
        return mv;
    }
}

测试

后台Controller抛出异常,测试!

任务

重点: 参数绑定- 重复
删除数据发请求-接收
添加/注册/更新  -> 接收
批量删除 --> 接收

其中使用的注解要会
------------------------
重新整合spring和mybatis

--------------------------------------
思考:
写项目后端数据如何在页面展现?
方案1: 存储域,在jsp页面取值
方案2: 不用jsp,用html开发,后端数据如何给前端展现?

你可能感兴趣的:(#,Java2307,java,数据库,mysql)