SpringMVC_基础

SpringMVC_基础

1.SpringMVC是什么?

SpringMVC 是 Spring 基础上开发的控制器框架 ,在现有MVC架构中充当控制器,也是一个典型的MVC框架。

SpringMVC可以替换项目中现有的struts2技术。

2.SpringMVC第一个环境搭建

1)引入依赖

<dependencies>
  <!--spring框架的相关依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.9.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.2.9.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.9.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.2.9.RELEASE</version>
  </dependency>
  <!--springMVC的相关依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.9.RELEASE</version>
  </dependency>
  <!--面向切面-->
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.6</version>
  </dependency>
  <!--servlet 及 jsp-->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
  </dependency>
</dependencies>

2)配置web.xml

DispatcherServlet	使用servlet标签	  url-pattern /

<!--springmvc核心servlet-->
<servlet>
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-clas
  <init-param>
    <!--固定写死用来加载springmvc配置文件的位置-->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <!--拦截所有请求交给springmvc处理-->
  <url-pattern>/</url-pattern>
</servlet-mapping>

3)引入springmvc.xml 配置文件

位置:随便  名字:随便  推荐:springmvc.xml并放置在resource根目录下

0.开启注解扫描
1.处理器映射器
2.处理器适配器
3.视图解析器

<!--开启注解扫描,并指定只扫描Controller-->
<context:component-scan base-package="com.itheima.springmvc.controller" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!--注册处理器映射器 及 处理器适配器-->
    <!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>-->
	<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>-->
<!--spring3.x 以后不建议上面的写法,可用<mvc:annotation-driven/>替代-->
<!--<mvc:annotation-driven/>中还包含对参数类型的转换,跳转,相应处理等-->
<mvc:annotation-driven/>

<!--注册 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

4)开发xxxController控制器,加入相关注解

@Controller
@RequestMapping("user")
public class UserController {
    /**
     * @RequestMapping:可以修饰在 类上 和 方法上
     *  1. 用在方法上,可以给当前方法加入指定的请求路径
     *  2. 用在类上,可以给类中所有的方法加入统一的请求路径,
     *     在方法访问之前需要加入类上的@RequestMapping的路径
     * @return
     */
    @RequestMapping("hello")
    public String hello(){
        //1.收集数据
        //2.调用业务方法
        System.out.println("hello spring mvc");
        //3.处理相应
        return "index";
    }
}

3.SpringMVC中的跳转方式

1)原始Servlet技术中跳转方式

  • forward跳转:请求转发
    • 特点:服务器内部跳转,跳转之后地址栏不变。一次跳转,跳转时可以使用request作用域传递数据。
  • redirect跳转:请求重定向
    • 特点:客户端跳转,跳转之后地址栏改变。多次跳转,跳转过程不能使用request作用域传递数据。

2)SpringMVC中跳转方式

  • Controller ----> JSP页面跳转
    • forward跳转:默认使用的就是forward跳转到也页面
      • 具体语法:return “页面逻辑名”;
    • redirect跳转:使用SpringMVC提供的关键字:redirect,
      • 具体语法:return “redirect:视图全名”;如:return “redirect:/index.jsp”;
      • 注意:使用redirect跳转不会经过视图解析器
  • Controller ----> Controller 之间跳转(相同|不同控制器)
    • forward|redirect 跳转:使用springmvc提供的关键字forward|redirect :
      • return “forward|redirect: /跳转controller类上@RequestMapping的路径/跳转类中指定方法上@RequestMapping的路径”

4.SpringMVC中的参数接收

  • 语法:使用控制器中方法的形参列表接收客户端的请求参数。
    • 要求:要求传递参数的key要与对应方法的形参变量名一致才能完成赋值操作。

4.1 零散类型的参数接收

@RequestMapping("param")
@Controller
public class ParamController {

    /**
     * 用于测试零散类型参数接收
     * 路径:http://localhost:8080/springMVC_war/param/test?username=老王&age=23
     * @return
     */
    @RequestMapping("test")
    public String test(String username,Integer age){
        System.out.println("username = " + username);
        System.out.println("age = " + age);
        return "index";
    }
}

4.2 对象类型的参数接收

  • 创建对象实体类

    public class User {
        private String username;
        private Integer age;
    
    
        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    
  • 对象作为控制器方法的形参,SpringMVC会自动完成请求参数到对象的封装:

    @RequestMapping("param")
    @Controller
    public class ParamController {
    
        /**
         * 用于测试对象类型参数接收
         * 路径:http://localhost:8080/springMVC_war/param/test?username=老王&age=23
         * @return
         */
        @RequestMapping("test")
        public String test(User user){
            System.out.println("user = " + user);
            return "index";
        }
    }
    

    注意:springmvc封装对象时直接根据传递参数key与对象中属性名一致自动封装对象。

4.3 数组或集合类型的参数接收

  • 数组类型参数的接收:

    @RequestMapping("param")
    @Controller
    public class ParamController {
    
        /**
         * 用于测试对象类型参数接收
         * 路径:http://localhost:8080/springMVC_war/param/test?names=老王&names=james
         * @return
         */
        @RequestMapping("test")
        public String test(String[] names){
            System.out.println("names = " + Arrays.toString(names));
            return "index";
        }
    }
    
  • 集合类型参数的接收:

    • 注意:

      SpringMVC不能直接通过形参列表方式收集集合类型参数.
      如果要接收集合类型的参数必须将集合放入对象中接收才可以,推荐放入VO对象中接收集合类型
      VO --> Value Object 值对象
      
    • 创建VO类,将集合作为其成员变量:

      public class CollectionVO {
          private List<String> names;
      
          public List<String> getNames() {
              return names;
          }
      
          public void setNames(List<String> names) {
              this.names = names;
          }
      }
      
    • 将VO对象作为控制器方法的形参,SpringMVC会自动将集合参数封装到VO对象的成员变量中:

      @RequestMapping("param")
      @Controller
      public class ParamController {
      
          /**
           * 用于测试集合类型参数接收
           * 路径:http://localhost:8080/springMVC_war/param/test?names=老王&names=james
           * @return
           */
          @RequestMapping("test")
          public String test(CollectionVO collectionVO){
              collectionVO.getNames().forEach(str-> System.out.println("str = " + str));
              return "index";
          }
      }
      

5.SpringMVC两种请求方式出现中文乱码

5.1 GET方式的请求出现乱码

tomcat8.x版本之前:默认使用server.xml 中URIEncoding = "iso-8859-1"编码不是utf-8,所以会出现中文乱码

tomcat8.x版本之后:默认使用server.xml 中URIEncoding = “utf-8”,解决了中文乱码问题

5.2 POST方式的请求出现乱码

  • 解决方案:

    1. 自定义filter,设置request和response对象编码为utf-8:

      /**
       * @Author:Unique.L
       * @Date: 2020/11/4 12:15
       * @Description: 自定义编码的Filter类
       */
      public class MyCharacterEncodingFilter implements Filter {
          private String encoding;
          /**
           * 在Filter类的初始化方法中获取配置的信息,赋值给成员变量
           * @param filterConfig
           * @throws ServletException
           */
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              this.encoding = filterConfig.getInitParameter("encoding");
          }
      
          /**
           * 通过filter过滤器设置request和response对象编码为指定的编码
           * @param servletRequest
           * @param servletResponse
           * @param filterChain
           * @throws IOException
           * @throws ServletException
           */
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              servletRequest.setCharacterEncoding(encoding);
              servletResponse.setCharacterEncoding(encoding);
              filterChain.doFilter(servletRequest,servletResponse);
          }
      
          @Override
          public void destroy() {
      
          }
      }
      
      <!--使用自定义的编码filter,解决post请求的中文乱码-->
      <filter>
        <filter-name>charset</filter-name>
        <filter-class>com.itheima.springmvc.filter.MyCharacterEncodingFilter</filter-class>
        <init-param>
          <param-name>encoding</param-name>
          <param-value>utf-8</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>charset</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      
    2. 使用springmvc提供好的编码filter:CharacterEncodingFilter

      <!--使用springmvc提供好的编码filter,解决post请求的中文乱码问题-->
      <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>
        <init-param>
          <param-name>forceRequestEncoding</param-name>
          <param-value>true</param-value>
        </init-param>
        <init-param>
          <param-name>forceResponseEncoding</param-name>
          <param-value>true</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      

6.SpringMVC中的数据传递机制

6.1 数据传递机制

数据怎么存储?数据在页面如何获取?在页面中获取的数据该如何展示?
Servletrequest,
session,
application
EL表达式EL+JSTL标签 展示
Struts2request,
session,
application
EL表达式EL+JSTL标签 展示
SpringMVCrequest,
session,
application
EL表达式EL+JSTL标签 展示

6.2 存数据具体使用哪种作用域?

具体使用哪种作用域,取决于跳转方式:

  • forward(一次请求):使用request作用域(Model(SpringMVC提供));
  • redirect(多次请求):使用session作用域、application作用域【不推荐】、?地址栏传递数据(少量数据)

6.3 SpringMVC控制器方法中获取request对象和response对象

/**
 * 注解将request、response对象作为控制器方法参数声明即可获取
 * @param request
 * @param response
 * @return
 */
@RequestMapping("findAll")
public String findAll(HttpServletRequest request, HttpServletResponse response){
    request.getSession();
    request.getSession().getServletContext();
    return "index";
}

6.4 SpringMVC两种请求方式的参数传递

@Controller
@RequestMapping("attr")
public class AttrController {

    /**
     * 使用forward跳转页面传递数据
     * @return
     */
    @RequestMapping("test")
    public String test(Model model, HttpServletRequest request){
        //1.零散类型的数据
        String name = "小城";
        request.setAttribute("name",name);
        //2.对象类型的数据
        User user = new User("James",36);
        model.addAttribute("user",user);
        //3.集合类型的数据
        List<String> list = Arrays.asList("asd", "123");
        model.addAttribute("list",list);
        return "attr";
    }

    /**
     * 使用redirect跳转页面传递数据
     * @return
     */
    @RequestMapping("test1")
    public String test1(HttpServletRequest request) throws UnsupportedEncodingException {
        //1.使用session域传递数据
        HttpSession session = request.getSession();
        User user = new User("James",36);
        session.setAttribute("user",user);
        //2.使用?地址值传递少量数据
        return "redirect:/attr.jsp?name="+ URLEncoder.encode("小王","UTF-8");
    }
}

7.Spring+SpringMVC+MyBatis整合

  • 引入依赖

    spring、springmvc、mybatis、mybatis-spring、mysql、druid、log4j、servlet-api、jstl、fastjson等
    
  • SM整合

    1. 建表
    2. 实体类
    3. DAO接口
    4. Mapper文件
    5. Service接口
    6. Service实现类,加上@Service、@Transactional,注入DAO对象
    7. 引入spring的applicationContext.xml编写Spring整合MyBatis的配置:
      • 开启注解扫描:<context:component-scan base-package=“com.itheima”/>
      • 创建数据源对象datasource,注入四大属性
      • 创建SqlSessionFactoryBean,注入datasource,mapperLocations,typeAliasesPackage
      • 创建MapperScannerConfigurer,注入basePackage、sqlSessionFactoryBeanName
      • 创建DataSourceTransactionManager,注入datasource
      • 开启注解式事务控制驱动:<tx:annotation-driven transaction-manager=“transactionManager”/>
    8. 测试Service方法调用
  • SS整合

    1. 配置web.xml

      • 启动工厂监听器 ContextLoaderListener

        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        
      • 配置工厂配置文件 applicationContext.xml:

        <context-param>
        	<param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
        
      • 配置springmvc的核心前端控制器 DispatcherServlet:

      • 配置springmvc接收post请求的中文乱码问题,CharacterEncodingFilter:

    2. 引入springmvc.xml配置

      • 开始注解扫描
      • 配置处理器映射器 及 处理器适配器
      • 配置视图解析器
    3. 开发Controller,加上@Controller、@RequestMapping,注入XxxService。

    4. 服务器部署进行访问测试。

8.SpringMVC中的静态资源拦截问题

8.1 出现静态资源拦截问题的原因

由于在web.xml中配置springmvc的核心servlet DispatcherServlet 时url-pattern 配置为“/”,
因此会导致项目中所有/开头的请求,均被作为控制器请求处理,这样会导致项目中的静态资源(css\js\img)被拦截

8.2 解决方案

  1. 更改url-pattern,不使用“/”,而是使用“*.do”的形式。

    • 存在的弊端:使用这种方式日后访问路径结尾必须加上指定的后缀 url.do
  2. url-pattern继续使用“/”,在springmvc.xml配置文件中加入如下配置:

    <mvc:default-servlet-handler/>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值