SpringMVC基础(1)——简介、入门程序、请求参数绑定、自定义类型转换器

目录

1.SpringMVC介绍

2.入门程序

(1)需求:

(2)入门环境搭建:

(3)实现代码

(4)上述代码的流程总结

(5)入门案例中涉及的组件

(6)@RequestMapping

3.请求参数的绑定

(1)支持的各数据类型演示

(2)请求参数乱码问题

1)post方式

2)get方式

4.自定义类型转换器

(1)SpringMVC中类型转换分析

(2)自定义类型转换器

5.获取Servlet原生的API


1.SpringMVC介绍

 

2.入门程序

(1)需求:

客户端点击超链接,发送请求,服务端执行相应的处理方法,方法执行成功后,转发到成功jsp页面

(2)入门环境搭建:

创建maven项目

解决maven项目创建过慢问题

补全maven的目录结构

在pom.xml中导入依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.cqu</groupId>
  <artifactId>springMVC_Demo01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>


  <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>

      <!--  版本锁定  -->
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <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.0</version>
      <scope>provided</scope>
    </dependency>
    
  </dependencies>

  <build>
    <plugins>
      <!--   集成tomcat7插件   -->
      <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <artifactId>tomcat7-maven-plugin</artifactId>
          <version>2.2</version>
          <configuration>
            <uriEncoding>UTF-8</uriEncoding>
            <port>8888</port>
            <path>/</path>
          </configuration>
      </plugin>
    </plugins>
  </build>


</project>

在web.xml中配置核心的前端控制器

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!-- 核心的前端控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

在src/main/resources下新建一个spring的配置文件springmvc.xml

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

</beans>

部署项目

因为我们在pom.xml中集成了tomcat7

所以我们可以直接使用maven集成的tomcat一键构建部署运行项目

(3)实现代码

在webapp目录下重新写一个index.jsp

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门程序</h3>
    <a href="/hello">入门程序</a>
</body>
</html>

HelloController.java

package cn.cqu.controller;

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

/**
 * 控制器类
 * 接受请求
 */

//把这个类交给spring来管理
@Controller
public class HelloController {

    //请求映射,/hello即为这个方法的请求路径
    @RequestMapping(path="/hello")
    public String sayHello(){
        System.out.println("Hello springMVC");
        return "success";//此处默认返回的是jsp的名字
    }
}

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
                http://www.springframework.org/schema/mvc/spring-mvc.xsd
                http://www.springframework.org/schema/context
		        http://www.springframework.org/schema/context/spring-context.xsd">

        <!--  开启注解扫描  -->
        <context:component-scan base-package="cn.cqu"/>

        <!--视图解析器-->
        <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/pages/"/>
                <property name="suffix" value=".jsp"/>
        </bean>

        <!--开启springMVC框架注解的支持-->
        <mvc:annotation-driven/>
</beans>

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!-- 核心的前端控制器 -->
  <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:springmvc.xml</param-value>
    </init-param>
    <!--启动服务器时
          创建DispatcherServlet对象,
          加载配置文件springmvc.xml,
          然后扫描注解生效
          然后控制器类会被扫到,就有了该类的对象
          然后一发请求,该路径映射到的方法就能被执行了
    -->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>入门成功</title>
</head>
<body>
    <h3>入门成功</h3>
</body>
</html>

部署

访问

           

(4)上述代码的流程总结

(5)入门案例中涉及的组件

  • (1)DispatcherServlet:前端控制器

用户请求到达前端控制器,它相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性

  • (2)HandlerMapping:处理器映射器

HandlerMapping负责根据用户请求找到Handler即处理器,SpringMVC提供了不同的映射器实现不同的映射方式,例如,配置文件方式,实现接口方式,注解方式等

  • (3)Handler:处理器

它就是我们开发中要编写的具体业务控制器,由DispatcherServlet把用户请求转发到Handler,由Handler对具体的用户请求进行处理

  • (4)HandlerAdapter:处理器适配器

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行

  • (5)View Resolver:视图解析器

View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户

  • (6)View:视图

SpringMVC框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等,我们最常用的视图就是jsp

  • (7)<mvc:annotation-driven>说明
    • SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
    • 使 用 <mvc:annotation-driven> 自动加载 RequestMappingHandlerMapping (处理映射器)和 RequestMappingHandlerAdapter ( 处 理 适 配 器 ) 
    • 可 用 在 SpringMVC.xml 配 置 文 件 中 使 用
    • <mvc:annotation-driven>替代注解处理器和适配器的配置。

它就相当于在 xml 中配置了:

<!-- ================HandlerMapping=========== --> 

<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerM
apping"></bean> 
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- ===============HandlerAdapter===============--> 
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA
dapter"></bean> 
<bean
class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean> 
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- ====================HadnlerExceptionResolvers=============== --> 
<bean
class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExcept
ionResolver"></bean> 
<bean
class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolv
er"></bean> 
<bean
class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"
></bean>

明确:

  • 我们只需要编写处理具体业务的控制器以及视图。

(6)@RequestMapping

  • 作用:
    • 用于建立请求 URL 和处理请求方法之间的映射关系。即请求访问的注解中配置的URL路径,就会执行相应的方法

  • 出现位置:可以出现在类上或方法上

    • 类上: 请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以/开头。

      • 它出现的目的是为了使我们的 URL 可以按照模块化管理:

      • 例如:

        • 账户模块:

        • /account/add

        • /account/update

        • /account/delete

          ...

        • 订单模块:

        • /order/add

        • /order/update

        • /order/delete

      • 红色的部分就是把 RequsetMappding 写在类上,使我们的 URL 更加精细。
    • 方法上:
      • 请求 URL 的第二级访问目录。

  • 属性:

    • value或path:用于指定请求的 URL

    • method:用于指定请求的方式。

    • params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的 key value 必须和配置的一模一样。

      • 例如:

        • params = {"accountName"},表示请求参数必须有 accountName

        • params = {"money!=100"},表示请求参数中money不能是100

    • headers:用于指定限制请求头的条件

    • 注意:以上四个属性只要出现2个或以上时,他们的关系是与的关系

3.请求参数的绑定

请求绑定:客户端发送来的请求中带着请求参数,而我们在控制器拿到参数的过程称作请求参数绑定

SpringMVC 绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。

示例1:

<a href="account/findAccount?accountId=10">查询账户</a>
中请求参数是:
        accountId=10

/**
 * 查询账户
* @return
*/
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
    System.out.println("查询了账户。。。。"+accountId);
    return "success"; 
}

注意:提交表单的name和接受方法中的参数的名称是相同的

(1)支持的各数据类型演示

  • 基本类型参数:包括基本类型和 String 类型
  • 此处参见上述示例1
  • POJO 类型参数:包括实体类,以及关联的实体类
    • param.jsp
    • <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>请求参数绑定</title>
      </head>
      <body>
          <form action="param/saveAccount" method="post">
              <%--    以下input中的name必须与Account中的字段名称一样,因为会通过name去查找它对应的set方法    --%>
              姓名:<input type="text" name="username"/><br>
              密码:<input type="password" name="password"/><br>
              金额:<input type="text" name="money"/><br>
              用户的姓名:<input type="text" name="user.uname"/><br>
              用户的年龄:<input type="text" name="user.age"/><br>
              <input type="submit" name="提交"/>
          </form>
      </body>
      </html>
    • User.java
    • package cn.cqu.domain;
      
      import java.io.Serializable;
      
      public class User implements Serializable {
          private String uname;
          private Integer age;
      
          public String getUname() {
              return uname;
          }
      
          public void setUname(String uname) {
              this.uname = uname;
          }
      
          public Integer getAge() {
              return age;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "User='" + uname + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
    • Account.java
    • package cn.cqu.domain;
      
      import java.io.Serializable;
      
      public class Account implements Serializable {
          private String username;
          private String password;
          private Double money;
          private User user;
      
          public String getUsername() {
              return username;
          }
      
          public void setUsername(String username) {
              this.username = username;
          }
      
          public String getPassword() {
              return password;
          }
      
          public void setPassword(String password) {
              this.password = password;
          }
      
          public Double getMoney() {
              return money;
          }
      
          public void setMoney(Double money) {
              this.money = money;
          }
      
          public User getUser() {
              return user;
          }
      
          public void setUser(User user) {
              this.user = user;
          }
      
          @Override
          public String toString() {
              return "Account{" +
                      "username='" + username + '\'' +
                      ", password='" + password + '\'' +
                      ", money=" + money +
                      ", user=" + user +
                      '}';
          }
      }
      
    • ParamController.java
    • package cn.cqu.controller;
      
      import cn.cqu.domain.Account;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      
      /**
       * 请求参数绑定绑定把数据封装到JavaBean的类当中
       */
      @Controller
      @RequestMapping("/param")
      public class ParamController {
          @RequestMapping("/saveAccount")
          public String saveAccount(Account account)
          {
              System.out.println("执行了。。。");
              System.out.println(account);
              return "success";
          }
      }
      
  • 数组和集合类型参数:包括 List 结构和 Map 结构的集合(包括数组)
  • param.jsp
  • <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>请求参数绑定</title>
    </head>
    <body>
        <%--把数据封装在Account类中,类中存在list和map的集合--%>
        <form action="param/saveAccount" method="post">
            <%--    以下input中的name必须与Account中的字段名称一样,因为会通过name去查找它对应的set方法    --%>
            姓名:<input type="text" name="username"/><br>
            密码:<input type="password" name="password"/><br>
            金额:<input type="text" name="money"/><br>
            用户1的姓名:<input type="text" name="list[0].uname"/><br>
            用户1的年龄:<input type="text" name="list[0].age"/><br>
    
            用户2的姓名:<input type="text" name="map['one'].uname"/><br>
            用户2的年龄:<input type="text" name="map['one'].age"/><br>
            <input type="submit" name="提交"/>
        </form>
    </body>
    </html>
    
  • User.java
  • package cn.cqu.domain;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private String uname;
        private Integer age;
    
        public String getUname() {
            return uname;
        }
    
        public void setUname(String uname) {
            this.uname = uname;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "User='" + uname + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
  • Account.java
  • package cn.cqu.domain;
    
    import java.io.Serializable;
    import java.util.List;
    import java.util.Map;
    
    public class Account implements Serializable {
        private String username;
        private String password;
        private Double money;
        private List<User> list;
        private Map<String,User> map;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Double getMoney() {
            return money;
        }
    
        public void setMoney(Double money) {
            this.money = money;
        }
    
        public List<User> getList() {
            return list;
        }
    
        public void setList(List<User> list) {
            this.list = list;
        }
    
        public Map<String, User> getMap() {
            return map;
        }
    
        public void setMap(Map<String, User> map) {
            this.map = map;
        }
    
        @Override
        public String toString() {
            return "Account{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", money=" + money +
                    ", list=" + list +
                    ", map=" + map +
                    '}';
        }
    }
    
  • ParamController.java
  • package cn.cqu.controller;
    
    import cn.cqu.domain.Account;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * 请求参数绑定绑定把数据封装到JavaBean的类当中
     */
    @Controller
    @RequestMapping("/param")
    public class ParamController {
        @RequestMapping("/saveAccount")
        public String saveAccount(Account account)
        {
            System.out.println("执行了。。。");
            System.out.println(account);
            return "success";
        }
    }
    

SpringMVC 绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求。

(2)请求参数乱码问题

1)post方式

  • 配置中文乱码的过滤器:(在web.xml中配置)

springmvc 的配置文件中可以配置,静态资源不过滤:

  • <!-- location 表示路径,mapping 表示文件,**表示该目录下的文件以及子目录的文件 -->
    • <mvc:resources location="/css/" mapping="/css/**"/>
    • <mvc:resources location="/images/" mapping="/images/**"/>
    • <mvc:resources location="/scripts/" mapping="/javascript/**"/>

2)get方式

tomacat GET POST 请求处理方式是不同的,GET 请求的编码问题,要改 tomcat server.xml

配置文件,如下:

<Connector connectionTimeout="20000" port="8080"  protocol="HTTP/1.1" redirectPort="8443"/>
改为:
<Connector connectionTimeout="20000" port="8080"  protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>


如果遇到 ajax 请求仍然乱码,请把:
useBodyEncodingForURI="true"改为 URIEncoding="UTF-8"
即可。

4.自定义类型转换器

(1)SpringMVC中类型转换分析

页面提交的任何数据都是字符串类型,而在我们传给控制器中的方法时,接受时,不一定时字符串,如上述的Account中Integer,Double类型等等,其实这是因为SpringMVC框架内部自动帮我们进行了数据类型转换,基本上常用的类型它都会帮我们转,我们做开发时不用去管,但是当我们存在一些特殊的格式的时候,它没办法帮我们自动转,这时,我们需要手动去解决,即自定义类型转换器

示例:

    

    

这种格式的日期,SpringMVC不能自动进行类型转换,不能完成封装数据,报错

(2)自定义类型转换器

使用步骤:

第一步:定义一个类,实现 Converter 接口,该接口有两个泛型。

package cn.cqu.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 把字符串转换为日期
 */
public class StringtoDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String  source) {
        //判断
        if(source == null)
        {
            throw new RuntimeException("请您传入数据");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //把字符串转换为日期
            return df.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("数据类型转换出现错误");
        }
    }
}

第二步:在 spring 配置文件中配置类型转换器。(如我这里是上述的springmvc.xml)

第三步:在 annotation-driven 标签中引用配置的类型转换服务

再次部署运行:

       

5.获取Servlet原生的API

SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。支持原始 ServletAPI 对象有:

  • HttpServletRequest 
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale
  • InputStream 
  • OutputStream 
  • Reader 
  • Writer

我们可以把上述对象,直接写在控制的方法参数中使用。

控制器中示例代码:

@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,
HttpServletResponse response,
HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success"; }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值