Spring4笔记11--SSH整合2--SpringWeb

SSH 框架整合技术:
  2. Spring 在 Web 项目中的使用(建立在Spring与Hibernate整合的基础上):

    在 Web 项目中使用 Spring 框架,首先要解决在 Servlet 中(暂时不使用 Struts2)获取到 Spring 容器的问题。只要在 View 层获取到了 Spring 容器,便可从容器中获取到 Service 对象。

  代码详解:

  (1) 创建Servlet:

 1 package com.tongji.servlets;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 import org.springframework.context.ApplicationContext;
11 import org.springframework.context.support.ClassPathXmlApplicationContext;
12 
13 import com.tongji.beans.Student;
14 import com.tongji.service.IStudentService;
15 
16 public class RegisterServlet extends HttpServlet {
17 
18     private static final long serialVersionUID = 4780732399020349670L;
19 
20     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21         doPost(request, response);
22     }
23 
24     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25         request.setCharacterEncoding("utf-8");
26         String name = request.getParameter("name");
27         String ageStr = request.getParameter("age");
28         Integer age = Integer.valueOf(ageStr);
29         System.out.println("name=" + name);
30         System.out.println("age=" + age);
31         
32         //从Spring容器中获取到Service
33         //创建容器
34         @SuppressWarnings("resource")
35         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
36         System.out.println("ac = " + ac);
37         
38         IStudentService service = (IStudentService) ac.getBean("studentService");
39         //调用Service的addStudent()方法
40         Student student = new Student(name, age);
41         service.addStudent(student);
42         //跳转到保存页面
43         request.getRequestDispatcher("/welcome.jsp").forward(request, response);
44     }
45 
46 }

    注意第36行,是为了显示每次请求是否使用的是同一Spring容器,即,是否只创建了一次Spring容器。Spring容器很大,很好资源,不适宜创建多次。

  (2) 在web.xml中注册Servlet:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="3.0"
 3     xmlns="http://java.sun.com/xml/ns/javaee"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 6   <servlet>
 7     <servlet-name>RegisterServlet</servlet-name>
 8     <servlet-class>com.tongji.servlets.RegisterServlet</servlet-class>
 9   </servlet>
10 
11   <servlet-mapping>
12     <servlet-name>RegisterServlet</servlet-name>
13     <url-pattern>/registerServlet</url-pattern>
14   </servlet-mapping>
15 
16 </web-app>

  (3) 创建前端JSP页面:

 1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 3 
 4 <html>
 5   <head>
 6     <title>index</title>
 7   </head>
 8   
 9   <body>
10     <form action="registerServlet" method="POST">
11         name:<input type="text" name="name"/><br>
12         age:<input type="text" name="age"/><br>
13         <input type="submit" value="submit"/>
14     </form>
15   </body>
16 </html>
 1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
 2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 3 
 4 <html>
 5   <head>
 6     <title>welcome</title>
 7   </head>
 8   
 9   <body>
10     welcome you!
11   </body>
12 </html>

    (4)Service层和Dao层和实体类的代码,以及Spring的配置文件都不变,发布运行。会发现:前端的每一次请求都会创建一次Spring容器,显然不合适

      此时,可以考虑,将 Spring 容器的创建放在 Servlet 进行初始化时进行,即执行 init()方法时执行。并且,Servlet 还是单例多线程的,即一个业务只有一个 Servlet 实例,所有执行该业务的用户执行的都是这一个 Servlet 实例。这样,Spring 容器就具有了唯一性了。  但是,Servlet 是一个业务一个 Servlet 实例,即 LoginServlet 只有一个,但还会有StudentServlet、TeacherServlet 等。每个业务都会有一个 Servlet,都会执行自己的 init()方法,也就都会创建一个 Spring 容器了。这样一来,Spring 容器就又不唯一了。

    解决方法:使用Spring的Web插件

    对于 Web 应用来说,ServletContext 对象是唯一的,一个 Web 应用,只有一个ServletContext 对象。该对象是在 Web 应用装载时初始化的,即在 Web 应用装载时会自动执行接口 ServletContext 的初始化方法。该初始化方法在整个应用中只会执行一次。若将Spring 容器的创建语句放到 ServletContext 的初始化方法中执行,并将创建好的 Spring 容器作为 ServletContext 的属性放入其中。以后再需要 Spring 容器,直接读取该属性值即可。ServletContext 对象生命周期与 Web 应用的相同。即放在其中的属性为全局属性。所以,放入 ServletContext 中的 Spring 容器,在整个应用的生命周期中,均可被访问。这样就可以保证 Spring 容器在 Web 应用中的唯一性了。
    上述的这些工作,已经被封装在了如下的 Spring 的 Jar 包的相关 API 中: spring-web-4.2.1.RELEASE.jar

    代码修改:

    (1) 注册监听器 ContextLoaderListener
      若要在 ServletContext 初始化时创建 Spring 容器,就需要使用监听器接口 ServletContextListener 对 ServletContext 进行监听。Spring 为该监听器接口定义了一个实现类 ContextLoaderListener,专门用于在 ServletContext 初始化时创建 Spring 容器。

    

    

 

    (2) 指定 Spring 配置文件的位置<context-param/>
      ContextLoaderListener 在对 Spring 容器进行创建时,需要加载 Spring 配置文件。其默认的 Spring 配置文件位置与名称为:WEB-INF/applicationContext.xml。但,一般会将该配置文件放置于项目的 classpath 下,即 src 下,所以需要在 web.xml 中对 Spring 配置文件的位置及名称进行指定。

    

    以上两处修改均在web.xml中添加

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="3.0"
 3     xmlns="http://java.sun.com/xml/ns/javaee"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 6   <!-- 指定Spring配置文件的名称及位置 -->
 7   <context-param>
 8       <param-name>contextConfigLocation</param-name>
 9       <param-value>classpath:applicationContext.xml</param-value>
10   </context-param>
11   
12   <!-- 注册监听器 -->
13   <listener>
14       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
15   </listener>
16   
17   <servlet>
18     <servlet-name>RegisterServlet</servlet-name>
19     <servlet-class>com.tongji.servlets.RegisterServlet</servlet-class>
20   </servlet>
21 
22   <servlet-mapping>
23     <servlet-name>RegisterServlet</servlet-name>
24     <url-pattern>/registerServlet</url-pattern>
25   </servlet-mapping>
26 
27 </web-app>

    (3) 修改 Spring 配置文件中映射文件路径的写法
        导入的 Jar 包 spring-web 中代码要求,Spring 配置文件中映射文件的路径前必须添加classpath:,以表示其在类路径下。

       Spring配置文件修改处代码:

       

    (4) 通过 WebApplicationContextUtils 获取 Spring 容器
      工具类WebApplicationContextUtils有一个方法专门用于从ServletContext中获取Spring容器对象:getRequiredWebApplicationContext(ServletContext sc)

      查其源码,看其调用关系,就可看到其是从 ServletContext 中读取的属性值,即 Spring容器。 
      

      Servlet修改处代码:

      

     至此,重新发布运行,整个Web应用只会创建一个Spring容器。

posted @ 2017-02-05 10:12  拉夫德尔  阅读(253)  评论(0编辑  收藏  举报