- 浏览: 564958 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (618)
- java (109)
- Java web (43)
- javascript (52)
- js (15)
- 闭包 (2)
- maven (8)
- 杂 (28)
- python (47)
- linux (51)
- git (18)
- (1)
- mysql (31)
- 管理 (1)
- redis (6)
- 操作系统 (12)
- 网络 (13)
- mongo (1)
- nginx (17)
- web (8)
- ffmpeg (1)
- python安装包 (0)
- php (49)
- imagemagic (1)
- eclipse (21)
- django (4)
- 学习 (1)
- 书籍 (1)
- uml (3)
- emacs (19)
- svn (2)
- netty (9)
- joomla (1)
- css (1)
- 推送 (2)
- android (6)
- memcached (2)
- docker、 (0)
- docker (7)
- go (1)
- resin (1)
- groovy (1)
- spring (1)
最新评论
-
chokee:
...
Spring3 MVC 深入研究 -
googleyufei:
很有用, 我现在打算学学Python. 这些资料的很及时.
python的几个实用网站(转的) -
hujingwei1001:
太好了找的就是它
easy explore -
xiangtui:
例子举得不错。。。学习了
java callback -
幻影桃花源:
太好了,謝謝
Spring3 MVC 深入研究
Tomcat源码系列1--Tomcat启动流程1
文章分类:Java编程
最近在看Tomcat的源码,下面用博客记下看源码的一些心得。
Tomcat是从org.apache.catalina.startup.Bootstrap#main()开始启动. 大致分为三个步骤,即init、load和start。代码如下:
- public static void main(String args[]) {
- try {
- // Attempt to load JMX class
- new ObjectName( "test:foo=bar" );
- } catch (Throwable t) {
- System.out.println(JMX_ERROR_MESSAGE);
- try {
- // Give users some time to read the message before exiting
- Thread.sleep(5000 );
- } catch (Exception ex) {
- }
- return ;
- }
- if (daemon == null ) {
- daemon = new Bootstrap();
- try {
- daemon.init(); ★1
- } catch (Throwable t) {
- t.printStackTrace();
- return ;
- }
- }
- try {
- String command = "start" ;
- if (args.length > 0 ) {
- command = args[args.length - 1 ];
- }
- if (command.equals( "startd" )) {
- args[0 ] = "start" ;
- daemon.load(args);
- daemon.start();
- } else if (command.equals( "stopd" )) {
- args[0 ] = "stop" ;
- daemon.stop();
- } else if (command.equals( "start" )) {
- daemon.setAwait(true );
- daemon.load(args); ★2
- // 反射调用Catalina的start方法
- daemon.start(); ★3
- } else if (command.equals( "stop" )) {
- daemon.stopServer(args);
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
public static void main(String args[]) { try { // Attempt to load JMX class new ObjectName("test:foo=bar"); } catch (Throwable t) { System.out.println(JMX_ERROR_MESSAGE); try { // Give users some time to read the message before exiting Thread.sleep(5000); } catch (Exception ex) { } return; } if (daemon == null) { daemon = new Bootstrap(); try { daemon.init(); ★1 } catch (Throwable t) { t.printStackTrace(); return; } } try { String command = "start"; if (args.length > 0) { command = args[args.length - 1]; } if (command.equals("startd")) { args[0] = "start"; daemon.load(args); daemon.start(); } else if (command.equals("stopd")) { args[0] = "stop"; daemon.stop(); } else if (command.equals("start")) { daemon.setAwait(true); daemon.load(args); ★2 // 反射调用Catalina的start方法 daemon.start(); ★3 } else if (command.equals("stop")) { daemon.stopServer(args); } } catch (Throwable t) { t.printStackTrace(); } }
从以上可以很清楚的看出tomcat是通过参数的不同进行相应的命令调用。
★1 启动、初始化(加载类)
启动之前要进行相应的init()初始化,进行相应的环境设置以及包的加,以下是init()方法。(org.apache.catalina.startup.Bootstrap.init())
- public void init()
- throws Exception
- {
- setCatalinaHome();//设置Catalina安装目录
- setCatalinaBase();//设置Catalina工作目录
- initClassLoaders();//加载jar包
- // 将classload设置进线程,以便我们使用时进行调用
- Thread.currentThread().
- setContextClassLoader(catalinaLoader);
- SecurityClassLoad.securityClassLoad(catalinaLoader);
- // 加载启动类和调用它的process方法
- if (log.isDebugEnabled())
- log.debug("Loading startup class" );
- Class startupClass =
- catalinaLoader.loadClass
- ("org.apache.catalina.startup.Catalina" );
- Object startupInstance = startupClass.newInstance();
- // 设置共享扩张类加载器
- if (log.isDebugEnabled())
- log.debug("Setting startup class properties" );
- String methodName = "setParentClassLoader" ;
- Class paramTypes[] = new Class[ 1 ];
- paramTypes[0 ] = Class.forName( "java.lang.ClassLoader" );
- Object paramValues[] = new Object[ 1 ];
- paramValues[0 ] = sharedLoader;
- Method method =
- startupInstance.getClass().getMethod(methodName,
- paramTypes);
- method.invoke(startupInstance, paramValues);
- catalinaDaemon = startupInstance;
- }
public void init() throws Exception { setCatalinaHome();//设置Catalina安装目录 setCatalinaBase();//设置Catalina工作目录 initClassLoaders();//加载jar包 // 将classload设置进线程,以便我们使用时进行调用 Thread.currentThread(). setContextClassLoader(catalinaLoader); SecurityClassLoad.securityClassLoad(catalinaLoader); // 加载启动类和调用它的process方法 if (log.isDebugEnabled()) log.debug("Loading startup class"); Class startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.newInstance(); // 设置共享扩张类加载器 if (log.isDebugEnabled()) log.debug("Setting startup class properties"); String methodName = "setParentClassLoader"; Class paramTypes[] = new Class[1]; paramTypes[0] = Class.forName("java.lang.ClassLoader"); Object paramValues[] = new Object[1]; paramValues[0] = sharedLoader; Method method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance; }
在加载jar的时候,需要初始化classloader,代码如下:(org.apache.catalina.startup.Bootstrap)
- private void initClassLoaders() {
- try {
- commonLoader = createClassLoader("common" , null );
- catalinaLoader= createClassLoader("server" , commonLoader);
- sharedLoader = createClassLoader("shared" , commonLoader);
- } catch (Throwable t) {
- log.error("Class loader creation threw exception" , t);
- System.exit(1 );
- }
- }
private void initClassLoaders() { try { commonLoader = createClassLoader("common", null); catalinaLoader= createClassLoader("server", commonLoader); sharedLoader = createClassLoader("shared", commonLoader); } catch (Throwable t) { log.error("Class loader creation threw exception", t); System.exit(1); } }
tomcat中的加载方式是:
|-------commonLoader (common)-> System Loader
|-------sharedLoader (shared)-> commonLoader -> System Loader
|-------catalinaLoader(server) -> commonLoader -> System Loader
Common
是公共类加载器,负责加载tomcat内部和web应用程序可以看到的类(%CATALINA_HOME%/bin/common下的jar文
件),Catalina负责加载的是tomcat内部使用的类(%CATALINA_HOME%/server下的jar文件),这些类对web应用程序
不可见。Shared负责加载的是web应用程序之间共享的类(%CATALINA_BASE%/shared下的jar文件),这些类对于tomcat
内部是不可见的。如果%CATALINA_HOME%/conf/catalina.Properties中没有指定Common的搜索路径,则用当前的
类的类加载器即系统类加载器作为Common。
★2 装载相应的资源
下面主要讲解tomcat的load()方法。下图是Catalina.load方法的时序图。
(1) 从上面的时序图可以看出首先调用Catalina类的load()方法,具体代码如下:
(org.apache.catalina.startup.Catalina)。
- public void load() {
- initDirs();
- // Before digester - it may be needed
- initNaming();
- // Create and execute our Digester
- Digester digester = createStartDigester();
- try {
- inputSource.setByteStream(inputStream);
- digester.push(this );
- digester.parse(inputSource); //对server.xml进行解析
- inputStream.close();
- }
- ......
- // Start the new server
- if (server instanceof Lifecycle) {
- try {
- server.initialize(); //server初始化工作
- } catch (LifecycleException e) {
- log.error("Catalina.start" , e);
- }
- }
- long t2 = System.currentTimeMillis();
- log.info("Initialization processed in " + (t2 - t1) + " ms" );
- }
public void load() { initDirs(); // Before digester - it may be needed initNaming(); // Create and execute our Digester Digester digester = createStartDigester(); try { inputSource.setByteStream(inputStream); digester.push(this); digester.parse(inputSource); //对server.xml进行解析 inputStream.close(); } ...... // Start the new server if (server instanceof Lifecycle) { try { server.initialize(); //server初始化工作 } catch (LifecycleException e) { log.error("Catalina.start", e); } } long t2 = System.currentTimeMillis(); log.info("Initialization processed in " + (t2 - t1) + " ms"); }
(2) 在上面的load()方法中需要进行server的初始化工作,下图为Catalina.initialize的时序图,从图中可以看出server初始化所完成的工作。
至此,load方法结束,初期化的工作结束,下面开始进入start方法。
★3 容器启动
容器启动时,会调用Catalina.start(),下图为它的时序图。从图中可以看出StandardService的start方法被调用后会分别对Container和Connector进行start方法的调用。
1. Bootstrap调用Catalina的start方法
Catalina.start()方法(org.apache.catalina.startup.Catalina.start())
- public void start() {
- // 启动server
- if (server instanceof Lifecycle) {
- try {
- ((Lifecycle) server).start();
- ......
- }
public void start() { // 启动server if (server instanceof Lifecycle) { try { ((Lifecycle) server).start(); ...... }
2. Catalina调用StandardServer的start方法
StandardServer.start() (org.apache.catalina.core.StandardServer.start() )
- public void start() throws LifecycleException {
- synchronized (services) {
- for ( int i = 0 ; i < services.length; i++) {
- if (services[i] instanceof Lifecycle)
- ((Lifecycle) services[i]).start();
- }
- }
public void start() throws LifecycleException { synchronized (services) { for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).start(); } }
3. StandardServer调用StandardService的start方法
- org.apache.catalina.core.StandardService.start() )
- public void start() throws LifecycleException {
- if (container != null ) {
- synchronized (container) {
- if (container instanceof Lifecycle) {
- // standardEngine的启动
- ((Lifecycle) container).start();
- }
- }
- //两个connector的启动,8080和8009
- synchronized (connectors) {
- for ( int i = 0 ; i < connectors.length; i++) {
- if (connectors[i] instanceof Lifecycle)
- ((Lifecycle) connectors[i]).start();
- }
- }
- }
org.apache.catalina.core.StandardService.start() ) public void start() throws LifecycleException { if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { // standardEngine的启动 ((Lifecycle) container).start(); } } //两个connector的启动,8080和8009 synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); } } }
以上StandardService.start()方法主要实现了两个功能,standardEngine的启动和connector的启动,下面分别来介绍。
Tomcat源码系列2--Tomcat启动流程2
文章分类:Java编程
下面是standardEngine 的启动和 connector 的启动
● standardEngine的启动
(1) 首先是StandardEngine.start()被调用
- public void start() throws LifecycleException {
- // Standard container startup
- //进行logger,manager,cluster,realm,resource的启动
- super .start();
- }
public void start() throws LifecycleException { // Standard container startup //进行logger,manager,cluster,realm,resource的启动 super.start(); }
(2) super.start()--->org.apache.catalina.core.ContainerBase#start()
- public synchronized void start() throws LifecycleException {
- //(省略) server.xml中配置应用组件的启动
- //StandardHost容器的启动,
- Container children[] = findChildren();
- for ( int i = 0 ; i < children.length; i++) {
- if (children[i] instanceof Lifecycle)
- ((Lifecycle) children[i]).start();
- }
- //StandardPipeline的启动(容器与容器间的管道)
- if (pipeline instanceof Lifecycle)
- ((Lifecycle) pipeline).start();
- }
public synchronized void start() throws LifecycleException { //(省略) server.xml中配置应用组件的启动 //StandardHost容器的启动, Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).start(); } //StandardPipeline的启动(容器与容器间的管道) if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); }
(3) StandardHost.start()被调用
- public synchronized void start() throws LifecycleException {
- //返回到以上的containerBase#start执行pipeline
- super .start();
- }
public synchronized void start() throws LifecycleException { //返回到以上的containerBase#start执行pipeline super.start(); }
(4) StandardPipeline#start
- public synchronized void start() throws LifecycleException {
- // 将会调用HostConfig#start方法
- lifecycle.fireLifecycleEvent(START_EVENT, null );
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null );
- }
public synchronized void start() throws LifecycleException { // 将会调用HostConfig#start方法 lifecycle.fireLifecycleEvent(START_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
(5) HostConfig#start
public void start() { //部暑webapps deployApps(); }
(6) HostConfig#deployApps
- protected void deployApps() {
- File appBase = appBase();
- File configBase = configBase();
- // Deploy XML descriptors from configBase
- deployDescriptors(configBase, configBase.list());
- // Deploy WARs, and loop if additional descriptors are found
- deployWARs(appBase, appBase.list());
- // Deploy expanded folders
- deployDirectories(appBase, appBase.list());
- }
protected void deployApps() { File appBase = appBase(); File configBase = configBase(); // Deploy XML descriptors from configBase deployDescriptors(configBase, configBase.list()); // Deploy WARs, and loop if additional descriptors are found deployWARs(appBase, appBase.list()); // Deploy expanded folders deployDirectories(appBase, appBase.list()); }
(7) deployWARs
- protected void deployWARs(File appBase, String[] files) {
- ……
- deployWAR(contextPath, dir, file);
- }
protected void deployWARs(File appBase, String[] files) { …… deployWAR(contextPath, dir, file); }
(8) deployWAR
- protected void deployWAR(String contextPath, File war, String file) {
- if (context instanceof Lifecycle) {
- // (省略)
- Class clazz = Class.forName(host.getConfigClass());
- LifecycleListener listener =
- (LifecycleListener) clazz.newInstance();
- ((Lifecycle) context).addLifecycleListener(listener);
- }
- context.setPath(contextPath);
- context.setDocBase(file);
- //以下这一步跟进去,,StandardContext的启动
- host.addChild(context);
- }
protected void deployWAR(String contextPath, File war, String file) { if (context instanceof Lifecycle) { // (省略) Class clazz = Class.forName(host.getConfigClass()); LifecycleListener listener = (LifecycleListener) clazz.newInstance(); ((Lifecycle) context).addLifecycleListener(listener); } context.setPath(contextPath); context.setDocBase(file); //以下这一步跟进去,,StandardContext的启动 host.addChild(context); }
(9) StandardContext#start
在Context的启动过程中,主要完成了以下任务。
----------------------------------------------------------------------------------------------------------------------
a) 设置web app的具体目录webappResources。
b) postWorkDirectory (),创建临时文件目录。Tomcat下面有一个work目录,用来存放临时文件。
c) 触发START_EVENT事件监听,在这个事件监听里面会启动ContextConfig的start()事件,ContextConfig是用来配置web.xml的。
d) 为context创建welcome files,通常是这三个启动文件:index.html、index.htm、index.jsp
e) 配置filter
f) 启动带有<load-on-startup>的Servlet。
g) 注册JMX。
----------------------------------------------------------------------------------------------------------------------
至此,Container启动完毕,下面是connector的启动。
● connector的启动
(1) org.apache.catalina.connector.Connector.start()
- public void start() throws LifecycleException {
- // Http11Protocol的启动
- protocolHandler.start();
- }
public void start() throws LifecycleException { // Http11Protocol的启动 protocolHandler.start(); }
(2) Http11Protocol#start
- public void start() throws Exception {
- try {
- //到了终点的启动
- endpoint.start();
- } catch (Exception ex) {
- log.error(sm.getString("http11protocol.endpoint.starterror" ), ex);
- throw ex;
- }
public void start() throws Exception { try { //到了终点的启动 endpoint.start(); } catch (Exception ex) { log.error(sm.getString("http11protocol.endpoint.starterror"), ex); throw ex; }
(3) JIoEndPoint#start
- public void start()
- throws Exception {
- for ( int i = 0 ; i < acceptorThreadCount; i++) {
- //这里的acceptor是一个线程,里面是一个serversocket的启动
- Thread acceptorThread = new Thread( new Acceptor(), getName() + "-Acceptor-" + i);
- acceptorThread.setPriority(threadPriority);
- acceptorThread.setDaemon(daemon);
- acceptorThread.start();
- }
- }
public void start() throws Exception { for (int i = 0; i < acceptorThreadCount; i++) { //这里的acceptor是一个线程,里面是一个serversocket的启动 Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i); acceptorThread.setPriority(threadPriority); acceptorThread.setDaemon(daemon); acceptorThread.start(); } }
(4) Acceptor#run
- public void run() {
- // Accept the next incoming connection from the server socket
- try {
- //这里进行了accept(),等待客户端消息,进行接收
- Socket socket = serverSocketFactory.acceptSocket(serverSocket);
- serverSocketFactory.initSocket(socket);
- // Hand this socket off to an appropriate processor
- if (!processSocket(socket)) {
- // Close socket right away
- try {
- socket.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }catch ( IOException x ) {
- if ( running ) log.error(sm.getString( "endpoint.accept.fail" ), x);
- } catch (Throwable t) {
- log.error(sm.getString("endpoint.accept.fail" ), t);
- }
- }
public void run() { // Accept the next incoming connection from the server socket try { //这里进行了accept(),等待客户端消息,进行接收 Socket socket = serverSocketFactory.acceptSocket(serverSocket); serverSocketFactory.initSocket(socket); // Hand this socket off to an appropriate processor if (!processSocket(socket)) { // Close socket right away try { socket.close(); } catch (IOException e) { // Ignore } } }catch ( IOException x ) { if ( running ) log.error(sm.getString("endpoint.accept.fail"), x); } catch (Throwable t) { log.error(sm.getString("endpoint.accept.fail"), t); } }
至此Connector.start方法调用完毕。整个server启动完毕。
Tomcat源码系列3--Tomcat请求处理的流程
文章分类:Java编程
本次讲解一下Tomcat请求处理的流程,不当之处还请comment。
一. Tomcat 总体结构
Tomcat采用模块化管理,下面是 Tomcat 的总体结构图:
从上图中可以看出 Tomcat 的核心是两个组件:Connector 和 Container。下面是一些概念的介绍。
① Server
一个server代表了整个catalina servlet容器,在Tomcat里面的Server的用处是启动和监听服务端事件(诸如重启、关闭等命令)。
② Service
Service是由一个或多个Connector与一个Engine的组合。
③ Connector
Connector将在某个指定的端口上监听客户的请求,把从socket传递过来的数据,封装成Request,传递给Engine来处理,并从Engine处获得响应并返回给客户。
Tomcat通常会用到两种Connector:
a) Http Connector 在端口8080处侦听来自客户browser的http请求。
b) AJP Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求。
二、请求处理过程解析
1. Connector处理请求
Connector处理请求的流程大致如下:
Connector组件启动后,会侦听相关的端口的客户端请求。
(1) 接受一个新的连接请求(org.apache.tomcat.util.net.TcpWorkerThread)
- void runIt(Object[] perThrData){
- Socket s = null ;
- try {
- s = endpoint.acceptSocket(); //获取一个请求
- } finally {
- if (endpoint.isRunning()) {
- endpoint.tp.runIt(this );
- // 此处启动另一个TcpWorkerTread去接受其他请求,此线程处理已接受的请求
- }
- }
- TcpConnection con = null ;
- con = (TcpConnection) perThrData[0 ];
- con.setEndpoint(endpoint);
- con.setSocket(s);endpoint.getConnectionHandler().processConnection(con,(Object[]) perThrData[1 ]);
- }
void runIt(Object[] perThrData){ Socket s = null; try { s = endpoint.acceptSocket(); //获取一个请求 } finally { if (endpoint.isRunning()) { endpoint.tp.runIt(this); // 此处启动另一个TcpWorkerTread去接受其他请求,此线程处理已接受的请求 } } TcpConnection con = null; con = (TcpConnection) perThrData[0]; con.setEndpoint(endpoint); con.setSocket(s);endpoint.getConnectionHandler().processConnection(con,(Object[]) perThrData[1]); }
(2) 新接收的请求被传到Http11ConnectionHandler中处理。(org.apache.coyote.http11.Http11Protocol.Http11ConnectionHandler)
- void processConnection(TcpConnection connection, Object[] thData){
- Http11Processor processor=null ;
- processor=(Http11Processor)thData[Http11Protocol.THREAD_DATA_PROCESSOR];
- socket=connection.getSocket();
- InputStream in = socket.getInputStream();
- OutputStream out = socket.getOutputStream();
- processor.setSocket(socket );
- processor.process(in, out);
- //processor是org.apache.coyote.http11.Http11Processor 的 一个实例
- }
void processConnection(TcpConnection connection, Object[] thData){ Http11Processor processor=null; processor=(Http11Processor)thData[Http11Protocol.THREAD_DATA_PROCESSOR]; socket=connection.getSocket(); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); processor.setSocket(socket ); processor.process(in, out); //processor是org.apache.coyote.http11.Http11Processor 的 一个实例 }
(3) 在 Http11Processor 中处理 http11 协议相关的信息(org.apache.coyote.http11.Http11Processor)
- void process(InputStream input, OutputStream output) throws IOException{
- ~~略~~
- inputBuffer.setInputStream(input);
- outputBuffer.setOutputStream(output);
- inputBuffer.parseHeaders();
- //http11 协议头在此方法中被取出
- adapter.service(request, response);
- //adapter 是org.apache.catalina.connector.CoyoteAdapter 的 一个实例
- }
void process(InputStream input, OutputStream output) throws IOException{ ~~略~~ inputBuffer.setInputStream(input); outputBuffer.setOutputStream(output); inputBuffer.parseHeaders(); //http11 协议头在此方法中被取出 adapter.service(request, response); //adapter 是org.apache.catalina.connector.CoyoteAdapter 的 一个实例 }
接下来的流程交由容器进行处理。
2. 容器处理请求
容器交由Pipeline处理,这个Pipeline里面会放置一些vavle,请求沿着pipeline传递下去并且vavle对其进行相关的处理。比如说日志等,valve还可以自定义,具体需要查看server.xml配置文件。相关类图如下:
Tomcat
的主要处理组件Engine、Host、Context和Wrapper的实现都会实现Pipeline接口,实际对请求的处理是一个
Adpater,Tomcat中Adapter的实现是CoyoteAdapter,因此容器请求处理的入口是CoyoteAdapter的
service方法。
1. CoyoteAdapter.service
--组装好请求处理链
--StandardEngine. getPipeline().getFirst().invoke(request, response);
--StandardEngineValve.invoke
2. StandardEngineValve.invoke
--Host.getPipeline().getFirst().invoke(request, response);
--StandardHostValve.invoke
3. StandardHostValve.invoke
--Context. getPipeline().getFirst().invoke(request, response);
--StandardContextValve.invoke
4. StandardContextValve.invoke
--ServletRequestListener.requestInitialized
--Wrapper.getPipeline().getFirst().invoke(request, response);
--StandardWrapperValve.invoke
-- ServletRequestListener.requestDestroyed
5. StandardWrapperValve.invoke
--组装Filter+Servlet
--处理请求
(1) Connector传来的请求调用CoyoteAdapter.service()方法。(org.apache.catalina.connector.CoyoteAdapter)
- public void service(org.apache.coyote.Request req,
- org.apache.coyote.Response res)
- throws Exception {
- ~~略~~
- if (request == null ) {
- request = (Request) connector.createRequest();
- request.setCoyoteRequest(req);
- response = (Response) connector.createResponse();
- response.setCoyoteResponse(res);
-
//创建request、response对象
</spa
发表评论
-
HTTP协议之multipart/form-data请求分析
2015-11-09 17:41 770原文地址:http://blog.csdn ... -
Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
2015-10-30 18:01 1054原文地址:http://blog.csdn.net/mmllk ... -
过滤器和拦截器的区别
2015-10-30 18:00 660原文地址:http://blog.163.com/hzd_lo ... -
过滤器、监听器、拦截器的区别
2015-10-30 17:59 597原文地址:http://blog.csdn.net/x_yp/ ... -
【JSP】让HTML和JSP页面不缓存的方法
2015-10-14 10:16 487原文地址:http://blog.csdn.net/juebl ... -
jsp去掉浏览器缓存
2015-10-14 09:21 629原文地址:http://bbs.csdn.net/topics ... -
pageContext对象的用法
2015-09-04 21:24 709原文地址:http://blog.csdn.net/warcr ... -
log4j日志文件乱码问题的解决方法
2015-01-06 18:11 827原文地址:http://blog.csdn.net/inkfi ... -
JEECMS 系统权限设计
2014-09-05 16:25 946原文地址:http://chinajweb.iteye.com ... -
使用servlet保存用户上传的文件到本地
2014-08-12 14:46 634原文地址:http://blog.csdn.net/shuwe ... -
Servlet 实现文件的上传与下载
2014-08-12 14:44 890原文地址:http://www.2cto.com/kf/201 ... -
android文件上传到服务器
2014-08-12 11:03 397代码非原创,fix了bug,完善的还是需要再思量: /** * ... -
常用社交网络(SNS、人人网、新浪微博)动态新闻(feed、新鲜事、好友动态)系统浅析
2014-08-05 15:09 937原文地址:http://blog.csdn.net/sunme ... -
Feed系统架构资料收集
2014-08-05 15:08 624原文地址:http://blog.csdn ... -
微博feed系统推拉模式和时间分区拉模式架构探讨
2014-08-05 14:47 417原文地址:http://www.csdn.net/articl ... -
spring 出错,Could not find acceptable representation
2014-08-03 14:41 1531原文地址:http://www.myexception.cn/ ... -
spring @ResponseBody 返回json格式有关问题
2014-08-03 14:20 638原文地址:http://www.myexception.cn/ ... -
httpclient上传文件及传参数
2014-07-27 14:02 1197原文地址:http://hyacinth.blog.sohu. ... -
在eclipse中把java工程变为web工程
2014-06-27 11:18 711项目上点鼠标右键->properties->Pro ... -
配置Tomcat直接显示目录结构和文件列表
2014-06-10 13:52 733配置Tomcat直接显示目录结构和文件列表 TomcatSe ...
相关推荐
当我们谈论“自己动手写Tomcat”时,我们实际上是在探讨如何理解和实现一个小型的Web服务器,就像Apache Tomcat那样。Tomcat是一款开源的Java Servlet容器,它实现了Java EE(现在称为Jakarta EE)中的Servlet、JSP...
tomcat文章中的项目部署的示例war包,用于部署项目测试 tomcat文章中的项目部署的示例war包,用于部署项目测试 tomcat文章中的项目部署的示例war包,用于部署项目测试 tomcat文章中的项目部署的示例war包,用于部署...
Tomcat是Apache软件基金会下的一个开源项目,是一个广泛使用的Java Servlet容器,特别因为其轻量级、高效能和稳定性而闻名。它实现了Java Servlet和JavaServer Pages(JSP)规范,使得开发者能够用Java语言来编写...
Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,是一个开源的Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范。Tomcat7、Tomcat8和Tomcat9是不同版本的Tomcat,每个版本都有其特性和改进...
多个tomcat部署在一个服务器上的文档应用。自己查阅资料总结。
Tomcat 7.0是7.x系列的一个版本,提供了一些关键改进和新特性,旨在提高性能、稳定性和安全性。 在Tomcat 7.0中,以下几个核心知识点值得深入理解: 1. **Servlet 3.0支持**:Tomcat 7.0引入了对Servlet 3.0规范的...
Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持,并提供了作为 Web服务器的一些特有功能,如Tomcat管理...
tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat最新客户端tomcat...
Tomcat是一个开源的、免费的应用服务器,主要用于部署和运行Java Servlets和JavaServer Pages(JSP)。它遵循Java EE(现在称为Jakarta EE)规范中的Web应用部分,是Apache软件基金会的一部分。 【描述】提及的"该...
一个tomcat对应多个端口,将基本件与其他文件分开方便做升级,详细配置文档
- 对于第一个Tomcat实例(默认为8080端口),无需进行特殊配置,可以直接使用默认的环境变量。 - 对于第二个Tomcat实例(例如8090端口),需要修改`shutdown.bat`, `startup.bat`以及`catalina.bat`这三个文件。在...
Tomcat 7 和 Tomcat 8 是两个非常重要的版本,它们是Apache软件基金会开发的开源Java Servlet容器,主要用于运行Java Web应用程序。这两个版本都遵循Java EE(Enterprise Edition)规范,但各自具有不同的特点和改进...
如果你学过html,css,你会知道你写的页面只能自己访问,别人不能远程访问你写的页面,Tomcat就是提供能够让别人访问自己写的页面的一个程序. 运行Tomcat需要JDK的支持【Tomcat会通过JAVA_HOME找到所需要的JDK】。在...
这一步可以使用 `systemd` 单元文件来实现,创建一个名为 `tomcat1.service` 和 `tomcat2.service` 的文件,并在 `/etc/systemd/system/` 目录下放置: ```bash sudo nano /etc/systemd/system/tomcat1.service ```...
5. **Web应用程序目录结构**:一个标准的Tomcat部署通常包含多个Web应用程序,每个应用都有自己的目录结构,如WEB-INF目录下的web.xml文件,它是Web应用的部署描述符,定义了应用的配置信息。 6. **配置文件**:...
为了解决这些问题,开发者引入了Redis作为session存储的中间件,而Tomcat-Redis-Session-Manager就是这样一个将Tomcat与Redis结合的解决方案。 Tomcat-Redis-Session-Manager是一个开源项目,它允许Tomcat服务器将...
首先,我们来看Apache Tomcat 5.5.16,这是Tomcat 5.5系列的一个稳定版本。5.5版本是Tomcat发展历史上的一个重要里程碑,它引入了Servlet 2.4和JSP 2.0规范,提供了更好的性能和安全性。5.5.16作为该系列的更新,...
【描述】虽然描述部分为空,但我们可以推测博主pirate4444在文章中可能以一个简化的Tomcat实现为例,逐步解析其核心组件,如Catalina(核心处理引擎)、 Coyote(HTTP连接器)和 Jasper(JSP编译器)等。他可能还会...
标题中的“tomcat6”指的是Apache Tomcat 6,这是一个开源的应用服务器,主要用来部署和运行Java Servlet和JavaServer Pages(JSP)应用程序。在Java Web开发领域,Tomcat是应用最广泛的轻量级服务器之一,尤其对于...
我们将一个 jsp 格式的 webshell 用 WinRar 打包,然后将其后缀改名为 WAR,最后将其上传到服务器,可以看到在 Tomcat 的后台中多了一个名为/gslw 的目录,点击该目录打开该目录 jsp 木马就运行了,这样就获得了一个...