Java深入

来源:互联网 发布:成都金沙房价 知乎 编辑:程序博客网 时间:2024/06/05 06:56

Servlet是什么

1. Servlet是服务器端运行的一个程序,是一个被编译好的Java类。它不是框架等。

2. Web容器的启动,需要依赖Servlet。当web服务器开始执行时,servlet类就被初始化

3. 当用户通过浏览器访问的时候,会输入URI,这个时候,web服务器就通过Servlet来分发请求执行不同的内容。


一般我们会使用Tomcat来运行Java的web项目。通常我们可以在web项目的目录中可以看到WEB-INF这样的文件夹。这个文件夹是受保护的,外部无法通过url来访问的。文件夹里面包含了web.xml以及classlibs目录。我们要将web项目运行起来,就得在web.xml中定义一个Servlet,因为定义了Servlet,web容器才能知道需要如何去分发请求进行业务处理的。

Servlet是有一个Jar包,里面包含了一些Servlet的相关设计和细节。


一个使用spring的Servlet的web.xml配置例子:

[html] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. <servlet>  
  2.     <servlet-name>apiServlet</servlet-name>  
  3.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.     <init-param>  
  5.         <param-name>contextConfigLocation</param-name>  
  6.         <param-value>classpath:spring-common.xml</param-value>  
  7.     </init-param>  
  8.     <load-on-startup>1</load-on-startup>  
  9. </servlet>  
  10. <servlet-mapping>  
  11.     <servlet-name>apiServlet</servlet-name>  
  12.     <url-pattern>/api/*</url-pattern>  
  13. </servlet-mapping>  



HttpServlet

HttpServlet是一个抽象类,具体的实现自己需要的Servlet需要通过继承该类来实现 。

HttpServlet中主要的几个方法:

方法用途doGet         处理HTTP GET请求doPost处理HTTP POST请求doPut处理HTTP PUT请求doDelete处理HTTP DELETE请求

Servlet最终调用的是service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost

可以看下HttpServlet类:

[java] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. package javax.servlet.http;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.io.OutputStreamWriter;  
  6. import java.io.UnsupportedEncodingException;  
  7. import java.lang.reflect.Method;  
  8. import java.text.MessageFormat;  
  9. import java.util.Enumeration;  
  10. import java.util.Locale;  
  11. import java.util.ResourceBundle;  
  12.   
  13. import javax.servlet.GenericServlet;  
  14. import javax.servlet.ServletException;  
  15. import javax.servlet.ServletOutputStream;  
  16. import javax.servlet.ServletRequest;  
  17. import javax.servlet.ServletResponse;  
  18.   
  19.   
  20. public abstract class HttpServlet extends GenericServlet  
  21.     implements java.io.Serializable  
  22. {  
  23.     private static final String METHOD_DELETE = "DELETE";  
  24.     private static final String METHOD_HEAD = "HEAD";  
  25.     private static final String METHOD_GET = "GET";  
  26.     private static final String METHOD_OPTIONS = "OPTIONS";  
  27.     private static final String METHOD_POST = "POST";  
  28.     private static final String METHOD_PUT = "PUT";  
  29.     private static final String METHOD_TRACE = "TRACE";  
  30.   
  31.     private static final String HEADER_IFMODSINCE = "If-Modified-Since";  
  32.     private static final String HEADER_LASTMOD = "Last-Modified";  
  33.       
  34.     private static final String LSTRING_FILE =  
  35.     "javax.servlet.http.LocalStrings";  
  36.     private static ResourceBundle lStrings =  
  37.     ResourceBundle.getBundle(LSTRING_FILE);  
  38.      
  39.   
  40.     public HttpServlet() { }  
  41.       
  42.     //处理HTTP的GET请求,你需要实现一个Servlet,然后实现该方法  
  43.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  44.     throws ServletException, IOException  
  45.     {  
  46.     String protocol = req.getProtocol();  
  47.     String msg = lStrings.getString("http.method_get_not_supported");  
  48.     if (protocol.endsWith("1.1")) {  
  49.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
  50.     } else {  
  51.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
  52.     }  
  53.     }  
  54.   
  55.     protected long getLastModified(HttpServletRequest req) {  
  56.     return -1;  
  57.     }  
  58.   
  59.   
  60.     protected void doHead(HttpServletRequest req, HttpServletResponse resp)  
  61.     throws ServletException, IOException  
  62.     {  
  63.     NoBodyResponse response = new NoBodyResponse(resp);  
  64.       
  65.     doGet(req, response);  
  66.     response.setContentLength();  
  67.     }  
  68.       
  69.     //实现HTTP POST请求  
  70.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  71.     throws ServletException, IOException  
  72.     {  
  73.     String protocol = req.getProtocol();  
  74.     String msg = lStrings.getString("http.method_post_not_supported");  
  75.     if (protocol.endsWith("1.1")) {  
  76.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
  77.     } else {  
  78.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
  79.     }  
  80.     }  
  81.   
  82.   
  83.     protected void doPut(HttpServletRequest req, HttpServletResponse resp)  
  84.     throws ServletException, IOException  
  85.     {  
  86.     String protocol = req.getProtocol();  
  87.     String msg = lStrings.getString("http.method_put_not_supported");  
  88.     if (protocol.endsWith("1.1")) {  
  89.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
  90.     } else {  
  91.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
  92.     }  
  93.     }  
  94.   
  95.   
  96.     protected void doDelete(HttpServletRequest req,  
  97.                 HttpServletResponse resp)  
  98.     throws ServletException, IOException  
  99.     {  
  100.     String protocol = req.getProtocol();  
  101.     String msg = lStrings.getString("http.method_delete_not_supported");  
  102.     if (protocol.endsWith("1.1")) {  
  103.         resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);  
  104.     } else {  
  105.         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);  
  106.     }  
  107.     }  
  108.       
  109.   
  110.     private Method[] getAllDeclaredMethods(Class c) {  
  111.   
  112.         if (c.equals(javax.servlet.http.HttpServlet.class)) {  
  113.             return null;  
  114.         }  
  115.   
  116.         Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());  
  117.         Method[] thisMethods = c.getDeclaredMethods();  
  118.       
  119.         if ((parentMethods != null) && (parentMethods.length > 0)) {  
  120.             Method[] allMethods =  
  121.                 new Method[parentMethods.length + thisMethods.length];  
  122.         System.arraycopy(parentMethods, 0, allMethods, 0,  
  123.                              parentMethods.length);  
  124.         System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,  
  125.                              thisMethods.length);  
  126.   
  127.         thisMethods = allMethods;  
  128.     }  
  129.   
  130.     return thisMethods;  
  131.     }  
  132.            
  133.     protected void doOptions(HttpServletRequest req, HttpServletResponse resp)  
  134.     throws ServletException, IOException  
  135.     {  
  136.     Method[] methods = getAllDeclaredMethods(this.getClass());  
  137.       
  138.     boolean ALLOW_GET = false;  
  139.     boolean ALLOW_HEAD = false;  
  140.     boolean ALLOW_POST = false;  
  141.     boolean ALLOW_PUT = false;  
  142.     boolean ALLOW_DELETE = false;  
  143.     boolean ALLOW_TRACE = true;  
  144.     boolean ALLOW_OPTIONS = true;  
  145.       
  146.     for (int i=0; i<methods.length; i++) {  
  147.         Method m = methods[i];  
  148.           
  149.         if (m.getName().equals("doGet")) {  
  150.         ALLOW_GET = true;  
  151.         ALLOW_HEAD = true;  
  152.         }  
  153.         if (m.getName().equals("doPost"))   
  154.         ALLOW_POST = true;  
  155.         if (m.getName().equals("doPut"))  
  156.         ALLOW_PUT = true;  
  157.         if (m.getName().equals("doDelete"))  
  158.         ALLOW_DELETE = true;  
  159.           
  160.     }  
  161.       
  162.     String allow = null;  
  163.     if (ALLOW_GET)  
  164.         if (allow==null) allow=METHOD_GET;  
  165.     if (ALLOW_HEAD)  
  166.         if (allow==null) allow=METHOD_HEAD;  
  167.         else allow += ", " + METHOD_HEAD;  
  168.     if (ALLOW_POST)  
  169.         if (allow==null) allow=METHOD_POST;  
  170.         else allow += ", " + METHOD_POST;  
  171.     if (ALLOW_PUT)  
  172.         if (allow==null) allow=METHOD_PUT;  
  173.         else allow += ", " + METHOD_PUT;  
  174.     if (ALLOW_DELETE)  
  175.         if (allow==null) allow=METHOD_DELETE;  
  176.         else allow += ", " + METHOD_DELETE;  
  177.     if (ALLOW_TRACE)  
  178.         if (allow==null) allow=METHOD_TRACE;  
  179.         else allow += ", " + METHOD_TRACE;  
  180.     if (ALLOW_OPTIONS)  
  181.         if (allow==null) allow=METHOD_OPTIONS;  
  182.         else allow += ", " + METHOD_OPTIONS;  
  183.       
  184.     resp.setHeader("Allow", allow);  
  185.     }  
  186.       
  187.      
  188.     protected void doTrace(HttpServletRequest req, HttpServletResponse resp)   
  189.     throws ServletException, IOException  
  190.     {  
  191.       
  192.     int responseLength;  
  193.       
  194.     String CRLF = "\r\n";  
  195.     String responseString = "TRACE "+ req.getRequestURI()+  
  196.         " " + req.getProtocol();  
  197.       
  198.     Enumeration reqHeaderEnum = req.getHeaderNames();  
  199.       
  200.     while( reqHeaderEnum.hasMoreElements() ) {  
  201.         String headerName = (String)reqHeaderEnum.nextElement();  
  202.         responseString += CRLF + headerName + ": " +  
  203.         req.getHeader(headerName);   
  204.     }  
  205.       
  206.     responseString += CRLF;  
  207.       
  208.     responseLength = responseString.length();  
  209.       
  210.     resp.setContentType("message/http");  
  211.     resp.setContentLength(responseLength);  
  212.     ServletOutputStream out = resp.getOutputStream();  
  213.     out.print(responseString);    
  214.     out.close();  
  215.     return;  
  216.     }         
  217.   
  218.     //最终所有的具体实现都是需要实现Service方法.容器最终调用的就是该方法  
  219.     protected void service(HttpServletRequest req, HttpServletResponse resp)  
  220.     throws ServletException, IOException  
  221.     {  
  222.     String method = req.getMethod();  
  223.         //这边通过HTTP的方法来判断,具体的HTTP METHOD,然后决定需要执行的方法名称。     
  224.     if (method.equals(METHOD_GET)) {  
  225.         long lastModified = getLastModified(req);  
  226.         if (lastModified == -1) {  
  227.         // servlet doesn't support if-modified-since, no reason  
  228.         // to go through further expensive logic  
  229.         doGet(req, resp);  
  230.         } else {  
  231.         long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);  
  232.         if (ifModifiedSince < (lastModified / 1000 * 1000)) {  
  233.             // If the servlet mod time is later, call doGet()  
  234.                     // Round down to the nearest second for a proper compare  
  235.                     // A ifModifiedSince of -1 will always be less  
  236.             maybeSetLastModified(resp, lastModified);  
  237.             doGet(req, resp);  
  238.         } else {  
  239.             resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);  
  240.         }  
  241.         }  
  242.   
  243.     } else if (method.equals(METHOD_HEAD)) {  
  244.         long lastModified = getLastModified(req);  
  245.         maybeSetLastModified(resp, lastModified);  
  246.         doHead(req, resp);  
  247.           
  248.     } else if (method.equals(METHOD_POST)) {  
  249.         doPost(req, resp);  
  250.           
  251.     } else if (method.equals(METHOD_PUT)) {  
  252.         doPut(req, resp);     
  253.           
  254.     } else if (method.equals(METHOD_DELETE)) {  
  255.         doDelete(req, resp);  
  256.           
  257.     } else if (method.equals(METHOD_OPTIONS)) {  
  258.         doOptions(req,resp);  
  259.           
  260.     } else if (method.equals(METHOD_TRACE)) {  
  261.         doTrace(req,resp);  
  262.           
  263.     } else {  
  264.         //  
  265.         // Note that this means NO servlet supports whatever  
  266.         // method was requested, anywhere on this server.  
  267.         //  
  268.   
  269.         String errMsg = lStrings.getString("http.method_not_implemented");  
  270.         Object[] errArgs = new Object[1];  
  271.         errArgs[0] = method;  
  272.         errMsg = MessageFormat.format(errMsg, errArgs);  
  273.           
  274.         resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);  
  275.     }  
  276.     }  
  277.   
  278.     private void maybeSetLastModified(HttpServletResponse resp,  
  279.                       long lastModified) {  
  280.     if (resp.containsHeader(HEADER_LASTMOD))  
  281.         return;  
  282.     if (lastModified >= 0)  
  283.         resp.setDateHeader(HEADER_LASTMOD, lastModified);  
  284.     }  
  285.      
  286.     public void service(ServletRequest req, ServletResponse res)  
  287.     throws ServletException, IOException  
  288.     {  
  289.     HttpServletRequest  request;  
  290.     HttpServletResponse response;  
  291.       
  292.     try {  
  293.         request = (HttpServletRequest) req;  
  294.         response = (HttpServletResponse) res;  
  295.     } catch (ClassCastException e) {  
  296.         throw new ServletException("non-HTTP request or response");  
  297.     }  
  298.     service(request, response);  
  299.     }  
  300. }  

HttpServlet最上层是继承Servlet这个接口类。Servlet这个接口类非常简单,只定义了5个方法。

可以看下下面的Servlet接口:

[java] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. package javax.servlet;  
  2.   
  3. import java.io.IOException;  
  4.   
  5.   
  6.   
  7.   
  8. public interface Servlet {  
  9.   
  10.     //容器初始化  
  11.     public void init(ServletConfig config) throws ServletException;  
  12.       
  13.       
  14.     //获取配置信息  
  15.     public ServletConfig getServletConfig();  
  16.       
  17.     //具体的service 请求分发  
  18.     public void service(ServletRequest req, ServletResponse res)  
  19.     throws ServletException, IOException;  
  20.       
  21.       
  22.    //获取servlet信息  
  23.     public String getServletInfo();  
  24.       
  25.     //容器销毁的时候  
  26.     public void destroy();  
  27. }  


Spring的DispatcherServlet

Spring主要通过DispatcherServlet实现了Servlet。DispatcherServlet最上层也是继承的是HttpServlet这个类。

我们主要看下DispatcherServlet两个比较重要的方法:

[java] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.     protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  3.         if (logger.isDebugEnabled()) {  
  4.             String requestUri = urlPathHelper.getRequestUri(request);  
  5.             logger.debug("DispatcherServlet with name '" + getServletName() + "' processing " + request.getMethod() +  
  6.                     " request for [" + requestUri + "]");  
  7.         }  
  8.   
  9.         // Keep a snapshot of the request attributes in case of an include,  
  10.         // to be able to restore the original attributes after the include.  
  11.         Map<String, Object> attributesSnapshot = null;  
  12.         if (WebUtils.isIncludeRequest(request)) {  
  13.             logger.debug("Taking snapshot of request attributes before include");  
  14.             attributesSnapshot = new HashMap<String, Object>();  
  15.             Enumeration<?> attrNames = request.getAttributeNames();  
  16.             while (attrNames.hasMoreElements()) {  
  17.                 String attrName = (String) attrNames.nextElement();  
  18.                 if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {  
  19.                     attributesSnapshot.put(attrName, request.getAttribute(attrName));  
  20.                 }  
  21.             }  
  22.         }  
  23.   
  24.         // Make framework objects available to handlers and view objects.  
  25.         request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());  
  26.         request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);  
  27.         request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);  
  28.         request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());  
  29.   
  30.         FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);  
  31.         if (inputFlashMap != null) {  
  32.             request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));  
  33.         }  
  34.         request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());  
  35.         request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);  
  36.   
  37.         try {  
  38.             doDispatch(request, response); //这边最终也是调用了doDispatch方法,该方法主要用来处理SPring框架的具体业务分发逻辑。  
  39.         }  
  40.         finally {  
  41.             // Restore the original attribute snapshot, in case of an include.  
  42.             if (attributesSnapshot != null) {  
  43.                 restoreAttributesAfterInclude(request, attributesSnapshot);  
  44.             }  
  45.         }  
  46.     }  
  47.           
  48.         //Spring框架最终的分发都是通过该方法的  
  49.     protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  50.         HttpServletRequest processedRequest = request;  
  51.         HandlerExecutionChain mappedHandler = null;  
  52.         int interceptorIndex = -1;  
  53.   
  54.         try {  
  55.             ModelAndView mv;  
  56.             boolean errorView = false;  
  57.   
  58.             try {  
  59.                 processedRequest = checkMultipart(request);  
  60.   
  61.                 // Determine handler for the current request.  
  62.                 mappedHandler = getHandler(processedRequest, false);  
  63.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  64.                     noHandlerFound(processedRequest, response);  
  65.                     return;  
  66.                 }  
  67.   
  68.                 // Determine handler adapter for the current request.  
  69.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  70.   
  71.                 // Process last-modified header, if supported by the handler.  
  72.                 String method = request.getMethod();  
  73.                 boolean isGet = "GET".equals(method);  
  74.                 if (isGet || "HEAD".equals(method)) {  
  75.                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
  76.                     if (logger.isDebugEnabled()) {  
  77.                         String requestUri = urlPathHelper.getRequestUri(request);  
  78.                         logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);  
  79.                     }  
  80.                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
  81.                         return;  
  82.                     }  
  83.                 }  
  84.   
  85.                 // 这里是处理前置拦截器  
  86.                 HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
  87.                 if (interceptors != null) {  
  88.                     for (int i = 0; i < interceptors.length; i++) {  
  89.                         HandlerInterceptor interceptor = interceptors[i];  
  90.                         if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {  
  91.                             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
  92.                             return;  
  93.                         }  
  94.                         interceptorIndex = i;  
  95.                     }  
  96.                 }  
  97.   
  98.                 //处理最终的Action逻辑  
  99.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  100.   
  101.                 // Do we need view name translation?  
  102.                 if (mv != null && !mv.hasView()) {  
  103.                     mv.setViewName(getDefaultViewName(request));  
  104.                 }  
  105.   
  106.                                 //处理后置拦截器  
  107.                 if (interceptors != null) {  
  108.                     for (int i = interceptors.length - 1; i >= 0; i--) {  
  109.                         HandlerInterceptor interceptor = interceptors[i];  
  110.                         interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);  
  111.                     }  
  112.                 }  
  113.             }  
  114.             catch (ModelAndViewDefiningException ex) {  
  115.                 logger.debug("ModelAndViewDefiningException encountered", ex);  
  116.                 mv = ex.getModelAndView();  
  117.             }  
  118.             catch (Exception ex) {  
  119.                 Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
  120.                 mv = processHandlerException(processedRequest, response, handler, ex);  
  121.                 errorView = (mv != null);  
  122.             }  
  123.   
  124.             // Did the handler return a view to render?  
  125.             if (mv != null && !mv.wasCleared()) {  
  126.                 render(mv, processedRequest, response);  
  127.                 if (errorView) {  
  128.                     WebUtils.clearErrorRequestAttributes(request);  
  129.                 }  
  130.             }  
  131.             else {  
  132.                 if (logger.isDebugEnabled()) {  
  133.                     logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +  
  134.                             "': assuming HandlerAdapter completed request handling");  
  135.                 }  
  136.             }  
  137.   
  138.             // Trigger after-completion for successful outcome.  
  139.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
  140.         }  
  141.   
  142.         catch (Exception ex) {  
  143.             // Trigger after-completion for thrown exception.  
  144.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
  145.             throw ex;  
  146.         }  
  147.         catch (Error err) {  
  148.             ServletException ex = new NestedServletException("Handler processing failed", err);  
  149.             // Trigger after-completion for thrown exception.  
  150.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
  151.             throw ex;  
  152.         }  
  153.   
  154.         finally {  
  155.             // Clean up any resources used by a multipart request.  
  156.             if (processedRequest != request) {  
  157.                 cleanupMultipart(processedRequest);  
  158.             }  
  159.         }  
  160.     } 



原文章地址:http://blog.csdn.net/initphp/article/details/38171219

原创粉丝点击