AmazingCounters.com

SpringMVC 的初理解

  项目中用到了jetty,springboot两种构建服务器的方式,jetty是一种嵌入式的方式,部署启动都很灵活,springboot最大的优点就是很多配置文件都自己集成好了,虽然用了这么多好的框架,但是我最近又迷茫了,这些框架到底是什么?怎么处理的?因此我又开始翻看了Tomcat,结合之前的学习和一些博客文章,记录一下,加深理解。

  在写SpringMVC的时候,其实我们就是在写一个servlet。Tomcat即是一个HTTP服务器,也是一个servlet容器,主要目的就是包装servlet,并对请求响应相应的servlet,纯servlet的web应用似乎很好理解Tomcat是如何装载servlet的。

1、什么是servlet?

Servlet是sun公司提供的一门用于开发动态web资源的技术。

2、如何编写一个servlet?

  2.1、编写一个Java类,实现HttpServlet接口,HttpServlet是在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。该类实现了Servlet的service方法,在方法体内判定了调用的是get,post,put,delete方法。如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。用户只要根据自己的需求重写doGet,doPost方法就可以了。
  2.2、把开发好的Java类部署到web服务器中。

  2.3、用浏览器发送请求就可以。这里我用postman发送一个请求。

  请求的地址:localhost:8080/ServletStudy/servlet/ServletDemo

1
2
3
4
5
6
7
8
9
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
    <HEAD>
        <TITLE>A Servlet</TITLE>
    </HEAD>
    <BODY>
    This is class servlet.study.ServletDemo, using the GET method
  </BODY>
</HTML>

如果是浏览器发送的请求,那么浏览器就会解析上面这段html

3、下面是一个servlet的实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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_3_0.xsd"
         version="3.0"
         metadata-complete="true">
 <servlet-name>list</servlet-name>
    <!-- 告诉容器,类完整的名字  包名.类名 -->
    <servlet-class>web02.ListEmpServlet1</servlet-class>  
   </servlet>  
<servlet-mapping>
        
    <servlet-name>list</servlet-name>
        
    <url-pattern>/list</url-pattern>  
         
 </servlet-mapping>
 
</web-app>

  

  

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package web02;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
 
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class ListEmpServlet extends HttpServlet  {
    public void service(HttpServletRequest request,HttpServletResponse response)
            throws ServletException,IOException{
         
                response.setContentType("text/html;charset=utf-8");
                 
                PrintWriter out=response.getWriter();
                 
                Connection conn=null;
                 
                try {
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                    try {
                        conn=DriverManager.getConnection("jdbc:oracle:thin:@10.10.141.151:1521:orcl",
                                "wwj",
                                "Admin@1234");
                         
                         
                        out.println("<table width='60%' border ='1' cellpadding='0' cellspacing='0'>");
                                out.println( "<tr><td>姓名</td><td>薪水</td><td>年龄</td>"
                                        + "</tr>");
                        String sql=("SELECT name,salary,age from servlet_wu");
                         
                        PreparedStatement stat=conn.prepareStatement(sql);
                         
                        ResultSet rst=stat.executeQuery();
                                         
                     
                        while(rst.next())                      
                        {
                             String uname=rst.getString("name");
                             Double salary=rst.getDouble("salary");
                             int age=rst.getInt("age");
                            out.println("<tr>"
                                    + "<td>"+uname
                                    + "</td><td>"+salary
                                    + "</td><td>"+age
                                    +"</td></tr>");
                        }
                        out.println("</table>");
                                 
                        //out.println("添加员工成功");//这句话在重定向之后会被清除,想要输出
                        //需要用脚本JS
                        response.sendRedirect("list");
                         
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } catch (ClassNotFoundException e) {
                    // 记日志
                    e.printStackTrace();
                     
                }
                 
                out.close();//关流或者servlet关闭后,服务器就会从响应对象中
         
     
    }
         
}

看到这个实例可以清楚的看到,一个servlet里面包括了很多,主要有:请求数据的解析,连接数据库,解析数据,返回给浏览器。一个两个还好维护,也很轻松,但是如果有十个,百个,千个呢?不敢想象。为了解决这个问题,MVC思想被应用过来,解救了广大的程序猿。

4、spring web mvc的原理图如下。

加载过程原理分析:

整个MVC的中心是dispatcherServlet,它处理了controller类的加载,请求地址与controller的映射,viewResolver类的处理,就是所谓的MVC。

1
2
3
4
5
6
7
8
9
10
11
protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
    initFlashMapManager(context);
}

这些都是初始化的时候需要做的事。

当用户的请求过来之后,具体流程步骤如下:
1、 首先用户发送请求——>DispatcherServlet,前端控制器收到请求后委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、 DispatcherServlet——>HandlerMapping。ApplicationContext.xml中id=handlermapping类会将请求的地址与控制器对应的map,然后DispatcherServlet类会把请求地址与servlet对应上。加载applicationContext.xml中的bean对应的类,处理viewresolver。
3、 HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
4、 ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
5、 View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
6、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

下面是我之前自己写的一个例子:

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContextmvc.xml</param-value>
        </init-param>
        <!-- 启动tomcat之后优先启动 -->
        <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
 
</web-app>  

applicationContext.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
49
50
51
52
53
54
55
56
57
58
59
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:p="http://www.springframework.org/schema/p"
     xmlns:util="http://www.springframework.org/schema/util"
     xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:cache="http://www.springframework.org/schema/cache" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd 
    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.xsd 
    http://www.springframework.org/schema/jdbc 
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd 
    http://www.springframework.org/schema/cache 
    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd 
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util.xsd"> 
    
    
   <!-- 配置handlerMapping -->
   <bean id="handlermapping"   class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
   <!-- 请求和controller对应的关系 -->
   <property name="mappings">
           <props>
            <prop key="/list.do">listController</prop> 
            <prop key="/add.do">addController</prop>   
            <prop key="/modify.do">modifyController</prop>
            <prop key="/delete.do">deleteController</prop>
             <prop key="/update.do">updateController</prop>   
           </props>
   </property>
   </bean>
   <!-- 配置controller -->
   <bean id="listController" class="springMVCmybatis.listController">  
   </bean>
   <bean id="addController" class="springMVCmybatis.addController">  
   </bean>
   <bean id="modifyController" class="springMVCmybatis.modifyController">  
   </bean>
   <bean id="deleteController" class="springMVCmybatis.deleteController">  
   </bean>
   <bean id="updateController" class="springMVCmybatis.updateController">  
   </bean>
   <!-- 配置viewResolver -->
   <bean id="viewresolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/">
    </property>
    <property name="suffix" value=".jsp">
    </property>
    </bean>
</beans>    

附言:

1、如果你看不懂springmvc的代码过程,可以先看看jetty的,有助于理解。

2、由于本人水平有限,有些地方写的模棱两可,后面再写详细点。

 

参考博客:

1、http://blog.csdn.net/tiantiandjava/article/details/47663853

2、http://jinnianshilongnian.iteye.com/blog/1594806

3、http://www.cnblogs.com/xdp-gacl/p/3760336.html

posted @   若谷先生  阅读(449)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示