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

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

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

  代码详解:java

  (1) 建立Servlet:web

 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容器很大,很好资源,不适宜建立屡次。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页面:app

 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 容器就又不惟一了。jsp

    解决方法:使用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容器。

相关文章
相关标签/搜索