SpringMVC-web

SpringMVC - web(Servlet)

  • 和用户交互的组件(获取用户传递参数, 想用数据给用户)
  • jsp --> Servlet --> Jsp
  • 目标
    • hello world
    • 怎么获取参数
    • 如何响应结果
      • 跳转页面
      • 响应数据
  • MVC
    • Model 数据
    • View 视图

SpringMVC会不会使用spring的功能?

  • 使用

如果使用了那么容器什么时候创建(配置文件什么时候被加载)?

  • web.xml中的DispatcherServlet中加载的

SpringMVC hello world

  1. 前置步骤

    1. 工程类型(webapp)

    2. 导包

      
        <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
          <maven.compiler.source>1.8</maven.compiler.source>
          <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
      
        <dependencies>
          <!-- servlet3.1规范的坐标 -->
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
          </dependency>
          <!--jsp坐标-->
          <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
          </dependency>
          <!--spring的坐标-->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
          </dependency>
          <!--spring web的坐标-->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.9.RELEASE</version>
          </dependency>
          <!--springmvc的坐标-->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
          </dependency>
      
        </dependencies>
      
        <!--构建-->
        <build>
          <!--设置插件-->
          <plugins>
            <!--具体的插件配置-->
            <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.1</version>
              <configuration>
                <port>80</port>
                <path>/</path>
                <!--<uriEncoding>UTF-8</uriEncoding>-->
              </configuration>
            </plugin>
          </plugins>
        </build>
      
  2. 中央控制器的配置

        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--加载配置文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath*:abc.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
  3. 如何创建spring容器

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
        <!--扫描加载所有的控制类类-->
        <context:component-scan base-package="com.itheima"/>
    
    
    </beans>
    
  4. 编写Controller(servlet)

    @Controller
    public class UserController {
        //设定当前方法的访问映射地址
        @RequestMapping("/abc")
        //设置当前方法返回值类型为String,用于指定请求完成后跳转的页面
        public String save(){
            System.out.println("user mvc controller is running ...");
            //设定具体跳转的页面
            return "success.jsp";
        }
    
    
        @RequestMapping("/hello")
        public String hello(String param) {
            System.out.println(param);
            return "success.jsp";
        }
    }
    

springMVC启动流程

  1. tomcat启动加载web.xml ( tomcat启动加载那个配置类)
  2. 保证dispactherServlet能够正常加载配置文件(在配置类中加载需要的servlet以及准备工作(容器创建))
  3. spring配置文件必须扫描对应的Controller(404)

mybatis - dao

Spring - 三层bean统一管理

  • Ioc
    • 作用:容器
    • 注解
    • xml
    • di
  • AOP
    • 作用:方法增强
      • 通知Advice
      • 切入点Pointcut
      • 切面Aspect
    • 事务
      • API
      • AOP
      • 声明式
      • 注解

静态资源放行

<mvc:default-servlet-handler/>

中乱码问题

  1. web.xml中配置过滤器

        <filter>
            <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
  2. tomcat插件uri编码配置

     <!--构建-->
        <build>
          <!--设置插件-->
          <plugins>
            <!--具体的插件配置-->
            <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.1</version>
              <configuration>
                <port>80</port>
                <path>/</path>
                <uriEncoding>UTF-8</uriEncoding>
              </configuration>
            </plugin>
          </plugins>
        </build>
    

纯注解

** tomcat启动的时候回去加载ServletContainerInitializer的实现类,但是具体的实现类需要在META-INF这下面配置一个配置文件**

  • 文件名: javax.servlet.ServletContainerInitializer
  • 内容: 你的实现类权限定类名
  1. DispatherServlet
  2. Spring的IOC

模拟SpringBoot内嵌tomcat

流程

  1. tomcat启动
  2. 加载web.xml, or 加载ServletContainerInitializer的实现类
  3. 后续准备工作(容器初始化, 包扫描, 过滤器)

参数获取

  • 基本数据类型(String, int)

    • 直接在对应的方法上写出参数即可
    • 如果名字需要修改@RequestParam(“name”)
  • 404问题:

    • 路径写错了

    • 你根本没有Controller注解

    • 你根本没扫描包( spring-mvc.xml)

    • 根本没有加载配置文件(web.xml)

    • 资源目录写错(resources)

    • 配置静态资源后

      <mvc:annotation-driven/>
      <mvc:default-servlet-handler/>
      
  • 400原因

    • 你请求的参数有问题
参数获取POJO(前端那些参数时,对象当做js对象使用)
  • 普通属性如何注入

  • 引用属性如何注入

  • 集合属性注入

  • map属性注入

  • 请求路径

http://localhost/requestParam3?name=Jock&age=39
  • 代码
    //http://localhost/requestParam3?name=Jock&age=39
    @RequestMapping("/requestParam3")
    public String requestParam3(User user){
        System.out.println(user);
        return "page.jsp";
    }
参数为集合类型
    //方法传递普通类型的数组参数,URL地址中使用同名变量为数组赋值
    //http://localhost/requestParam9?nick=Jockme&nick=zahc
    @RequestMapping("/requestParam9")
    public String requestParam9(String[] nick){
        System.out.println(nick[0]+","+nick[1]);
        return "page.jsp";
    }

    //方法传递保存普通类型的List集合时,无法直接为其赋值,需要使用@RequestParam参数对参数名称进行转换
    //http://localhost/requestParam10?nick=Jockme&nick=zahc
    @RequestMapping("/requestParam10")
    public String requestParam10(@RequestParam("nick") List<String> nick){
        System.out.println(nick);
        return "page.jsp";
    }
如何获取日期参数
  1. 配置文件的方式, 格式根据自己的需求修改

        <!--开启注解驱动,加载自定义格式化转换器对应的类型转换服务-->
        <mvc:annotation-driven conversion-service="conversionService"/>
        <!--自定义格式化转换器-->
        <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <!--覆盖格式化转换器定义规则,该规则是一个set集合,对格式化转换器来说是追加和替换的思想,而不是覆盖整体格式化转换器-->
            <property name="formatters">
                <set>
                    <!--具体的日期格式化转换器-->
                    <bean class="org.springframework.format.datetime.DateFormatter">
                        <!--具体的规则,不具有通用性,仅适用于当前的日期格式化转换器-->
                        <property name="pattern" value="yyyy-MM-dd"/>
                    </bean>
                </set>
            </property>
        </bean>
    
  2. 注解形式

        @RequestMapping("/requestParam11")
        public String requestParam11(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){
            System.out.println(date);
            return "page.jsp";
        }
    

自定义类型转换器

  1. 实现一个接口Converter<参数, 需要得到的类型>

  2. 实现convert方法

    public class MyDateConverter implements Converter<String, Date> {
        //重写接口的抽象方法,参数由泛型决定
        public Date convert(String source) {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            //类型转换器无法预计使用过程中出现的异常,因此必须在类型转换器内部捕获,不允许抛出,框架无法预计此类异常如何处理
            try {
                date = df.parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
    
  3. 配置将转换器添加到spring对应的组件

        <mvc:annotation-driven conversion-service="conversionService"/>
        <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <!--覆盖类型转换器定义规则,该规则是一个set集合,对类型转换器来说是追加和替换的思想,而不是覆盖整体格式化转换器-->
            <property name="converters">
                <set>
                    <!--添加自定义的类型转换器,会根据定义的格式覆盖系统中默认的格式-->
                    <!--当前案例中是将String转换成Date的类型转换器进行了自定义,所以添加后,系统中原始自带的String——>Date的类型转换器失效-->
                    <bean class="com.itheima.converter.MyDateConverter"/>
                </set>
            </property>
        </bean>
    

@RequestMapping

// target代表你能写在那些地方
// type代表类型, 能写在类上
// METHOD 方法上
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";

    //路径
    //Alias别名
    @AliasFor("path")
    String[] value() default {};
	//路径
    @AliasFor("value")
    String[] path() default {};

    // method, 指定请求方式(GET,POST)
    RequestMethod[] method() default {};
	//参数
    String[] params() default {};
	//请求头信息指定
    String[] headers() default {};
	//接收的媒体类型
    String[] consumes() default {};
	//响应的媒体类型
    String[] produces() default {};
}

响应- 页面跳转

  1. 重定向
    1. 相当于页面重新刷新, 不能够拿到后端给的request,response
  2. 转发
    1. 携带有request,response,在jsp中可以直接使用其中的数据
页面跳转方式 - 直接返回值是页面路径

** 没有配置视图解析器**

@RequestMapping("/showPage")
public String showPage() {
    System.out.println("user mvc controller is running ...");
    //返回值直接为webapp下的路径
    return "/system/userlist.jsp";
}

@RequestMapping("/showPage")
public String showPage() {
    System.out.println("user mvc controller is running ...");
    //返回值直接为webapp下的路径
    return "/WEB-INF/page/page.jsp";
}


@RequestMapping("/showPage2")
public String showPage2() {
    System.out.println("user mvc controller is running ...");
    // forward   转发
    // redirect 重定向
    return "redirect:/WEB-INF/page/page.jsp";
}

页面跳转方式 - 直接返回值是页面路径(有视图解析器)

  1. 配置视图解析器

        <context:component-scan base-package="com.itheima"/>
    
        <!--设定页面加载的前缀后缀,仅适用于默认形式,不适用于手工标注转发或重定向的方式-->
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/page/"/>
                <property name="suffix" value=".jsp"/>
            </bean>
    
        <!--开启springmvc注解驱动,对@ResponseBody的注解进行格式增强,追加其类型转换的功能,具体实现由MappingJackson2HttpMessageConverter进行-->
        <mvc:annotation-driven/>
        <mvc:default-servlet-handler/>
    
  2. 在返回值中直接写上/WEB-INF/page/的静态页面名称即可

    @RequestMapping("/showPage3")
    public String showPage3() {
        System.out.println("user mvc controller is running ...");
        return "page";
    }

携带数据 - jsp中使用

  1. 直接利用request对象存储数据

        @RequestMapping("/showPageAndData1")
        public String showPageAndData1(HttpServletRequest request) {
            request.setAttribute("name","itheima");
            return "page";
        }
    
  2. 使用model对象存储数据,实际上依然存储在request中

        @RequestMapping("/showPageAndData2")
        public String showPageAndData2(Model model) {
            //添加数据的方式,key对value
            model.addAttribute("name","Jock");
            Book book  = new Book();
            book.setName("SpringMVC入门案例");
            book.setPrice(66.66d);
            //添加数据的方式,key对value
            model.addAttribute("book",book);
            return "page";
        }
    
  3. 使用modelAndView

    1. view视图(jsp,html)
    2. model数据
        //使用ModelAndView形参传递参数,该对象还封装了页面信息
        @RequestMapping("/showPageAndData3")
        public ModelAndView showPageAndData3(ModelAndView modelAndView) {
            //ModelAndView mav = new ModelAndView();    替换形参中的参数
            Book book  = new Book();
            book.setName("SpringMVC入门案例");
            book.setPrice(66.66d);
    
            //添加数据的方式,key对value
            modelAndView.addObject("book",book);
            //添加数据的方式,key对value
            modelAndView.addObject("name","Jockme");
            //设置页面的方式,该方法最后一次执行的结果生效
            modelAndView.setViewName("page");
            //返回值设定成ModelAndView对象
            return modelAndView;
        }
    

响应JSON数据

1. 导包
 <!--json相关坐标3个-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>
2. spring-mvc配置文件添加注解支持
<mvc:annotation-driven/>
3.使用
  • 注解: @ResponBody,添加到控制器中的方法上即可
    @RequestMapping("/mapdata")
    @ResponseBody
    public Map<String, Object> mapdata() {
        Map map = new HashMap();
        map.put("name", "zhangsan");
        map.put("age", 12);
        return map;
    }

Servlet原生API获取

  • request、response、session
    @RequestMapping("/showData4")
    @ResponseBody
    public Book showData4(HttpServletRequest request, HttpServletResponse response) {
        return book;
    }
  • cookie, header
    //@CookieValue
    //@RequestHeader
    //@SessionAttribute

重点

  • hello world
  • 执行流程(无配置实现)
  • 获取参数
  • 响应数据
    • 存储到request
  • 响应json
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dukai954

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值