模拟请求和响应

模拟请求和响应

需求:

假设用户会在浏览器中输入某些地址:比如: http:///abc.html 、 http:///def.html
根据请求地址的不同,进行不同的响应:(即显示对应的页面内容: 默认输出结果)。

思路1:

在代码中根据地址的不同 用 if 判断,然后 执行不同的逻辑

if(“abc.html”.equals(url)){
//返回abc结果
}else if(“def.html”.equal(url)){
//返回def结果
}

思路不好,不利于程序的扩展。当改变映射规则时,需要重新编写Java代码。

思路2:

想避免固化的逻辑,应该将映射规则配置在外部的文件中。

  1. url地址 --> 映射某个程序的功能
  2. 用properties文件或 XML 文件都可以来描述

下面用 XML 格式 实现。

格式一:

<mapping>
	<url>abc.html</url>
    <function>com.xxx.Mxx.method</function>
</mapping>
<mapping>
	<url>def.html</url>
    <function>com.xxx.Mxx.method</function>
</mapping>

格式二:

<servlet>
	<servlet-name>demo</servlet-name>
    <servlet-class>com.xxx.Mxx</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>demo</servlet-name>
    <url-pattern>abc.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>demo</servlet-name>
    <url-pattern>def.html</url-pattern>
</servlet-mapping>

定义接口(叫它Servlet)实现 类的功能

功能1:初始化方法 void init();
功能2:用户请求过来以后,工作的内容 void service();
功能3:销毁方法 void destroy();

后续的开发工作是:

要想定义一个服务器端的行为,就创建一个类,实现Serlvet接口。然后实现它中定义的方法。

想要跟某个URL地址对应,修改xml配置文件即可。

代码演示:

配置xml

<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://www.example.org/web-app_2_5"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd" version="1">

    <servlet>
        <servlet-name>abc</servlet-name>
        <servlet-class>com.example.web.AbcServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>abc</servlet-name>
        <url-pattern>/abc.html</url-pattern>
    </servlet-mapping>


    <servlet>
        <servlet-name>def</servlet-name>
        <servlet-class>com.example.web.DefServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>def</servlet-name>
        <url-pattern>/def.html</url-pattern>
    </servlet-mapping>

定义一个接口实现三个方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Demo类做一个 请求和响应的 模拟

  1. 启动

解析web.xml文件
将结果存放在 Map 中
思考:
key: String url地址
value: // String 包名+类名
// Servlet的实例对象
Servlet中的init初始化方法怎么调用呢?
方法执行以来与对象。

  1. 等待用户服务

读取用户的url地址
判断系统中是否能处理(看一下字典中是否包含对应的key),
如果可以,则调用map中value的service方法。
如果不可以,返回404错误。

  1. 退出系统

假设用户输入的是bye,执行退出逻辑。
遍历map中的所有servlet实例,调用它们的destroy方法。

public class Demo {
    private static Map<String,Servlet> mappings = new HashMap<>();

    private static Map<String,String> servlets = new HashMap<>();
    private static Map<String,String> servlet_mappings=new HashMap<>();

    public static void main(String[] args) {
        start();
        work();
    }

    public static void start() {
        //加载web.xml
        URL resource = Demo.class.getResource("web.xml");
        SAXReader reader = new SAXReader();
        try {
            Document read = reader.read(resource);
            //得到根元素
            Element rootElement = read.getRootElement();

            Iterator iterator = rootElement.elementIterator();
            while(iterator.hasNext()){
                Element next = (Element) iterator.next();
                if("servlet".equals(next.getName())){
                    String sname = next.element("servlet-name").getTextTrim();
                    String sclass = next.element("servlet-class").getTextTrim();
                    servlets.put(sname, sclass);
                }else if("servlet-mapping".equals(next.getName())){
                    String sname = next.element("servlet-name").getTextTrim();
                    String url=next.element("url-pattern").getTextTrim();
                    servlet_mappings.put(sname, url);
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        //解析完成,进入初始化的流程
        for(Map.Entry<String, String> entry: servlet_mappings.entrySet()){
            String sname = entry.getKey();
            String sClass = servlets.get(sname);
            String url = entry.getValue();
            //创建class的对象
            try {
                Class<Servlet> aClass = (Class<Servlet>) Class.forName(sClass);
                Servlet servlet = aClass.newInstance();
                servlet.init();//进行初始化
                mappings.put(url, servlet);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }

    public static void work() {

        while(true){
            //等待输入
            System.out.println("请输入要访问的地址:");
            Scanner scanner = new Scanner(System.in);
            String url = scanner.next();
            if("bye".equalsIgnoreCase(url)){
                stop();
                System.exit(0);
//                break;
            }

            Servlet servlet = mappings.get(url);
            if(servlet==null){
                System.out.println("404错误!");
                continue;
            }

            servlet.service();//进行响应。
        }
    }

    public static void stop() {
        for(Map.Entry<String,Servlet> entry:mappings.entrySet()){
            Servlet value = entry.getValue();
            value.destroy();//销毁逻辑
        }
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值