Spring MVC起步(五)

ping MVC是基于模型-视图-控制器(Model-View-Controller,MVC)模式实现的Web层框架。

一个案例教你使用Spring MVC 构建Web应用程序。

我们还是以一张图来了解Spring MVC如何做到和前端页面交互的:

搭建Spring MVC

首先我们就需要导入jar,这在前面的文章中已经介绍了,不在赘述。(需要jar可以去Maven仓库进行下载)

  1. DispatcherServlet
    根据图示,页面请求首先走的就是Spring MVC的前端控制器DispatcherServlet,我们需要在web.xml中配置前端控制器Servlet:
    1
    2
    3
    4
    5
    
    <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.DispatcherServlet</servlet-class>
      <load-on>1</load-on>
    </servlet>
    

默认情况下,DispatcherServlet加载时会从一个基于这个Servlet名字的XML文件中加载Spring上下文。
接下来我们必须声明DispatcherServlet处理哪些URL:

1
2
3
4
<servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <url-pattern>/</pattern>
</servlet-mapping>

 

注意: 我们常见的配置此资源请求路径为*.do,这样,在浏览器的请求路径通常是xxx.do这样,但是存在暴露URL实现细节的问题。
所以我们通过将DispatcherServlet映射到/,声明了它作为默认的Servlet会处理所有请求,包括静态资源的请求。

  1. 命名空间
    同时,Spring提供了<mvc:resources>元素,让你更灵活的配置如何处理静态资源的请求。下面我们创建springmvc.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           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">
      <mvc:resources mapping="/resources/**" location="/resources/">
    </beans>
    

如上所示这个spring.xml并没有太大区别,仅仅是多了一个命名空间。当我们想对静态资源请求做处理,<mvc:resources>就正好满足了我们的需求:
属性mapping设置为/resources/**表明路径必须以/resources开始,而且包含其任意子路径;属性location定义了这里静态资源的存储位置。

  1. 处理器映射器和控制器
    配置前端控制器Servlet和Spring MVC的命名空间,下面我们应该配置Spring MVC的控制器(DispatcherServlet需要咨询一个或多个处理器映射来明确的将请求分发给哪个控制器)。Spring自带多个处理器映射:

    • BeanNameUrlHandlerMapping:根据Bean的名字将控制器映射到URL
    • ControllerBeanNameHandlerMapping:根据控制器Bean的名字将控制器映射到URL。(Bean的名字不需要遵循URL的约定)
    • ControllerClassNameHandlerMapping:通过使用控制器的类名作为URL基础将控制器映射到URL
    • DefaultAnnotationHandlerMapping:将请求映射给使用@RequestMapping注解的控制器和控制方法
    • SimpleUrlHandlerMapping:使用定义在Spring应用上下文的属性集合将控制器映射到URL
      如上几种控制器,因为我们使用@RequestMapping,所以以上控制器我们并不需要直接去使用,取而代之的是<mvc:annotation-driven>标签将自动为我们分配所需要的控制器。
  2. 视图解析器
    当前台request请求发送过来,先经过Spring MVC的DispatcherServlet前端控制器,然后经过Spring的处理器映射器和处理器控制器(Controller)对接收到URL信息进行处理;控制器会将处理后的信息(Model)返回给用户;之后再讲这些数据进行格式化,发送给一个视图(View);
    控制器最后再将这些模型视图数据打包,将渲染输出的模型和视图名称发送给DispatcherServlet;最后DispatcherServlet将使用视图解析器把逻辑视图名匹配为一定特定的视图实现。
    所以,接下来我们要配置视图解析器:

    1
    2
    3
    4
    5
    6
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 前缀 -->
            <property name="prefix" value="/WEB-INF/"/>
            <!-- 后缀 -->
            <property name="suffix" value=".jsp"/>
    </bean>
    

Spring MVC中常用InternalResourceViewResolver视图解析器根据我们定义的路径将视图解析到浏览器上。prefix表示模板视图(JSP)所在路径的前缀名,suffix表示模板视图的后缀名。
注意:
如果你的JSP放到了WEB-INF下,那么我们在浏览器上是无法直接访问的,必须通过控制层进行跳转,但同时这也保证了一定的安全性。所以我们习惯将JSP文件放到WEB-INF/下,将静态资源放到webapp下。

  1. 编写控制层
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    @Controller
    @RequestMapping(value="/user")
    public class UserController{
      
      @RequestMapping(value="/save", method = RquestMethod.POST)
      public String save(@RequestParam String username, @RequestParam String password, Model model){
        //逻辑处理
        return "save";
      }
    }
    

如上,这就是一个简单的控制器,我们接下来分析一下这个Controller:

  1. @Controller@Component注解的一种)表明了该类是一个控制器类(我们需要现在配置文件中配置扫描这个控制器类<context:component-scan>),<xontext:component-scan>会查找被@Component标注的类,将其注册为Bean。
  2. @RequestMapping注解有两个作用:1.表名此方法(save())是一个请求处理方法;2.指明了该方法要处理请求/save路径下的请求。所以我们看到@RequestMapping注解可以标注在类上和方法上,其实分别表示两种不同的作用范围,因为类包裹了方法。如我们现在的配置,就表示save()方法的在浏览器上的请求路径应该是:localhost:8080/(项目名)/user/save(如果我们指定了前端控制器DispatcherServlet的映射路径,如:*,do,那么save()方法的请求路径就应该是localhost:8080/(项目名)/user/save.do)。
  3. method=RequestMethod.POST指定了当前请求是POST请求
  4. return表明了该映射方法需要返回到哪里。首先我们观察该save()方法的返回值数据类型,那么设置为String在Spring MVC的映射方法中就表示要返回一个视图,我们只需要定义返回视图的名字,Spring MVC会根据视图解析器查找此名字对应的视图。如我们现在的配置返回的视图路径其实就是:/WEB-INF/save.jsp(在视图解析器中我们已经配置了前缀和后缀)。
  5. @RequestParam:该注解并不是必须的,它提供了一些属性如可以设置默认值等,在参数不匹配的时候有用,且对于当前我们这种请求包含多个参数时尽量使用@RequestParam,避免一些未知的问题。
  6. Model对象内部类似Map<String, Obeject>,且提供了一些方式用来设置值。通过Model对象的addAttribute()方法设置的值可以在JSP中用EL表达式取出来,类似放到了域对象中

入门案例

首先我们看一下项目目录结构(注意 :我这里使用的是IDEA+Maven),可能和大家的有所区别,但大家目前不要过分关注这些。

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">

    <display-name>Archetype Created Web Application</display-name>
    <welcome-file-list>
        <welcome-file>/WEB-INF/index.jsp</welcome-file>
    </welcome-file-list>

    <!-- 配置Spring的字符编码过滤器 -->
    <filter>
        <filter-name>CharacterEncoding</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>CharacterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- ContextLoaderListener监听器监听servlet的创建 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 告诉监听器需要加载那些配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/spring.xml</param-value>
    </context-param>

    <!-- Spring MVC的前端控制器 -->
    <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:spring/springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

注意之前没有介绍CharacterEncodingFilter,此过滤器是Spring提供的为避免request请求乱码问题而设定的。
配置Spring MVC的前端控制器时,包含了<init-param>标签旨在加载前端控制器时同时去加载Spring MVC的上下文。

spring.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

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

    <!-- 加载数据库资源配置文件 -->
    <context:property-placeholder location="classpath:resource/jdbc.properties"/>

    <!-- 配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 注入Bean -->
    <bean id="userService" class="service.UserServiceImp"/>
    <bean id="userDao" class="dao.UserDaoImp">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

注意这里配置连接池我们使用的是加载外置的属性文件:jdbc.properties,使用<context:property-placeholder>加载。

springmvc.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
         http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 扫描Controller层 -->
    <context:component-scan base-package="controller"/>

    <!-- 处理静态资源 -->
    <mvc:resources mapping="/resources/**" location="/resources/"/>

    <!-- 一个注解实现配置:BeanNameUrlHandlerMapping(处理器映射器)和DefaultAnnotationHandlerMapping(处理器控制器) -->
    <mvc:annotation-driven/>

    <!-- 配置Spring MVC视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/"/>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

Controller层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Controller
@RequestMapping(value = "/user")
public class UserController {

    //注入
    @Autowired
    private UserService userService;

    //跳转到添加用户信息页
    @RequestMapping(value="/savePage")
    public String savePage(){
        return "view/save";
    }

    //保存用户
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(@RequestParam String username,@RequestParam String password, Model model){
        userService.save(username,password);
        model.addAttribute("message","保存数据成功");
        return "view/success";
    }
}

如果我们想要访问保存信息的JSP页面,应在浏览器中输入:localhost:8080/user/savePage;而保存表单信息方法的路径是:localhost:8080/user/save

Service层

  1. UserService

    1
    2
    3
    
    public interface UserService {
        void save(String username, String password);
    }
    
  2. UserServiceImp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    @Transactional
    public class UserServiceImp implements UserService {
    
        @Autowired
        private UserDao userDao;
    
        //保存
        public void save(String username, String password) {
            userDao.save(username,password);
        }
    }
    

@Transaction标识该类,Spring会为该类设置事务性性通知(配合<tx:annotation-driven>

Dao层

  1. UserDao

    1
    2
    3
    
    public interface UserDao {
        void save(String username, String password);
    }
    
  2. UserDaoImp

    1
    2
    3
    4
    5
    6
    7
    8
    
    public class UserDaoImp extends JdbcDaoSupport implements UserDao {
    
        //保存数据
        public void save(String username, String password) {
            //使用Spring提供的JDBC模板可以直接执行SQL语句
            this.getJdbcTemplate().update("insert into user(id,username,password) values(?,?,?)",null,username,password);
        }
    }
    

这里我们仍使用的是Spring提供的JDBC模板类,只需要dao继承这个模板类即可。使用JdbcDaoSupportgetJdbcTemple()方法执行SQL语句。(this表示当前对象)

前端页面

  1. save.jsp
1
2
3
4
5
6
7
<h2>表单</h2>
<hr/>
<form action="<%=basePath%>/user/save" method="post">
    username: <input type="text" name="username"/><br/>
    password: <input type="password" name="password"/><br/>
    <input type="submit" value="提交"/>
</form>
  1. success.jsp
1
2
3
4
5
6
7
8
9
<head>
    <title>Title</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>${message}</h1>
</body>
</html>

运行

首先我们需要把项目部署到Tomcat服务器上,然后启动Tomcat:

没有报错,接下来我们来浏览器中输入我们项目中添加页面的访问路径:localhost:8080/user/savePage

我们输入中文信息,并点击提交,通过断点查看:

后台映射方法save()接收到了JSP表单传递进来的参数,并且中文没有乱码(如果没有配置CharacterEncodingFilter就可能乱码)。继续执行:

当我们的request请求经控制层处理完毕后,DispatcherServlet将视图数据返回到页面上,我们return已经设置了返回页面/WEB-INF/view/success.jsp,那么请求成功就会返回到该页面上。并且我们在success.jsp中用EL表达式取出来了message这个属性的值,当我们在Controller控制层设置了message值为数据保存成功,就相当于保存进了request域中一个名为message的值。

数据库:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 5 Design Patterns is for all Java developers who want to learn Spring for the enterprise application. Therefore, enterprise Java developers will find it particularly useful in the understanding of design patterns used by the Spring Framework and how it solves common design problems in the enterprise application, and they will fully appreciate the examples presented in this book. Before reading this book, readers should have basic knowledge of Core Java, JSP, Servlet, and XML. Spring 5 Framework is newly launched by Pivotal with reactive programming. Spring 5 introduces many new features and enhancements from its previous version. We will discuss all this in the book. Spring 5 Design Patterns will give you in-depth insight about the Spring Framework. The great part of today's Spring Framework is that all companies have already taken it as a primary framework for development of the enterprise application. For Spring, no external enterprise server is needed to start working with it. The goals of writing this book are to discuss all design patterns used behind the Spring Framework and how they are implemented in the Spring Framework. Here, the author has also given you some best practices that must be used in the design and development of the application. The book contains 12 chapters that cover everything from the basics to more complex design pattern such as reactive programming. Spring 5 Design Patterns is divided into three sections. The first section introduces you to the essentials of the design patterns and the Spring Framework. The second section steps behind the front end and shows where Spring fits in the back end of an application. The third section expands on this by showing how to build web applications with Spring and introducing a new feature of the Spring 5 reactive programming. This part also shows how to handle concurrency in the enterprise application.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值