httpServlet源码:

 

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements.  See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License.  You may obtain a copy of the License at
  8. *
  9. *     http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package javax.servlet.http;
  18. import java.io.IOException;
  19. import java.io.OutputStreamWriter;
  20. import java.io.PrintWriter;
  21. import java.io.UnsupportedEncodingException;
  22. import java.lang.reflect.Method;
  23. import java.text.MessageFormat;
  24. import java.util.Enumeration;
  25. import java.util.ResourceBundle;
  26. import javax.servlet.DispatcherType;
  27. import javax.servlet.GenericServlet;
  28. import javax.servlet.ServletException;
  29. import javax.servlet.ServletOutputStream;
  30. import javax.servlet.ServletRequest;
  31. import javax.servlet.ServletResponse;
  32. /**
  33. * Provides an abstract class to be subclassed to create
  34. * an HTTP servlet suitable for a Web site. A subclass of
  35. * <code>HttpServlet</code> must override at least
  36. * one method, usually one of these:
  37. *
  38. * <ul>
  39. * <li> <code>doGet</code>, if the servlet supports HTTP GET requests
  40. * <li> <code>doPost</code>, for HTTP POST requests
  41. * <li> <code>doPut</code>, for HTTP PUT requests
  42. * <li> <code>doDelete</code>, for HTTP DELETE requests
  43. * <li> <code>init</code> and <code>destroy</code>,
  44. * to manage resources that are held for the life of the servlet
  45. * <li> <code>getServletInfo</code>, which the servlet uses to
  46. * provide information about itself
  47. * </ul>
  48. *
  49. * <p>There's almost no reason to override the <code>service</code>
  50. * method. <code>service</code> handles standard HTTP
  51. * requests by dispatching them to the handler methods
  52. * for each HTTP request type (the <code>do</code><i>Method</i>
  53. * methods listed above).
  54. *
  55. * <p>Likewise, there's almost no reason to override the
  56. * <code>doOptions</code> and <code>doTrace</code> methods.
  57. *
  58. * <p>Servlets typically run on multithreaded servers,
  59. * so be aware that a servlet must handle concurrent
  60. * requests and be careful to synchronize access to shared resources.
  61. * Shared resources include in-memory data such as
  62. * instance or class variables and external objects
  63. * such as files, database connections, and network
  64. * connections.
  65. * See the
  66. * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
  67. * Java Tutorial on Multithreaded Programming</a> for more
  68. * information on handling multiple threads in a Java program.
  69. */
  70. public abstract class HttpServlet extends GenericServlet {
  71. private static final long serialVersionUID = 1L;
  72. private static final String METHOD_DELETE = "DELETE";
  73. private static final String METHOD_HEAD = "HEAD";
  74. private static final String METHOD_GET = "GET";
  75. private static final String METHOD_OPTIONS = "OPTIONS";
  76. private static final String METHOD_POST = "POST";
  77. private static final String METHOD_PUT = "PUT";
  78. private static final String METHOD_TRACE = "TRACE";
  79. private static final String HEADER_IFMODSINCE = "If-Modified-Since";
  80. private static final String HEADER_LASTMOD = "Last-Modified";
  81. private static final String LSTRING_FILE =
  82. "javax.servlet.http.LocalStrings";
  83. private static final ResourceBundle lStrings =
  84. ResourceBundle.getBundle(LSTRING_FILE);
  85. /**
  86. * Does nothing, because this is an abstract class.
  87. */
  88. public HttpServlet() {
  89. // NOOP
  90. }
  91. /**
  92. * Called by the server (via the <code>service</code> method) to
  93. * allow a servlet to handle a GET request.
  94. *
  95. * <p>Overriding this method to support a GET request also
  96. * automatically supports an HTTP HEAD request. A HEAD
  97. * request is a GET request that returns no body in the
  98. * response, only the request header fields.
  99. *
  100. * <p>When overriding this method, read the request data,
  101. * write the response headers, get the response's writer or
  102. * output stream object, and finally, write the response data.
  103. * It's best to include content type and encoding. When using
  104. * a <code>PrintWriter</code> object to return the response,
  105. * set the content type before accessing the
  106. * <code>PrintWriter</code> object.
  107. *
  108. * <p>The servlet container must write the headers before
  109. * committing the response, because in HTTP the headers must be sent
  110. * before the response body.
  111. *
  112. * <p>Where possible, set the Content-Length header (with the
  113. * {@link javax.servlet.ServletResponse#setContentLength} method),
  114. * to allow the servlet container to use a persistent connection
  115. * to return its response to the client, improving performance.
  116. * The content length is automatically set if the entire response fits
  117. * inside the response buffer.
  118. *
  119. * <p>When using HTTP 1.1 chunked encoding (which means that the response
  120. * has a Transfer-Encoding header), do not set the Content-Length header.
  121. *
  122. * <p>The GET method should be safe, that is, without
  123. * any side effects for which users are held responsible.
  124. * For example, most form queries have no side effects.
  125. * If a client request is intended to change stored data,
  126. * the request should use some other HTTP method.
  127. *
  128. * <p>The GET method should also be idempotent, meaning
  129. * that it can be safely repeated. Sometimes making a
  130. * method safe also makes it idempotent. For example,
  131. * repeating queries is both safe and idempotent, but
  132. * buying a product online or modifying data is neither
  133. * safe nor idempotent.
  134. *
  135. * <p>If the request is incorrectly formatted, <code>doGet</code>
  136. * returns an HTTP "Bad Request" message.
  137. *
  138. * @param req   an {@link HttpServletRequest} object that
  139. *                  contains the request the client has made
  140. *                  of the servlet
  141. *
  142. * @param resp  an {@link HttpServletResponse} object that
  143. *                  contains the response the servlet sends
  144. *                  to the client
  145. *
  146. * @exception IOException   if an input or output error is
  147. *                              detected when the servlet handles
  148. *                              the GET request
  149. *
  150. * @exception ServletException  if the request for the GET
  151. *                                  could not be handled
  152. *
  153. * @see javax.servlet.ServletResponse#setContentType
  154. */
  155. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  156. throws ServletException, IOException
  157. {
  158. String protocol = req.getProtocol();
  159. String msg = lStrings.getString("http.method_get_not_supported");
  160. if (protocol.endsWith("1.1")) {
  161. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  162. } else {
  163. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  164. }
  165. }
  166. /**
  167. * Returns the time the <code>HttpServletRequest</code>
  168. * object was last modified,
  169. * in milliseconds since midnight January 1, 1970 GMT.
  170. * If the time is unknown, this method returns a negative
  171. * number (the default).
  172. *
  173. * <p>Servlets that support HTTP GET requests and can quickly determine
  174. * their last modification time should override this method.
  175. * This makes browser and proxy caches work more effectively,
  176. * reducing the load on server and network resources.
  177. *
  178. * @param req   the <code>HttpServletRequest</code>
  179. *                  object that is sent to the servlet
  180. *
  181. * @return  a <code>long</code> integer specifying
  182. *              the time the <code>HttpServletRequest</code>
  183. *              object was last modified, in milliseconds
  184. *              since midnight, January 1, 1970 GMT, or
  185. *              -1 if the time is not known
  186. */
  187. protected long getLastModified(HttpServletRequest req) {
  188. return -1;
  189. }
  190. /**
  191. * <p>Receives an HTTP HEAD request from the protected
  192. * <code>service</code> method and handles the
  193. * request.
  194. * The client sends a HEAD request when it wants
  195. * to see only the headers of a response, such as
  196. * Content-Type or Content-Length. The HTTP HEAD
  197. * method counts the output bytes in the response
  198. * to set the Content-Length header accurately.
  199. *
  200. * <p>If you override this method, you can avoid computing
  201. * the response body and just set the response headers
  202. * directly to improve performance. Make sure that the
  203. * <code>doHead</code> method you write is both safe
  204. * and idempotent (that is, protects itself from being
  205. * called multiple times for one HTTP HEAD request).
  206. *
  207. * <p>If the HTTP HEAD request is incorrectly formatted,
  208. * <code>doHead</code> returns an HTTP "Bad Request"
  209. * message.
  210. *
  211. * @param req   the request object that is passed to the servlet
  212. *
  213. * @param resp  the response object that the servlet
  214. *                  uses to return the headers to the client
  215. *
  216. * @exception IOException   if an input or output error occurs
  217. *
  218. * @exception ServletException  if the request for the HEAD
  219. *                                  could not be handled
  220. */
  221. protected void doHead(HttpServletRequest req, HttpServletResponse resp)
  222. throws ServletException, IOException {
  223. if (DispatcherType.INCLUDE.equals(req.getDispatcherType())) {
  224. doGet(req, resp);
  225. } else {
  226. NoBodyResponse response = new NoBodyResponse(resp);
  227. doGet(req, response);
  228. response.setContentLength();
  229. }
  230. }
  231. /**
  232. * Called by the server (via the <code>service</code> method)
  233. * to allow a servlet to handle a POST request.
  234. *
  235. * The HTTP POST method allows the client to send
  236. * data of unlimited length to the Web server a single time
  237. * and is useful when posting information such as
  238. * credit card numbers.
  239. *
  240. * <p>When overriding this method, read the request data,
  241. * write the response headers, get the response's writer or output
  242. * stream object, and finally, write the response data. It's best
  243. * to include content type and encoding. When using a
  244. * <code>PrintWriter</code> object to return the response, set the
  245. * content type before accessing the <code>PrintWriter</code> object.
  246. *
  247. * <p>The servlet container must write the headers before committing the
  248. * response, because in HTTP the headers must be sent before the
  249. * response body.
  250. *
  251. * <p>Where possible, set the Content-Length header (with the
  252. * {@link javax.servlet.ServletResponse#setContentLength} method),
  253. * to allow the servlet container to use a persistent connection
  254. * to return its response to the client, improving performance.
  255. * The content length is automatically set if the entire response fits
  256. * inside the response buffer.
  257. *
  258. * <p>When using HTTP 1.1 chunked encoding (which means that the response
  259. * has a Transfer-Encoding header), do not set the Content-Length header.
  260. *
  261. * <p>This method does not need to be either safe or idempotent.
  262. * Operations requested through POST can have side effects for
  263. * which the user can be held accountable, for example,
  264. * updating stored data or buying items online.
  265. *
  266. * <p>If the HTTP POST request is incorrectly formatted,
  267. * <code>doPost</code> returns an HTTP "Bad Request" message.
  268. *
  269. *
  270. * @param req   an {@link HttpServletRequest} object that
  271. *                  contains the request the client has made
  272. *                  of the servlet
  273. *
  274. * @param resp  an {@link HttpServletResponse} object that
  275. *                  contains the response the servlet sends
  276. *                  to the client
  277. *
  278. * @exception IOException   if an input or output error is
  279. *                              detected when the servlet handles
  280. *                              the request
  281. *
  282. * @exception ServletException  if the request for the POST
  283. *                                  could not be handled
  284. *
  285. * @see javax.servlet.ServletOutputStream
  286. * @see javax.servlet.ServletResponse#setContentType
  287. */
  288. protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  289. throws ServletException, IOException {
  290. String protocol = req.getProtocol();
  291. String msg = lStrings.getString("http.method_post_not_supported");
  292. if (protocol.endsWith("1.1")) {
  293. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  294. } else {
  295. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  296. }
  297. }
  298. /**
  299. * Called by the server (via the <code>service</code> method)
  300. * to allow a servlet to handle a PUT request.
  301. *
  302. * The PUT operation allows a client to
  303. * place a file on the server and is similar to
  304. * sending a file by FTP.
  305. *
  306. * <p>When overriding this method, leave intact
  307. * any content headers sent with the request (including
  308. * Content-Length, Content-Type, Content-Transfer-Encoding,
  309. * Content-Encoding, Content-Base, Content-Language, Content-Location,
  310. * Content-MD5, and Content-Range). If your method cannot
  311. * handle a content header, it must issue an error message
  312. * (HTTP 501 - Not Implemented) and discard the request.
  313. * For more information on HTTP 1.1, see RFC 2616
  314. * <a href="http://www.ietf.org/rfc/rfc2616.txt"></a>.
  315. *
  316. * <p>This method does not need to be either safe or idempotent.
  317. * Operations that <code>doPut</code> performs can have side
  318. * effects for which the user can be held accountable. When using
  319. * this method, it may be useful to save a copy of the
  320. * affected URL in temporary storage.
  321. *
  322. * <p>If the HTTP PUT request is incorrectly formatted,
  323. * <code>doPut</code> returns an HTTP "Bad Request" message.
  324. *
  325. * @param req   the {@link HttpServletRequest} object that
  326. *                  contains the request the client made of
  327. *                  the servlet
  328. *
  329. * @param resp  the {@link HttpServletResponse} object that
  330. *                  contains the response the servlet returns
  331. *                  to the client
  332. *
  333. * @exception IOException   if an input or output error occurs
  334. *                              while the servlet is handling the
  335. *                              PUT request
  336. *
  337. * @exception ServletException  if the request for the PUT
  338. *                                  cannot be handled
  339. */
  340. protected void doPut(HttpServletRequest req, HttpServletResponse resp)
  341. throws ServletException, IOException {
  342. String protocol = req.getProtocol();
  343. String msg = lStrings.getString("http.method_put_not_supported");
  344. if (protocol.endsWith("1.1")) {
  345. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  346. } else {
  347. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  348. }
  349. }
  350. /**
  351. * Called by the server (via the <code>service</code> method)
  352. * to allow a servlet to handle a DELETE request.
  353. *
  354. * The DELETE operation allows a client to remove a document
  355. * or Web page from the server.
  356. *
  357. * <p>This method does not need to be either safe
  358. * or idempotent. Operations requested through
  359. * DELETE can have side effects for which users
  360. * can be held accountable. When using
  361. * this method, it may be useful to save a copy of the
  362. * affected URL in temporary storage.
  363. *
  364. * <p>If the HTTP DELETE request is incorrectly formatted,
  365. * <code>doDelete</code> returns an HTTP "Bad Request"
  366. * message.
  367. *
  368. * @param req   the {@link HttpServletRequest} object that
  369. *                  contains the request the client made of
  370. *                  the servlet
  371. *
  372. *
  373. * @param resp  the {@link HttpServletResponse} object that
  374. *                  contains the response the servlet returns
  375. *                  to the client
  376. *
  377. * @exception IOException   if an input or output error occurs
  378. *                              while the servlet is handling the
  379. *                              DELETE request
  380. *
  381. * @exception ServletException  if the request for the
  382. *                                  DELETE cannot be handled
  383. */
  384. protected void doDelete(HttpServletRequest req,
  385. HttpServletResponse resp)
  386. throws ServletException, IOException {
  387. String protocol = req.getProtocol();
  388. String msg = lStrings.getString("http.method_delete_not_supported");
  389. if (protocol.endsWith("1.1")) {
  390. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  391. } else {
  392. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  393. }
  394. }
  395. private static Method[] getAllDeclaredMethods(Class<?> c) {
  396. if (c.equals(javax.servlet.http.HttpServlet.class)) {
  397. return null;
  398. }
  399. Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
  400. Method[] thisMethods = c.getDeclaredMethods();
  401. if ((parentMethods != null) && (parentMethods.length > 0)) {
  402. Method[] allMethods =
  403. new Method[parentMethods.length + thisMethods.length];
  404. System.arraycopy(parentMethods, 0, allMethods, 0,
  405. parentMethods.length);
  406. System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
  407. thisMethods.length);
  408. thisMethods = allMethods;
  409. }
  410. return thisMethods;
  411. }
  412. /**
  413. * Called by the server (via the <code>service</code> method)
  414. * to allow a servlet to handle a OPTIONS request.
  415. *
  416. * The OPTIONS request determines which HTTP methods
  417. * the server supports and
  418. * returns an appropriate header. For example, if a servlet
  419. * overrides <code>doGet</code>, this method returns the
  420. * following header:
  421. *
  422. * <p><code>Allow: GET, HEAD, TRACE, OPTIONS</code>
  423. *
  424. * <p>There's no need to override this method unless the
  425. * servlet implements new HTTP methods, beyond those
  426. * implemented by HTTP 1.1.
  427. *
  428. * @param req   the {@link HttpServletRequest} object that
  429. *                  contains the request the client made of
  430. *                  the servlet
  431. *
  432. * @param resp  the {@link HttpServletResponse} object that
  433. *                  contains the response the servlet returns
  434. *                  to the client
  435. *
  436. * @exception IOException   if an input or output error occurs
  437. *                              while the servlet is handling the
  438. *                              OPTIONS request
  439. *
  440. * @exception ServletException  if the request for the
  441. *                                  OPTIONS cannot be handled
  442. */
  443. protected void doOptions(HttpServletRequest req,
  444. HttpServletResponse resp)
  445. throws ServletException, IOException {
  446. Method[] methods = getAllDeclaredMethods(this.getClass());
  447. boolean ALLOW_GET = false;
  448. boolean ALLOW_HEAD = false;
  449. boolean ALLOW_POST = false;
  450. boolean ALLOW_PUT = false;
  451. boolean ALLOW_DELETE = false;
  452. boolean ALLOW_TRACE = true;
  453. boolean ALLOW_OPTIONS = true;
  454. for (int i=0; i<methods.length; i++) {
  455. Method m = methods[i];
  456. if (m.getName().equals("doGet")) {
  457. ALLOW_GET = true;
  458. ALLOW_HEAD = true;
  459. }
  460. if (m.getName().equals("doPost"))
  461. ALLOW_POST = true;
  462. if (m.getName().equals("doPut"))
  463. ALLOW_PUT = true;
  464. if (m.getName().equals("doDelete"))
  465. ALLOW_DELETE = true;
  466. }
  467. String allow = null;
  468. if (ALLOW_GET)
  469. allow=METHOD_GET;
  470. if (ALLOW_HEAD)
  471. if (allow==null) allow=METHOD_HEAD;
  472. else allow += ", " + METHOD_HEAD;
  473. if (ALLOW_POST)
  474. if (allow==null) allow=METHOD_POST;
  475. else allow += ", " + METHOD_POST;
  476. if (ALLOW_PUT)
  477. if (allow==null) allow=METHOD_PUT;
  478. else allow += ", " + METHOD_PUT;
  479. if (ALLOW_DELETE)
  480. if (allow==null) allow=METHOD_DELETE;
  481. else allow += ", " + METHOD_DELETE;
  482. if (ALLOW_TRACE)
  483. if (allow==null) allow=METHOD_TRACE;
  484. else allow += ", " + METHOD_TRACE;
  485. if (ALLOW_OPTIONS)
  486. if (allow==null) allow=METHOD_OPTIONS;
  487. else allow += ", " + METHOD_OPTIONS;
  488. resp.setHeader("Allow", allow);
  489. }
  490. /**
  491. * Called by the server (via the <code>service</code> method)
  492. * to allow a servlet to handle a TRACE request.
  493. *
  494. * A TRACE returns the headers sent with the TRACE
  495. * request to the client, so that they can be used in
  496. * debugging. There's no need to override this method.
  497. *
  498. * @param req   the {@link HttpServletRequest} object that
  499. *                  contains the request the client made of
  500. *                  the servlet
  501. *
  502. * @param resp  the {@link HttpServletResponse} object that
  503. *                  contains the response the servlet returns
  504. *                  to the client
  505. *
  506. * @exception IOException   if an input or output error occurs
  507. *                              while the servlet is handling the
  508. *                              TRACE request
  509. *
  510. * @exception ServletException  if the request for the
  511. *                                  TRACE cannot be handled
  512. */
  513. protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
  514. throws ServletException, IOException
  515. {
  516. int responseLength;
  517. String CRLF = "\r\n";
  518. StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI())
  519. .append(" ").append(req.getProtocol());
  520. Enumeration<String> reqHeaderEnum = req.getHeaderNames();
  521. while( reqHeaderEnum.hasMoreElements() ) {
  522. String headerName = reqHeaderEnum.nextElement();
  523. buffer.append(CRLF).append(headerName).append(": ")
  524. .append(req.getHeader(headerName));
  525. }
  526. buffer.append(CRLF);
  527. responseLength = buffer.length();
  528. resp.setContentType("message/http");
  529. resp.setContentLength(responseLength);
  530. ServletOutputStream out = resp.getOutputStream();
  531. out.print(buffer.toString());
  532. out.close();
  533. return;
  534. }
  535. /**
  536. * Receives standard HTTP requests from the public
  537. * <code>service</code> method and dispatches
  538. * them to the <code>do</code><i>Method</i> methods defined in
  539. * this class. This method is an HTTP-specific version of the
  540. * {@link javax.servlet.Servlet#service} method. There's no
  541. * need to override this method.
  542. *
  543. * @param req   the {@link HttpServletRequest} object that
  544. *                  contains the request the client made of
  545. *                  the servlet
  546. *
  547. * @param resp  the {@link HttpServletResponse} object that
  548. *                  contains the response the servlet returns
  549. *                  to the client
  550. *
  551. * @exception IOException   if an input or output error occurs
  552. *                              while the servlet is handling the
  553. *                              HTTP request
  554. *
  555. * @exception ServletException  if the HTTP request
  556. *                                  cannot be handled
  557. *
  558. * @see javax.servlet.Servlet#service
  559. */
  560. protected void service(HttpServletRequest req, HttpServletResponse resp)
  561. throws ServletException, IOException {
  562. String method = req.getMethod();
  563. if (method.equals(METHOD_GET)) {
  564. long lastModified = getLastModified(req);
  565. if (lastModified == -1) {
  566. // servlet doesn't support if-modified-since, no reason
  567. // to go through further expensive logic
  568. doGet(req, resp);
  569. } else {
  570. long ifModifiedSince;
  571. try {
  572. ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
  573. } catch (IllegalArgumentException iae) {
  574. // Invalid date header - proceed as if none was set
  575. ifModifiedSince = -1;
  576. }
  577. if (ifModifiedSince < (lastModified / 1000 * 1000)) {
  578. // If the servlet mod time is later, call doGet()
  579. // Round down to the nearest second for a proper compare
  580. // A ifModifiedSince of -1 will always be less
  581. maybeSetLastModified(resp, lastModified);
  582. doGet(req, resp);
  583. } else {
  584. resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
  585. }
  586. }
  587. } else if (method.equals(METHOD_HEAD)) {
  588. long lastModified = getLastModified(req);
  589. maybeSetLastModified(resp, lastModified);
  590. doHead(req, resp);
  591. } else if (method.equals(METHOD_POST)) {
  592. doPost(req, resp);
  593. } else if (method.equals(METHOD_PUT)) {
  594. doPut(req, resp);
  595. } else if (method.equals(METHOD_DELETE)) {
  596. doDelete(req, resp);
  597. } else if (method.equals(METHOD_OPTIONS)) {
  598. doOptions(req,resp);
  599. } else if (method.equals(METHOD_TRACE)) {
  600. doTrace(req,resp);
  601. } else {
  602. //
  603. // Note that this means NO servlet supports whatever
  604. // method was requested, anywhere on this server.
  605. //
  606. String errMsg = lStrings.getString("http.method_not_implemented");
  607. Object[] errArgs = new Object[1];
  608. errArgs[0] = method;
  609. errMsg = MessageFormat.format(errMsg, errArgs);
  610. resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
  611. }
  612. }
  613. /*
  614. * Sets the Last-Modified entity header field, if it has not
  615. * already been set and if the value is meaningful.  Called before
  616. * doGet, to ensure that headers are set before response data is
  617. * written.  A subclass might have set this header already, so we
  618. * check.
  619. */
  620. private void maybeSetLastModified(HttpServletResponse resp,
  621. long lastModified) {
  622. if (resp.containsHeader(HEADER_LASTMOD))
  623. return;
  624. if (lastModified >= 0)
  625. resp.setDateHeader(HEADER_LASTMOD, lastModified);
  626. }
  627. /**
  628. * Dispatches client requests to the protected
  629. * <code>service</code> method. There's no need to
  630. * override this method.
  631. *
  632. * @param req   the {@link HttpServletRequest} object that
  633. *                  contains the request the client made of
  634. *                  the servlet
  635. *
  636. * @param res   the {@link HttpServletResponse} object that
  637. *                  contains the response the servlet returns
  638. *                  to the client
  639. *
  640. * @exception IOException   if an input or output error occurs
  641. *                              while the servlet is handling the
  642. *                              HTTP request
  643. *
  644. * @exception ServletException  if the HTTP request cannot
  645. *                                  be handled
  646. *
  647. * @see javax.servlet.Servlet#service
  648. */
  649. @Override
  650. public void service(ServletRequest req, ServletResponse res)
  651. throws ServletException, IOException {
  652. HttpServletRequest  request;
  653. HttpServletResponse response;
  654. try {
  655. request = (HttpServletRequest) req;
  656. response = (HttpServletResponse) res;
  657. } catch (ClassCastException e) {
  658. throw new ServletException("non-HTTP request or response");
  659. }
  660. service(request, response);
  661. }
  662. }
  663. /*
  664. * A response wrapper for use in (dumb) "HEAD" support.
  665. * This just swallows that body, counting the bytes in order to set
  666. * the content length appropriately.  All other methods delegate to the
  667. * wrapped HTTP Servlet Response object.
  668. */
  669. // file private
  670. class NoBodyResponse extends HttpServletResponseWrapper {
  671. private final NoBodyOutputStream noBody;
  672. private PrintWriter writer;
  673. private boolean didSetContentLength;
  674. // file private
  675. NoBodyResponse(HttpServletResponse r) {
  676. super(r);
  677. noBody = new NoBodyOutputStream();
  678. }
  679. // file private
  680. void setContentLength() {
  681. if (!didSetContentLength) {
  682. if (writer != null) {
  683. writer.flush();
  684. }
  685. super.setContentLength(noBody.getContentLength());
  686. }
  687. }
  688. // SERVLET RESPONSE interface methods
  689. @Override
  690. public void setContentLength(int len) {
  691. super.setContentLength(len);
  692. didSetContentLength = true;
  693. }
  694. @Override
  695. public void setContentLengthLong(long len) {
  696. super.setContentLengthLong(len);
  697. didSetContentLength = true;
  698. }
  699. @Override
  700. public void setHeader(String name, String value) {
  701. super.setHeader(name, value);
  702. checkHeader(name);
  703. }
  704. @Override
  705. public void addHeader(String name, String value) {
  706. super.addHeader(name, value);
  707. checkHeader(name);
  708. }
  709. @Override
  710. public void setIntHeader(String name, int value) {
  711. super.setIntHeader(name, value);
  712. checkHeader(name);
  713. }
  714. @Override
  715. public void addIntHeader(String name, int value) {
  716. super.addIntHeader(name, value);
  717. checkHeader(name);
  718. }
  719. private void checkHeader(String name) {
  720. if ("content-length".equalsIgnoreCase(name)) {
  721. didSetContentLength = true;
  722. }
  723. }
  724. @Override
  725. public ServletOutputStream getOutputStream() throws IOException {
  726. return noBody;
  727. }
  728. @Override
  729. public PrintWriter getWriter() throws UnsupportedEncodingException {
  730. if (writer == null) {
  731. OutputStreamWriter w;
  732. w = new OutputStreamWriter(noBody, getCharacterEncoding());
  733. writer = new PrintWriter(w);
  734. }
  735. return writer;
  736. }
  737. }
  738. /*
  739. * Servlet output stream that gobbles up all its data.
  740. */
  741. // file private
  742. class NoBodyOutputStream extends ServletOutputStream {
  743. private static final String LSTRING_FILE =
  744. "javax.servlet.http.LocalStrings";
  745. private static final ResourceBundle lStrings =
  746. ResourceBundle.getBundle(LSTRING_FILE);
  747. private int contentLength = 0;
  748. // file private
  749. NoBodyOutputStream() {
  750. // NOOP
  751. }
  752. // file private
  753. int getContentLength() {
  754. return contentLength;
  755. }
  756. @Override
  757. public void write(int b) {
  758. contentLength++;
  759. }
  760. @Override
  761. public void write(byte buf[], int offset, int len) throws IOException {
  762. if (buf == null) {
  763. throw new NullPointerException(
  764. lStrings.getString("err.io.nullArray"));
  765. }
  766. if (offset < 0 || len < 0 || offset+len > buf.length) {
  767. String msg = lStrings.getString("err.io.indexOutOfBounds");
  768. Object[] msgArgs = new Object[3];
  769. msgArgs[0] = Integer.valueOf(offset);
  770. msgArgs[1] = Integer.valueOf(len);
  771. msgArgs[2] = Integer.valueOf(buf.length);
  772. msg = MessageFormat.format(msg, msgArgs);
  773. throw new IndexOutOfBoundsException(msg);
  774. }
  775. contentLength += len;
  776. }
  777. @Override
  778. public boolean isReady() {
  779. // TODO SERVLET 3.1
  780. return false;
  781. }
  782. @Override
  783. public void setWriteListener(javax.servlet.WriteListener listener) {
  784. // TODO SERVLET 3.1
  785. }
  786. }

 

GenericServlet源码:

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements.  See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License.  You may obtain a copy of the License at
  8. *
  9. *     http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package javax.servlet;
  18. import java.io.IOException;
  19. import java.util.Enumeration;
  20. /**
  21. * Defines a generic, protocol-independent servlet. To write an HTTP servlet for
  22. * use on the Web, extend {@link javax.servlet.http.HttpServlet} instead.
  23. * <p>
  24. * <code>GenericServlet</code> implements the <code>Servlet</code> and
  25. * <code>ServletConfig</code> interfaces. <code>GenericServlet</code> may be
  26. * directly extended by a servlet, although it's more common to extend a
  27. * protocol-specific subclass such as <code>HttpServlet</code>.
  28. * <p>
  29. * <code>GenericServlet</code> makes writing servlets easier. It provides simple
  30. * versions of the lifecycle methods <code>init</code> and <code>destroy</code>
  31. * and of the methods in the <code>ServletConfig</code> interface.
  32. * <code>GenericServlet</code> also implements the <code>log</code> method,
  33. * declared in the <code>ServletContext</code> interface.
  34. * <p>
  35. * To write a generic servlet, you need only override the abstract
  36. * <code>service</code> method.
  37. */
  38. public abstract class GenericServlet implements Servlet, ServletConfig,
  39. java.io.Serializable {
  40. private static final long serialVersionUID = 1L;
  41. private transient ServletConfig config;
  42. /**
  43. * Does nothing. All of the servlet initialization is done by one of the
  44. * <code>init</code> methods.
  45. */
  46. public GenericServlet() {
  47. // NOOP
  48. }
  49. /**
  50. * Called by the servlet container to indicate to a servlet that the servlet
  51. * is being taken out of service. See {@link Servlet#destroy}.
  52. */
  53. @Override
  54. public void destroy() {
  55. // NOOP by default
  56. }
  57. /**
  58. * Returns a <code>String</code> containing the value of the named
  59. * initialization parameter, or <code>null</code> if the parameter does not
  60. * exist. See {@link ServletConfig#getInitParameter}.
  61. * <p>
  62. * This method is supplied for convenience. It gets the value of the named
  63. * parameter from the servlet's <code>ServletConfig</code> object.
  64. *
  65. * @param name
  66. *            a <code>String</code> specifying the name of the
  67. *            initialization parameter
  68. * @return String a <code>String</code> containing the value of the
  69. *         initialization parameter
  70. */
  71. @Override
  72. public String getInitParameter(String name) {
  73. return getServletConfig().getInitParameter(name);
  74. }
  75. /**
  76. * Returns the names of the servlet's initialization parameters as an
  77. * <code>Enumeration</code> of <code>String</code> objects, or an empty
  78. * <code>Enumeration</code> if the servlet has no initialization parameters.
  79. * See {@link ServletConfig#getInitParameterNames}.
  80. * <p>
  81. * This method is supplied for convenience. It gets the parameter names from
  82. * the servlet's <code>ServletConfig</code> object.
  83. *
  84. * @return Enumeration an enumeration of <code>String</code> objects
  85. *         containing the names of the servlet's initialization parameters
  86. */
  87. @Override
  88. public Enumeration<String> getInitParameterNames() {
  89. return getServletConfig().getInitParameterNames();
  90. }
  91. /**
  92. * Returns this servlet's {@link ServletConfig} object.
  93. *
  94. * @return ServletConfig the <code>ServletConfig</code> object that
  95. *         initialized this servlet
  96. */
  97. @Override
  98. public ServletConfig getServletConfig() {
  99. return config;
  100. }
  101. /**
  102. * Returns a reference to the {@link ServletContext} in which this servlet
  103. * is running. See {@link ServletConfig#getServletContext}.
  104. * <p>
  105. * This method is supplied for convenience. It gets the context from the
  106. * servlet's <code>ServletConfig</code> object.
  107. *
  108. * @return ServletContext the <code>ServletContext</code> object passed to
  109. *         this servlet by the <code>init</code> method
  110. */
  111. @Override
  112. public ServletContext getServletContext() {
  113. return getServletConfig().getServletContext();
  114. }
  115. /**
  116. * Returns information about the servlet, such as author, version, and
  117. * copyright. By default, this method returns an empty string. Override this
  118. * method to have it return a meaningful value. See
  119. * {@link Servlet#getServletInfo}.
  120. *
  121. * @return String information about this servlet, by default an empty string
  122. */
  123. @Override
  124. public String getServletInfo() {
  125. return "";
  126. }
  127. /**
  128. * Called by the servlet container to indicate to a servlet that the servlet
  129. * is being placed into service. See {@link Servlet#init}.
  130. * <p>
  131. * This implementation stores the {@link ServletConfig} object it receives
  132. * from the servlet container for later use. When overriding this form of
  133. * the method, call <code>super.init(config)</code>.
  134. *
  135. * @param config
  136. *            the <code>ServletConfig</code> object that contains
  137. *            configuration information for this servlet
  138. * @exception ServletException
  139. *                if an exception occurs that interrupts the servlet's
  140. *                normal operation
  141. * @see UnavailableException
  142. */
  143. @Override
  144. public void init(ServletConfig config) throws ServletException {
  145. this.config = config;
  146. this.init();
  147. }
  148. /**
  149. * A convenience method which can be overridden so that there's no need to
  150. * call <code>super.init(config)</code>.
  151. * <p>
  152. * Instead of overriding {@link #init(ServletConfig)}, simply override this
  153. * method and it will be called by
  154. * <code>GenericServlet.init(ServletConfig config)</code>. The
  155. * <code>ServletConfig</code> object can still be retrieved via
  156. * {@link #getServletConfig}.
  157. *
  158. * @exception ServletException
  159. *                if an exception occurs that interrupts the servlet's
  160. *                normal operation
  161. */
  162. public void init() throws ServletException {
  163. // NOOP by default
  164. }
  165. /**
  166. * Writes the specified message to a servlet log file, prepended by the
  167. * servlet's name. See {@link ServletContext#log(String)}.
  168. *
  169. * @param msg
  170. *            a <code>String</code> specifying the message to be written to
  171. *            the log file
  172. */
  173. public void log(String msg) {
  174. getServletContext().log(getServletName() + ": " + msg);
  175. }
  176. /**
  177. * Writes an explanatory message and a stack trace for a given
  178. * <code>Throwable</code> exception to the servlet log file, prepended by
  179. * the servlet's name. See {@link ServletContext#log(String, Throwable)}.
  180. *
  181. * @param message
  182. *            a <code>String</code> that describes the error or exception
  183. * @param t
  184. *            the <code>java.lang.Throwable</code> error or exception
  185. */
  186. public void log(String message, Throwable t) {
  187. getServletContext().log(getServletName() + ": " + message, t);
  188. }
  189. /**
  190. * Called by the servlet container to allow the servlet to respond to a
  191. * request. See {@link Servlet#service}.
  192. * <p>
  193. * This method is declared abstract so subclasses, such as
  194. * <code>HttpServlet</code>, must override it.
  195. *
  196. * @param req
  197. *            the <code>ServletRequest</code> object that contains the
  198. *            client's request
  199. * @param res
  200. *            the <code>ServletResponse</code> object that will contain the
  201. *            servlet's response
  202. * @exception ServletException
  203. *                if an exception occurs that interferes with the servlet's
  204. *                normal operation occurred
  205. * @exception IOException
  206. *                if an input or output exception occurs
  207. */
  208. @Override
  209. public abstract void service(ServletRequest req, ServletResponse res)
  210. throws ServletException, IOException;
  211. /**
  212. * Returns the name of this servlet instance. See
  213. * {@link ServletConfig#getServletName}.
  214. *
  215. * @return the name of this servlet instance
  216. */
  217. @Override
  218. public String getServletName() {
  219. return config.getServletName();
  220. }
  221. }

 

 

Servlet源码:

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements.  See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License.  You may obtain a copy of the License at
  8. *
  9. *     http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package javax.servlet;
  18. import java.io.IOException;
  19. /**
  20. * Defines methods that all servlets must implement.
  21. *
  22. * <p>
  23. * A servlet is a small Java program that runs within a Web server. Servlets
  24. * receive and respond to requests from Web clients, usually across HTTP, the
  25. * HyperText Transfer Protocol.
  26. *
  27. * <p>
  28. * To implement this interface, you can write a generic servlet that extends
  29. * <code>javax.servlet.GenericServlet</code> or an HTTP servlet that extends
  30. * <code>javax.servlet.http.HttpServlet</code>.
  31. *
  32. * <p>
  33. * This interface defines methods to initialize a servlet, to service requests,
  34. * and to remove a servlet from the server. These are known as life-cycle
  35. * methods and are called in the following sequence:
  36. * <ol>
  37. * <li>The servlet is constructed, then initialized with the <code>init</code>
  38. * method.
  39. * <li>Any calls from clients to the <code>service</code> method are handled.
  40. * <li>The servlet is taken out of service, then destroyed with the
  41. * <code>destroy</code> method, then garbage collected and finalized.
  42. * </ol>
  43. *
  44. * <p>
  45. * In addition to the life-cycle methods, this interface provides the
  46. * <code>getServletConfig</code> method, which the servlet can use to get any
  47. * startup information, and the <code>getServletInfo</code> method, which allows
  48. * the servlet to return basic information about itself, such as author,
  49. * version, and copyright.
  50. *
  51. * @see GenericServlet
  52. * @see javax.servlet.http.HttpServlet
  53. */
  54. public interface Servlet {
  55. /**
  56. * Called by the servlet container to indicate to a servlet that the servlet
  57. * is being placed into service.
  58. *
  59. * <p>
  60. * The servlet container calls the <code>init</code> method exactly once
  61. * after instantiating the servlet. The <code>init</code> method must
  62. * complete successfully before the servlet can receive any requests.
  63. *
  64. * <p>
  65. * The servlet container cannot place the servlet into service if the
  66. * <code>init</code> method
  67. * <ol>
  68. * <li>Throws a <code>ServletException</code>
  69. * <li>Does not return within a time period defined by the Web server
  70. * </ol>
  71. *
  72. *
  73. * @param config
  74. *            a <code>ServletConfig</code> object containing the servlet's
  75. *            configuration and initialization parameters
  76. *
  77. * @exception ServletException
  78. *                if an exception has occurred that interferes with the
  79. *                servlet's normal operation
  80. *
  81. * @see UnavailableException
  82. * @see #getServletConfig
  83. */
  84. public void init(ServletConfig config) throws ServletException;
  85. /**
  86. *
  87. * Returns a {@link ServletConfig} object, which contains initialization and
  88. * startup parameters for this servlet. The <code>ServletConfig</code>
  89. * object returned is the one passed to the <code>init</code> method.
  90. *
  91. * <p>
  92. * Implementations of this interface are responsible for storing the
  93. * <code>ServletConfig</code> object so that this method can return it. The
  94. * {@link GenericServlet} class, which implements this interface, already
  95. * does this.
  96. *
  97. * @return the <code>ServletConfig</code> object that initializes this
  98. *         servlet
  99. *
  100. * @see #init
  101. */
  102. public ServletConfig getServletConfig();
  103. /**
  104. * Called by the servlet container to allow the servlet to respond to a
  105. * request.
  106. *
  107. * <p>
  108. * This method is only called after the servlet's <code>init()</code> method
  109. * has completed successfully.
  110. *
  111. * <p>
  112. * The status code of the response always should be set for a servlet that
  113. * throws or sends an error.
  114. *
  115. *
  116. * <p>
  117. * Servlets typically run inside multithreaded servlet containers that can
  118. * handle multiple requests concurrently. Developers must be aware to
  119. * synchronize access to any shared resources such as files, network
  120. * connections, and as well as the servlet's class and instance variables.
  121. * More information on multithreaded programming in Java is available in <a
  122. * href
  123. * ="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
  124. * the Java tutorial on multi-threaded programming</a>.
  125. *
  126. *
  127. * @param req
  128. *            the <code>ServletRequest</code> object that contains the
  129. *            client's request
  130. *
  131. * @param res
  132. *            the <code>ServletResponse</code> object that contains the
  133. *            servlet's response
  134. *
  135. * @exception ServletException
  136. *                if an exception occurs that interferes with the servlet's
  137. *                normal operation
  138. *
  139. * @exception IOException
  140. *                if an input or output exception occurs
  141. */
  142. public void service(ServletRequest req, ServletResponse res)
  143. throws ServletException, IOException;
  144. /**
  145. * Returns information about the servlet, such as author, version, and
  146. * copyright.
  147. *
  148. * <p>
  149. * The string that this method returns should be plain text and not markup
  150. * of any kind (such as HTML, XML, etc.).
  151. *
  152. * @return a <code>String</code> containing servlet information
  153. */
  154. public String getServletInfo();
  155. /**
  156. * Called by the servlet container to indicate to a servlet that the servlet
  157. * is being taken out of service. This method is only called once all
  158. * threads within the servlet's <code>service</code> method have exited or
  159. * after a timeout period has passed. After the servlet container calls this
  160. * method, it will not call the <code>service</code> method again on this
  161. * servlet.
  162. *
  163. * <p>
  164. * This method gives the servlet an opportunity to clean up any resources
  165. * that are being held (for example, memory, file handles, threads) and make
  166. * sure that any persistent state is synchronized with the servlet's current
  167. * state in memory.
  168. */
  169. public void destroy();
  170. }

httpServlet,GenericServlet,Servlet源码分析的更多相关文章

  1. Servlet源码分析

    Servlet API的核心就是javax.servlet.Servlet接口,所有的Servlet 类(抽象的或者自己写的)都必须实现这个接口.在Servlet接口中定义了5个方法,其中有3个方法是 ...

  2. JavaWeb高级:Servlet源码分析

    很多东西归根结底是对Servlet源代码的了解,通过学习源代码加深了解Java高级特性

  3. Servlet和Tomcat底层源码分析

    Servlet 源码分析   Servlet 结构图 Servlet 和 ServletConfig 都是顶层接口,而 GenericServlet 实现了这两个顶层接口,然后HttpServlet ...

  4. Spring mvc源码分析系列--Servlet的前世今生

    Spring mvc源码分析系列--Servlet的前世今生 概述 上一篇文章Spring mvc源码分析系列--前言挖了坑,但是由于最近需求繁忙,一直没有时间填坑.今天暂且来填一个小坑,这篇文章我们 ...

  5. Servlet容器Tomcat中web.xml中url-pattern的配置详解[附带源码分析]

    目录 前言 现象 源码分析 实战例子 总结 参考资料 前言 今天研究了一下tomcat上web.xml配置文件中url-pattern的问题. 这个问题其实毕业前就困扰着我,当时忙于找工作. 找到工作 ...

  6. springmvc源码分析系列-请求处理流程

    接上一篇-springmvc源码分析开头片 上一节主要说了一下springmvc与struts2的作为MVC中的C(controller)控制层的一些区别及两者在作为控制层方面的一些优缺点.今天就结合 ...

  7. 【原创】005 | 搭上SpringBoot请求处理源码分析专车

    前言 如果这是你第二次看到师长,说明你在觊觎我的美色! 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 专车介绍 该趟专车是开往Spring Boot请求处理源码分析专车,主要用来分析S ...

  8. 深入理解 spring 容器,源码分析加载过程

    Spring框架提供了构建Web应用程序的全功能MVC模块,叫Spring MVC,通过Spring Core+Spring MVC即可搭建一套稳定的Java Web项目.本文通过Spring MVC ...

  9. springmvc源码分析

    Spring MVC源码分析--初始化过程 标签: springmvcconstructioniocclass 2012-09-09 21:32 26578人阅读 评论(3) 收藏 举报 版权声明:本 ...

随机推荐

  1. hdu 2842(矩阵高速幂+递推)

    题意:一个中国环的游戏,规则是一个木棒上有n个环.第一个环是能够任意放上或拆下的,剩下的环x假设想放上或拆下必须前一个环x-1是放上的且前x-2个环所有是拆下的,问n个环最少多少次操作能够所有拆掉. ...

  2. npm 淘宝设置代理

    直接安装cnpm导致无限索引,因此直接使用代理 方法一: 直接在当前用户文件夹下,npmrc 文件上直接设置代理:registry=https://registry.npm.taobao.org 方法 ...

  3. Model Vaildation

    https://docs.asp.net/en/latest/mvc/models/validation.html 许多有用的验证属性都必须引用命名空间: System.ComponentModel. ...

  4. HDU 5384 Danganronpa (2015年多校比赛第8场)

    1.题目描写叙述:点击打开链接 2.解题思路:本题利用字典树解决.本题要求查找全部的B[j]在A[i]中出现的总次数.那么我们能够建立一颗字典树,将全部的B[j]插入字典树,因为一个串的全部字串相当于 ...

  5. POJ 1952 BUY LOW, BUY LOWER 动态规划题解

    Description The advice to "buy low" is half the formula to success in the bovine stock mar ...

  6. Use Apache HBase™ when you need random, realtime read/write access to your Big Data.

    Apache HBase™ is the Hadoop database, a distributed, scalable, big data store. Use Apache HBase™ whe ...

  7. cenos 6.5 安装apache 2.4.28出现种问题

    编译出错 configure: error: APR-util not found. Please read the documentation 解决办法 wget http://apache.fre ...

  8. memset 导致的段错误(segmentation fault)

    在调试Minixml库时,定义了一个结构体: struct ssid_info_s{ std::string wl_ssid_name; std::string wl_ssid_mac; std::s ...

  9. STM32 ~ ili9341 横屏驱动代码

    void ili9341_Initializtion(void) { u16 i; RCC->APB2ENR|=<<; //使能PORTB时钟 GPIOB->CRH&= ...

  10. 使用dbms_stats.gather_table_stats调整表的统计信息

    创建实验表,插入10万行数据 SQL> create table test (id number,name varchar2(10)); Table created. SQL> decla ...