实现自己的控制层do-c (仿Struts2和SpringMVC)(七)

上篇博客中我们建立了一个注解类C和一个使用者类DemoC,还记得DemoC类中的helloString()方法吗?对,你们猜的不错,接下来我们要做的就是访问DemoChelloString方法。

在普通的Servlet中,要请求到服务端,服务端必需做一些Servlet让我们做的工作:编写Servlet子类并注册它。即使Spring/Struts这样的框架也得按套路出牌,因为它们都是对Servlet的封装。当然,我们也不例外。额外说一点的是,Spring在web.xml中注册的是Servlet,而Struts2在web.xml中注册的是Filter。我们采用Servlet方式。

我们新建一个Servlet,名为TransServlet,按照约定,它应该在包com.billy.jee.framework.servlet下,即它的全限定名是

com.billy.jee.framework.servlet.TransServlet

它的初始代码如下:

package com.billy.jee.framework.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TransServlet extends HttpServlet {
    /** */
    private static final long serialVersionUID = 8719005417117579209L;


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        System.out.print(System.currentTimeMillis());
    }

}

需要注意的是,我们并没有重写doGet()doPost()方法而是直接重写了service()方法,因为一个请求是先到达service()方法,处理后再分发到相应的方法如doGet()、doPost()、doPut()、doHead()、doTrace()等方法。 我们在service()方法里输出当前时间毫秒数,仅此而已。

接着我们就在把这个TransServlet注册到web.xml中,代码如下:

<servlet>
    <servlet-name>transServlet</servlet-name>
    <servlet-class>com.billy.jee.framework.servlet.TransServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>transServlet</servlet-name>
    <url-pattern>*.ts</url-pattern>
</servlet-mapping>

从配置中可以看到,我们注册了TransServlet并将它的servlet-name配置成transServlet,并将请求路径配置成*.ts。

配置完成之后,我们就要访问这个服务端应用了。我们可以使用tomcat或Resin或GlassFish来部署这个web工程,为方便测试与调试,我在此处选择了jetty。

要使用jetty,我们需要在pom.xml中做一些配置。请回顾一下博客四中的pom.xml文件,我们在dependencies节点下添加了两个依赖dependency(依赖可以理解成classpath下的jar包),即junit和servlet-api,这里我们添加jetty的依赖,如下(请确保如下代码在dependencies节点下):

    <dependency>
        <groupId>org.eclipse.jetty.aggregate</groupId>
        <artifactId>jetty-all-server</artifactId>
        <version>7.6.1.v20120215</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-jsp</artifactId>
        <version>7.6.1.v20120215</version>
    </dependency>

此处我们要添加一个JettyServerStart工具类,代码较长,如下:

package com.billy.jee.framework.util;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;

import javax.management.MBeanServer;

import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.webapp.WebAppContext;

public class JettyServerStart {
    private int           port;
    private String        context;
    private String        webappPath;
    private int           scanIntervalSeconds;
    private boolean       jmxEnabled;
    private Server        server;
    private WebAppContext webapp;

    public JettyServerStart(String webappPath, int port, String context) {
        this(webappPath, port, context, 0, false);
    }

    public JettyServerStart(String webappPath, int port, String context, int scanIntervalSeconds, boolean jmxEnabled) {
        this.webappPath = webappPath;
        this.port = port;
        this.context = context;
        this.scanIntervalSeconds = scanIntervalSeconds;
        this.jmxEnabled = jmxEnabled;
        validateConfig();
    }

    private void validateConfig() {
        if (port < 0 || port > 65536) {
            throw new IllegalArgumentException("Invalid port of web server: " + port);
        }
        if (context == null) {
            throw new IllegalStateException("Invalid context of web server: " + context);
        }
        if (webappPath == null) {
            throw new IllegalStateException("Invalid context of web server: " + webappPath);
        }
    }

    public void start() {
        if (server == null || server.isStopped()) {
            try {
                doStart();
            } catch (Throwable e) {
                e.printStackTrace();
                System.err.println("System.exit() ......");
                System.exit(1);
            }
        } else {
            throw new RuntimeException("Jetty Server already started.");
        }
    }

    private void doStart() throws Throwable {
        if (!portAvailable(port)) {
            throw new IllegalStateException("port: " + port + " already in use!");
        }

        System.setProperty("org.eclipse.jetty.util.URI.charset", "UTF-8");
        System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.Slf4jLog");
        System.setProperty("org.eclipse.jetty.server.Request.maxFormContentSize", "20000000");

        server = new Server(port);
        server.setHandler(getHandler());

        if (jmxEnabled) {
            MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
            MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
            server.addBean(mBeanContainer);
        }

        if (scanIntervalSeconds > 0) {
            startFileWatchScanner();
        }

        long ts = System.currentTimeMillis();
        server.start();

        ts = System.currentTimeMillis() - ts;
        System.err.println("Jetty Server started: " + String.format("%.2f sec", ts / 1000d));

        server.join();
    }

    protected Handler getHandler(){
        webapp = new WebAppContext(webappPath, context);
        return webapp;
    }

    private void startFileWatchScanner() throws Exception {
        List<File> scanList = new ArrayList<File>();
        scanList.add(new File(webappPath, "WEB-INF"));

        Scanner scanner = new Scanner();
        scanner.setReportExistingFilesOnStartup(false);
        scanner.setScanInterval(scanIntervalSeconds);
        scanner.setScanDirs(scanList);
        scanner.addListener(new Scanner.BulkListener() {

            @SuppressWarnings("rawtypes")
            public void filesChanged(List changes) {
                try {
                    System.err.println("Loading changes ......");
                    webapp.stop();
                    webapp.start();
                    System.err.println("Loading complete.\n");
                } catch (Exception e) {
                    System.err.println("Error reconfiguring/restarting webapp after change in watched files");
                    e.printStackTrace();
                }
            }
        });
        System.err.println("Starting scanner at interval of " + scanIntervalSeconds + " seconds.");
        scanner.start();
    }

    private static boolean portAvailable(int port) {
        if (port <= 0) {
            throw new IllegalArgumentException("Invalid start port: " + port);
        }

        ServerSocket ss = null;
        DatagramSocket ds = null;
        try {
            ss = new ServerSocket(port);
            ss.setReuseAddress(true);
            ds = new DatagramSocket(port);
            ds.setReuseAddress(true);
            return true;
        } catch (IOException e) {
        } finally {
            if (ds != null) {
                ds.close();
            }
            if (ss != null) try {
                ss.close();
            } catch (IOException e) {
            }
        }
        return false;
    }

    public static void main(String[] args) {
        String webapp = "D:/haocheng/workspace/com.cheng.spring.mvc.test/src/main/webapp";
        new JettyServerStart(webapp, 8080, "/").start();
    }
}

工具类有了,接下来就是要调用工具类来让我们使用,与JettyServerStart相比,JettyStarterTest就很精简了。代码如下(请注意包名,该类是测试类,在src/test/java目录下,不在src/main/java下):

package test.billy.jee.framework.util.JettyServerStart;

import com.billy.jee.framework.util.JettyServerStart;

public class JettyStarterTest {

    public static void main(String[] args) {
        String webapp = "src/main/webapp";
        int port = 2016;
        new JettyServerStart(webapp, port, "/webby").start();
    }
}

对!你没有看错,这就是个java程序,右键Run As Java Application就能启动该类,这时候在地址栏里输入http://127.0.0.1:2016/webby即可访问到该项目。

需要注意的是,若你使用Eclipse或MyEclipse作为ide的话,上面的启动类的代码不用改变,但当你使用idea开发的话,请将webapp变量赋值为"项目名/src/main/webapp"即可。

右键项目Run As Maven install即可将项目安装到本地仓库,接着执行JettyStarterTest类启动服务,然后在地址栏项目名的基础上随便输入一个地址如http://127.0.0.1:2016/webby/aaaa.ts,可以看到控制台打印出了系统当前时间毫秒数。也说明aaaa.ts是能请求到TransServlet的service()方法中的。

接着我们就要在TransServlet中进行调用DemoC的helloString()方法了。

我们将打印语句注释掉,并在其下添加如下代码:

DemoC demoC = new DemoC();
demoC.helloString("这是DemoC");

重新启动服务,我们同样访问http://127.0.0.1:2016/webby/aaaa.ts,看到后台的输出了吗?

param hello: 这是DemoC

我们确实调用了DemoC这个类的helloString()方法了。可以也遗留了几个问题:

这两个问题其实也是一个问题,我们最终想要的结果可能是——

我在地址栏输出http://127.0.0.1:2016/webby/demo/helloString.ts?hello=这是DemoC吗,系统应该能定位到DemoC类的helloString()方法,并将参数hello传入。

这一个问题,或称两个问题我们下篇博客中会给出解决方案。

转载于:https://my.oschina.net/valuetodays/blog/714171

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值