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容器。

相關文章
相關標籤/搜索