当前位置: 首页 > 编程日记 > 正文

Java中Filter、Servlet、Listener的学习

1、Filter的功能
filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).

一个Filter包括:

1)、在servlet被调用之前截获;

2)、在servlet被调用之前检查servlet request;

3)、根据需要修改request头和request数据;

4)、根据需要修改response头和response数据;

5)、在servlet被调用之后截获.

服务器每次只调用setFilterConfig方法一次准备filter 的处理;调用doFilter方法多次以处理不同的请求.FilterConfig接口有方法可以找到filter名字及初始化参数信息.服务器可以设置 FilterConfig为空来指明filter已经终结。

每一个filter从doFilter()方法中得到当前的request及response.在这个方法里,可以进行任何的针对request及 response的操作.(包括收集数据,包装数据等).filter调用chain.doFilter()方法把控制权交给下一个filter.一个 filter在doFilter()方法中结束.如果一个filter想停止request处理而获得对response的完全的控制,那它可以不调用下 一个filter

例子:

首先新建一个Filter

[java] view plaincopy
  1. /** 
  2.  *  
  3.  */  
  4. package com.ee.filter;  
  5. import java.io.IOException;  
  6. import javax.servlet.Filter;  
  7. import javax.servlet.FilterChain;  
  8. import javax.servlet.FilterConfig;  
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.ServletRequest;  
  11. import javax.servlet.ServletResponse;  
  12. /** 
  13.  * @author Administrator 
  14.  * 
  15.  */  
  16. public class LogFilter implements Filter {  
  17. private FilterConfig filterConfig;  
  18. public FilterConfig getFilterConfig() {  
  19. System.err.println("...getFilterConfig...");  
  20. return filterConfig;  
  21. }
  22. public void setFilterConfig(FilterConfig filterConfig) {  
  23. System.err.println("...setFilterConfig...");  
  24. this.filterConfig = filterConfig;  
  25. }
  26. /* (non-Javadoc) 
  27.      * @see javax.servlet.Filter#destroy() 
  28.      */  
  29. @Override  
  30. public void destroy() {  
  31. System.err.println("...filter destroy...");  
  32. }
  33. /* (non-Javadoc) 
  34.      * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) 
  35.      */  
  36. @Override  
  37. public void doFilter(ServletRequest request, ServletResponse response,  
  38. FilterChain chain) throws IOException, ServletException {  
  39. System.err.println("...doFilter...");  
  40. chain.doFilter(request, response);//看到这没,这只要是传递下一个Filter  
  41. }
  42. /* (non-Javadoc) 
  43.      * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) 
  44.      */  
  45. @Override  
  46. public void init(FilterConfig filterConfig) throws ServletException {  
  47. System.err.println("...init Filter...");  
  48. this.filterConfig = filterConfig;  
  49. }
  50. }


在web.xml里配置

[html] view plaincopy
  1. <filter>  
  2. <filter-name>LogFilter</filter-name>  
  3. <filter-class>com.ee.filter.LogFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6. <filter-name>LogFilter</filter-name>  
  7. <url-pattern>/*</url-pattern>  
  8. </filter-mapping>  


启动运行

可以看到...init Filter...首先在TOMCAT启动时即被打印,然后在运行里面再看到...doFilter...被打印。

2、servlet功能

1.Servlet 是什么?
  Servlet是使用Java Servlet 应用程序设计接口(API)及相关类和方法的 Java 程序。除了 Java Servlet API,Servlet 还可以使用用以扩展和添加到 API 的 Java 类软件包。Servlet 在启用 Java 的 Web 服务器上或应用服务器上运行并扩展了该服务器的能力。Java servlet对于Web服务器就好象Java applet对于Web浏览器。Servlet装入Web服务器并在Web服务器内执行,而applet装入Web浏览器并在Web浏览器内执行。Java Servlet API 定义了一个servlet 和Java使能的服务器之间的一个标准接口,这使得Servlets具有跨服务器平台的特性。
  Servlet 通过创建一个框架来扩展服务器的能力,以提供在 Web 上进行请求和响应服务。当客户机发送请求至服务器时,服务器可以将请求信息发送给 Servlet,并让 Servlet 建立起服务器返回给客户机的响应。 当启动 Web 服务器或客户机第一次请求服务时,可以自动装入 Servlet。装入后, Servlet 继续运行直到其它客户机发出请求。Servlet 的功能涉及范围很广。例如,Servlet 可完成如下功能:
  (1) 创建并返回一个包含基于客户请求性质的动态内容的完整的 HTML页面。
  (2) 创建可嵌入到现有 HTML 页面中的一部分 HTML 页面(HTML 片段)。
  (3) 与其它服务器资源(包括数据库和基于 Java 的应用程序)进行通信。
  (4) 用多个客户机处理连接,接收多个客户机的输入,并将结果广播到多个客户机上。例如,Servlet 可以是多参与者的游戏服务器。
  (5) 当允许在单连接方式下传送数据的情况下,在浏览器上打开服务器至applet的新连接,并将该连
接保持在打开状态。当允许客户机和服务器简单、高效地执行会话的情况下,applet也可以启动客户浏览器和服务器之间的连接。可以通过定制协议或标准(如 IIOP)进行通信。
  (6) 对特殊的处理采用 MIME 类型过滤数据,例如图像转换和服务器端包括(SSI)。
  (7) 将定制的处理提供给所有服务器的标准例行程序。例如,Servlet 可以修改如何认证用户。
  2.Servlet 的生命周期
  Servlet 的生命周期始于将它装入 Web 服务器的内存时,并在终止或重新装入 Servlet 时结束。

(1) 初始化
  在下列时刻装入 Servlet:
 如果已配置自动装入选项,则在启动服务器时自动装入
 在服务器启动后,客户机首次向 Servlet 发出请求时
 重新装入 Servlet 时装入 Servlet 后,服务器创建一个 Servlet 实例并且调用 Servlet 的 init() 方法。在初始化阶段,Servlet 初始化参数被传递给 Servlet 配置对象。
  (2) 请求处理
  对于到达服务器的客户机请求,服务器创建特定于请求的一个“请求”对象和一个“响应”对象。服务器调用 Servlet 的 service() 方法,该方法用于传递“请求”和“响应”对象。service() 方法从“请求”对象获得请求信息、处理该请求并用“响应”对象的方法以将响应传回客户机。service() 方法可以调用其它方法来处理请求,例如 doGet()、doPost() 或其它的方法。
  (3) 终止
  当服务器不再需要 Servlet, 或重新装入 Servlet 的新实例时,服务器会调用 Servlet 的 destroy() 方法。
  3. Java Servlet API
  Java Servlet 开发工具(JSDK)提供了多个软件包,在编写 Servlet 时需要用到这些软件包。其中包括两个用于所有 Servlet 的基本软件包:javax.servlet 和 javax.servlet.http。可从sun公司的Web站点下载 Java Servlet 开发工具。 下面主要介绍javax.servlet.http提供的HTTP Servlet应用编程接口。
  HTTP Servlet 使用一个 HTML 表格来发送和接收数据。要创建一个 HTTP Servlet,请扩展 HttpServlet 类, 该类是用专门的方法来处理 HTML 表格的 GenericServlet 的一个子类。 HTML 表单是由 <FORM> 和 </FORM> 标记定义的。表单中典型地包含输入字段(如文本输入字段、复选框、单选按钮和选择列表)和用于提交数据的按钮。当提交信息时,它们还指定服务器应执行哪一个Servlet(或其它的程序)。 HttpServlet 类包含 init()、destroy()、service() 等方法。其中 init() 和 destroy() 方法是继承的。
  (1) init() 方法
  在 Servlet 的生命期中,仅执行一次 init() 方法。它是在服务器装入 Servlet 时执行的。 可以配置服务器,以在启动服务器或客户机首次访问 Servlet 时装入 Servlet。 无论有多少客户机访问 Servlet,都不会重复执行 init() 。
  缺省的 init() 方法通常是符合要求的,但也可以用定制 init() 方法来覆盖它,典型的是管理服务器端资源。 例如,可能编写一个定制 init() 来只用于一次装入 GIF 图像,改进 Servlet 返回 GIF 图像和含有多个客户机请求的性能。另一个示例是初始化数据库连接。缺省的 init() 方法设置了 Servlet 的初始化参数,并用它的 ServletConfig 对象参数来启动配置, 因此所有覆盖 init() 方法的 Servlet 应调用 super.init() 以确保仍然执行这些任务。在调用 service() 方法之前,应确保已完成了 init() 方法。
  (2) service() 方法
  service() 方法是 Servlet 的核心。每当一个客户请求一个HttpServlet 对象,该对象的service() 方法就要被调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。 在 HttpServlet 中已存在 service() 方法。缺省的服务功能是调用与 HTTP 请求的方法相应的 do 功能。例如, 如果 HTTP 请求方法为 GET,则缺省情况下就调用 doGet() 。Servlet 应该为 Servlet 支持的 HTTP 方法覆盖 do 功能。因为 HttpServlet.service() 方法会检查请求方法是否调用了适当的处理方法,不必要覆盖 service() 方法。只需覆盖相应的 do 方法就可以了。
 当一个客户通过HTML 表单发出一个HTTP POST请求时,doPost()方法被调用。与POST请求相关的参数作为一个单独的HTTP 请求从浏览器发送到服务器。当需要修改服务器端的数据时,应该使用doPost()方法。
 当一个客户通过HTML 表单发出一个HTTP GET请求或直接请求一个URL时,doGet()方法被调用。与GET请求相关的参数添加到URL的后面,并与这个请求一起发送。当不会修改服务器端的数据时,应该使用doGet()方法。
  Servlet的响应可以是下列几种类型:
  一个输出流,浏览器根据它的内容类型(如text/HTML)进行解释。
  一个HTTP错误响应, 重定向到另一个URL、servlet、JSP。
  (3) destroy() 方法
  destroy() 方法仅执行一次,即在服务器停止且卸装Servlet 时执行该方法。典型的,将 Servlet 作为服务器进程的一部分来关闭。缺省的 destroy() 方法通常是符合要求的,但也可以覆盖它,典型的是管理服务器端资源。例如,如果 Servlet 在运行时会累计统计数据,则可以编写一个 destroy() 方法,该方法用于在未装入 Servlet 时将统计数字保存在文件中。另一个示例是关闭数据库连接。
当服务器卸装 Servlet 时,将在所有 service() 方法调用完成后,或在指定的时间间隔过后调用 destroy() 方法。一个Servlet 在运行service() 方法时可能会产生其它的线程,因此请确认在调用 destroy() 方法时,这些线程已终止或完成。
  (4) GetServletConfig()方法
  GetServletConfig()方法返回一个 ServletConfig 对象,该对象用来返回初始化参数和  ServletContext。ServletContext 接口提供有关servlet 的环境信息。
  (5) GetServletInfo()方法
  GetServletInfo()方法是一个可选的方法,它提供有关servlet 的信息,如作者、版本、版权。
  当服务器调用sevlet 的Service()、doGet()和doPost()这三个方法时,均需要 “请求”和“响应”对象作为参数。“请求”对象提供有关请求的信息,而“响应”对象提供了一个将响应信息返回给浏览器的一个通信途径。javax.servlet 软件包中的相关类为ServletResponse和ServletRequest,而javax.servlet.http 软件包中的相关类为HttpServletRequest 和 HttpServletResponse。Servlet 通过这些对象与服务器通信并最终与客户机通信。Servlet 能通过调用“请求”对象的方法获知客户机环境,服务器环境的信息和所有由客户机提供的信息。Servlet 可以调用“响应”对象的方法发送响应,该响应是准备发回客户机的。

例子:

创建一个servlet

[java] view plaincopy
  1. /** 
  2.  *  
  3.  */  
  4. package com.ee.servlet;  
  5. import java.io.IOException;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. /** 
  11.  * @author Administrator 
  12.  * 
  13.  */  
  14. public class LogServlet extends HttpServlet {  
  15. /** 
  16.      *  
  17.      */  
  18. private static final long serialVersionUID = 1L;  
  19. @Override  
  20. protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  21. throws ServletException, IOException {  
  22. doPost(req, resp);
  23. }
  24. @Override  
  25. protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  26. throws ServletException, IOException {  
  27. System.err.println("...doPost(req, resp)...");  
  28. }
  29. }


在web.xml中的配置:

[html] view plaincopy
  1. <servlet>  
  2. <servlet-name>LogServlet</servlet-name>  
  3. <servlet-class>com.ee.servlet.LogServlet</servlet-class>  
  4. </servlet>  
  5. <servlet-mapping>  
  6. <servlet-name>LogServlet</servlet-name>  
  7. <url-pattern>/*</url-pattern><!-- 看到此没有,这个拦截所有路径 -->  
  8. </servlet-mapping>  


它的拦截规则:

当一个请求发送到servlet容器的时候,容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url,比如我访问的是http://localhost/test/aaa.html,我的应用上下文是test,容器会将http://localhost/test去掉,剩下的/aaa.html部分拿来做servlet的映射匹配。这个映射匹配过程是有顺序的,而且当有一个servlet匹配成功以后,就不会去理会剩下的servlet了(filter不同,后文会提到)。其匹配规则和顺序如下:

1.     精确路径匹配。例子:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先 进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的servlet了。

2.     最长路径匹配。例子:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。

3.     扩展匹配,如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action

4.     如果前面三条规则都没有找到一个servlet,容器会根据url选择对应的请求资源。如果应用定义了一个default servlet,则容器会将请求丢给default servlet

3、Listener功能

它是基于观察者模式设计的,Listener 的设计对开发 Servlet 应用程序提供了一种快捷的手段,能够方便的从另一个纵向维度控制程序和数据。目前 Servlet 中提供了 5 种两类事件的观察者接口,它们分别是:4 个 EventListeners 类型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener 和 2 个 LifecycleListeners 类型的,ServletContextListener、HttpSessionListener。如下图所示:

Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1。常用的监听接口有以下几个:

ServletContextAttributeListener监听对ServletContext属性的操作,比如增加、删除、修改属性。

ServletContextListener监听ServletContext。当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。

HttpSessionListener监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。

HttpSessionAttributeListener监听HttpSession中的属性的操作。当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。

下面我们开发一个具体的例子,这个监听器能够统计在线的人数。在ServletContext初始化和销毁时,在服务器控制台打印对应的信息。当ServletContext里的属性增加、改变、删除时,在服务器控制台打印对应的信息。

要获得以上的功能,监听器必须实现以下3个接口:

HttpSessionListener

ServletContextListener

ServletContextAttributeListener

例子:

[java] view plaincopy
  1. /** 
  2.  *  
  3.  */  
  4. package com.ee.listener;  
  5. import javax.servlet.ServletContextAttributeEvent;  
  6. import javax.servlet.ServletContextAttributeListener;  
  7. import javax.servlet.ServletContextEvent;  
  8. import javax.servlet.ServletContextListener;  
  9. import javax.servlet.http.HttpSessionEvent;  
  10. import javax.servlet.http.HttpSessionListener;  
  11. /** 
  12.  * @author Administrator 
  13.  * 
  14.  */  
  15. public class OnlineUserListener implements HttpSessionListener,  
  16. ServletContextListener, ServletContextAttributeListener {
  17. private long onlineUserCount = 0;  
  18. public long getOnlineUserCount() {  
  19. return onlineUserCount;  
  20. }
  21. /* (non-Javadoc) 
  22.      * @see javax.servlet.ServletContextAttributeListener#attributeAdded(javax.servlet.ServletContextAttributeEvent) 
  23.      */  
  24. @Override  
  25. public void attributeAdded(ServletContextAttributeEvent arg0) {  
  26. }
  27. /* (non-Javadoc) 
  28.      * @see javax.servlet.ServletContextAttributeListener#attributeRemoved(javax.servlet.ServletContextAttributeEvent) 
  29.      */  
  30. @Override  
  31. public void attributeRemoved(ServletContextAttributeEvent arg0) {  
  32. }
  33. /* (non-Javadoc) 
  34.      * @see javax.servlet.ServletContextAttributeListener#attributeReplaced(javax.servlet.ServletContextAttributeEvent) 
  35.      */  
  36. @Override  
  37. public void attributeReplaced(ServletContextAttributeEvent attributeEvent) {  
  38. System.err.println("...attributeReplaced...");  
  39. }
  40. /* (non-Javadoc) 
  41.      * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) 
  42.      */  
  43. @Override  
  44. public void contextDestroyed(ServletContextEvent arg0) {  
  45. }
  46. /* (non-Javadoc) 
  47.      * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
  48.      */  
  49. @Override  
  50. public void contextInitialized(ServletContextEvent arg0) {  
  51. }
  52. /* (non-Javadoc) 
  53.      * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent) 
  54.      */  
  55. @Override  
  56. public void sessionCreated(HttpSessionEvent httpSessionEvent) {  
  57. onlineUserCount ++;
  58. toUpdateCount(httpSessionEvent);
  59. }
  60. /* (non-Javadoc) 
  61.      * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) 
  62.      */  
  63. @Override  
  64. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {  
  65. onlineUserCount --;
  66. toUpdateCount(httpSessionEvent);
  67. }
  68. private void toUpdateCount(HttpSessionEvent httpSessionEvent){  
  69. httpSessionEvent.getSession().setAttribute("onlineUserCount", onlineUserCount);  
  70. }
  71. }

Web.xml

[html] view plaincopy
  1. <listener>  
  2. <listener-class>com.ee.listener.OnlineUserListener</listener-class>  
  3. </listener>  



JSP页面:

[html] view plaincopy
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2. pageEncoding="UTF-8"%>  
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
    4. <html>  
    5. <head>  
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    7. <title>主页</title>  
    8. </head>  
    9. <body>  
    10. <h4>你好!</h4>  
    11. 在线人数:<h1><%=request.getSession().getAttribute("onlineUserCount") %></h1>  
    12. </body>  
    13. </html>  

相关文章:

CentOS 6安装DHCP

#wget ftp://ftp.isc.org/isc/dhcp/dhcp-4.2.3/dhcp-4.2.3.tar.gz #tar xvzf dhcp-4.2.3.tar.gz# cd dhcp-4.2.3#./configure #make #make install

小米AI实验室六篇论文获ICASSP2022收录,多模态语音唤醒挑战赛夺冠

1月22日&#xff0c;全球语音、声学顶级会议ICASSP 2022公布了论文入选名单&#xff0c;小米AI实验室6篇学术论文被接收。小米“自由说”系统在MISP&#xff08;基于多模态信息的语音处理&#xff09;挑战赛中荣获多模态语音唤醒第一名和多模态语音识别第二名&#xff0c;并受邀…

React + Koa 实现服务端渲染(SSR)

⚛️React是目前前端社区最流行的UI库之一&#xff0c;它的基于组件化的开发方式极大地提升了前端开发体验&#xff0c;React通过拆分一个大的应用至一个个小的组件&#xff0c;来使得我们的代码更加的可被重用&#xff0c;以及获得更好的可维护性&#xff0c;等等还有其他很多…

11 款可替代 top 命令的工具!

‍‍作者 | JackTian来源 | 杰哥的IT之旅在 Linux 环境下 top 命令都不陌生&#xff0c;它以实时动态的方式查看系统的整体运行情况&#xff0c;综合了多方信息监测系统性能和运行信息的实用工具&#xff0c;通过 top 命令所提供的互动式界面&#xff0c;可以用热键来进行管理。…

几个重要的RFC

RFC目录 权威无须解释 http://www.ietf.org/rfc/RFC中文目录http://man.chinaunix.net/develop/rfc/default.htm几个常用的RFC参考&#xff1a; RFC1945 超文本传输协议--HTTP/1.0 RFC2616超文本传输协议--HTTP/1.1 对 RFC2068的补充RFC3920可扩展的消息和出席信息协议 (XMPP)…

iOS开发笔记-两种单例模式的写法

iOS开发笔记&#xff0d;两种单例模式的写法 单例模式是开发中最常用的写法之一&#xff0c;iOS的单例模式有两种官方写法&#xff0c;如下&#xff1a; 不使用GCD #import "ServiceManager.h"static ServiceManager *defaultManager;implementation ServiceManager(…

流式大数据处理的三种框架:Storm,Spark和Samza

2019独角兽企业重金招聘Python工程师标准>>> 许多分布式计算系统都可以实时或接近实时地处理大数据流。本文将对三种Apache框架分别进行简单介绍&#xff0c;然后尝试快速、高度概述其异同。 Apache Storm 在Storm中&#xff0c;先要设计一个用于实时计算的图状结构…

CentOS用yum安装X Window

安装X图形界面系统yum list 列出所有可安装的软件包 可以通过 yum grouplist 来查看可能批量安装哪些列表 先装X windows #yum groupinstall X Window System -y 安装GNOME桌面环境#yum groupinstall GNOME Desktop Environment -y 安装KDE桌面环境#yum groupinstall KDE (K D…

Oracle VDI 安装

为什么80%的码农都做不了架构师&#xff1f;>>> 你可以在这里找到本文的原文。 虽然说Oracle已经停止了VDI的开发&#xff0c;之后支持服务业很快停止了。但是&#xff0c;作为经典的桌面虚拟化产品&#xff0c;还是值得研究一番。虽然Oracle VDI的文档已经写的很详…

Python 写了一个网页版的「P图软件」,惊呆了!

作者 | 小欣来源 | Python爱好者集中营今天是开工第一天&#xff0c;这篇文章可以算作是虎年的第一篇干货技术类文章了&#xff0c;今天小编用Python做了一个网页版的“P图软件”&#xff0c;大致的流程在于我们可以将上传的照片进行黑白处理、铅笔素描处理、模糊化处理等一系列…

Template mode HTML5 has not been configured

#thymeleafspring.thymeleaf.prefixclasspath:/templates/spring.thymeleaf.suffix.htmlspring.thymeleaf.cachefalsespring.thymeleaf.content-typetext/htmlspring.thymeleaf.enabledtruespring.thymeleaf.encodingUTF-8spring.thymeleaf.modeHTML5 解决办法&#xff1a;注释…

Java数据结构与算法(第四章栈和队列)

2019独角兽企业重金招聘Python工程师标准>>> 本章涉及的三种数据存储类型&#xff1a;栈、队列和优先级队列。 不同类型的结构 程序员的工具 数组是已经介绍过的数据存储结构&#xff0c;和其他结构&#xff08;链表、树等等&#xff09;一样&#xff0c;都适用于数…

可构建AI的「AI」诞生:几分之一秒内,就能预测新网络的参数

‍‍来源 | 学术头条人工智能在很大程度上是一场数字游戏。当深度神经网络在 10 年前开始超越传统算法&#xff0c;是因为我们终于有了足够的数据和处理能力来充分利用它们。今天的神经网络更依赖于数据和算力。训练网络时&#xff0c;需要仔细调整表征网络的数百万甚至数十亿参…

It is not safe to rely on the system's timezone settings

在写php程序中有时会出现这样的警告&#xff1a; PHP Warning: date(): It is not safe to rely on the systems timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those metho…

.NET MVC+ EF+LINQ 多表联查VIEW显示列表

1.VIEW 页面显示代码 <link href"~/Content/bootstrap.css" rel"stylesheet" /><div class"well"><table class"table"><tr><th>用户名</th><th>地址</th><th>订单编号</th…

从奥运订票系统说起——谈FastCGI 与IT 架构

2008年&#xff0c;对于首都人民来说&#xff0c;没有什么比奥运会更大的事情了。如何买到一张称心如意的比赛门票&#xff0c;也成了很多人的一个梦想。然而&#xff0c;在奥运官网抢票购买的时候&#xff0c;这个梦想却轻易地被网上购票系统的当机击成碎片&#xff0c;很多充…

【哲学百科】文艺复兴及唯理主义时期(公元1500~公元1750)

我为达目的&#xff0c;不择手段-尼古拉.马基雅维利要令习惯于君主统治的民众保有自由是一件多么困难的事情。马基雅维利的观点之一是君主不应受到道德标准的束缚&#xff0c;而应竭尽所能保全自身的荣耀以及所统治的城邦的胜利与繁荣&#xff0c;这种做法随后被人们归为现实主…

如何用 OpenGL 绘制雪花?

作者 | 许向武 责编 | 张红月出品 | CSDN博客看冬奥才知道&#xff0c;阿勒泰不但是中国的“雪都”&#xff0c;还是“人类滑雪起源地”。这个说法是否成立&#xff0c;姑且不论&#xff0c;阿勒泰的雪的确很漂亮。冬奥会有一个宣传片&#xff0c;就是借用一朵阿勒泰雪花…

面试之Hashtable和ConcurrentHashMap

那么要如何保证HashMap的线程安全呢&#xff1f; 方法有很多&#xff0c;比如使用Hashtable或者Collections.synchronizedMap&#xff0c;但是这两位选手都有一个共同的问题&#xff1a;性能。因为不管是读还是写操作&#xff0c;他们都会给整个集合上锁&#xff0c;导致同一时…

PHP动态编译出现Cannot find autoconf

在安装完PHP后,想动态编译PHP的memcache扩展库 cd memcache-2.2.5//usr/local/webserver/php/bin/phpize./configure --with-php-config/usr/local/webserver/php/bin/php-config 但是执行/usr/local/webserver/php/bin/phpize时出现错误:Configuring for:PHP Api Version: …

AnimeGANv2 实现动漫风格迁移,简单操作

作者 | Yunlord出品 | CSDN博客前言之前一直在研究如何将图像动漫化&#xff0c;尝试了阿里云api和百度api&#xff0c;效果都不尽如人意。结果发现了一个宝藏github项目——AnimeGANv2&#xff0c;能够将现实世界场景照片进行动漫风格化。可以看出AnimeGAN的效果非常好&#x…

C#调用win32 api程序实例

1、声明static extern 方法&#xff0c;使用DllImport特性 class MyClass{[DllImport("kernel32", SetLastError true)]public static extern int GetCurrentDirectory(int a, StringBuilder b);} 2、调用 StringBuilder sbnew StringBuilder {Length 250}; MyClas…

Python 之 pip拒绝访问

起因 在我使用pip安装第三方库的时候&#xff0c;控制台提示我升级pip版本 You are using pip version 9.0.1, however version 10.0.1 is available. You should consider upgrading via the python -m pip install --upgrade pip command. 很显然&#xff0c;需要使用这样的指…

Unix / 类 Unix shell 中有哪些很酷很冷门很少用很有用的命令?(转)

著作权归作者所有。 商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 作者&#xff1a;孙立伟 链接&#xff1a;http://www.zhihu.com/question/20140085/answer/14107336 来源&#xff1a;知乎 这个问题quora上有人提过 What are some lesser known but useful…

干货满满的 Python 实战项目,点赞收藏

作者 | 俊欣来源 | 关于数据分析与可视化今天小编来给大家介绍3个干货满满的计算机视觉方向的Python实战项目&#xff0c;主要用到的库有opencv-pythonnumpypillow要是大家所配置的环境当中没有这几个模块的话&#xff0c;就需要先用pip命令下载安装pip install opencv-python …

php安装完成以后要复制php.ini文件

直接 #find / -name "php.ini" 找不到&#xff0c;是因为安装php的时候没有复制配置文件 php版本变化以后ini文件名有变 php.ini-production对应于php.ini-recommended php.ini-development对应于php.ini-dist二者差异&#xff1f; 由于版本更新,这些文件有了新的命…

MASQUERADE --random 端口不随机

iptables -t nat -A POSTROUTING -o xxxx -j MASQUERADE --random发现源端口并不是随机的而是有规律递增&#xff0c;经过Google的搜索查找&#xff0c;发现新的版本有--random-full 这个参数iptables -t nat -A POSTROUTING -o xxxx -j MASQUERADE --random-full经过测试端口随…

PHP安装与使用VLD查看opcode代码【PHP安装第三方扩展的方法】

需要分析PHP代码的性能&#xff0c;或者说实现同样功能的代码到底哪个更好呢&#xff1f;或者说想知道底层的实现可以使用VLD查看opcode 下载与安装VLD # wget http://pecl.php.net/get/vld-0.11.2.tgz# tar zxvf vld-0.11.2.tgz# cd ./vld-0.11.2# /usr/local/php/bin/phpize …

实现数组字符串翻转的两种方法

//第一种方法&#xff1a;递归法 #include <stdio.h> int reverse_string(char * string) {if (*string ! \0){reverse_string(string1);printf("%c", *string);} } int main() {char *string "abcde";printf("源字符串为&#xff1a;%s\n&quo…

详解 Python 如何将爬取到的数据分别存储到 txt、excel、mysql 中!

作者 | 黄伟呢来源 | 数据分析与统计学之美1. 页面分析我爬取的页面是腾讯体育&#xff0c;链接如下&#xff1a;https://nba.stats.qq.com/player/list.htm观察上图&#xff1a;左边展示的分别是NBA的30支球队&#xff0c;右边就是每只球队对应球员的详细信息。此时思路就很清…