【Tomcat与网络1】史前时代—没有Spring该如何写Web服务

在前面我们介绍了网络与Java相关的问题, 最近在调研的时候发现这块内容其实非常复杂,涉及的内容多而且零碎,想短时间梳理出整个体系是不太可能的,所以我们还是继续看Tomcat的问题,后面有网络的内容继续补充吧。

目录

1 搭建一个本地web服务

2 Java web是如何工作的


Servlet是Java Web的核心机制,而实现Servlet最好的服务器无疑就是Tomcat。在前面我们介绍了如何用Java实现网络通信,这个与自己实现一个Servlet服务器,比如Tomcat 还差多少呢?差十万八千里,有一个挺好玩的图:

目前各类Spring的材料实在太多了,我们用的也多。那么Spring到底是什么?又有什么用呢?我们可以找到一堆的标准答案,但是貌似对Spring的理解总是感觉没有学透,那么Spring的作用到底体现在哪里呢?要理解这个问题,我们需要先看一下没有Spring的世界是什么样的,然后再看看有了Spring之后是什么样子的,这样自然理解更加透彻。

史前时代

假如没有Spring框架,要开发一个java web程序该怎么做呢?很多人马上想到了Java web里的Servlet、JSP以及Tomcat这些技术,是的,这是用Java做web应用基础技术。接触Java 有些年头了,相信很多人已经忘记了怎么创建一个不使用构建工具和任何Java Web框架的原始JavaWeb。本节我们看一下如何搭建一个没有高级框架的web应用。这个工作使用idea还挺麻烦,我们记录一下:

1 搭建一个本地web服务

1.打开idea,选择file->New->Project

2.点击Java,点击下一步.

3.修改项目名

这里根据你的计划,设置到一个相对稳定的目录即可。为了防止异常问题,建立路径里不要有空格或者中文字符。

4.右键项目,选择add framework support

5.完成之后,项目结构变成了这样,然后我们在WEB-INF下创建classes和lib文件夹,如下所示:

6.接下来,编辑项目结构, 将output path的路径改成classes文件夹的路径,如下所示:

7.点击dependencies,选择加号,选择jars or directories, 点击后,他会弹出一个文件选择框,这里选择lib文件所在位置,如图所示:

然后此时单击西方的“+”号,会出现中间位置的弹窗,单击之后会在中间位置出现一个小窗口:

这里将web-INF下的lib目录添加进来。此时还会出现一个弹窗,就是询问这个lib是干什么的,这就是我们后面会手动添加的lib:

之后选中退出即可,效果如下:

接下来要配置tomcat,我们使用的是8.5。这个需要先下载到本地,然后执行一下看看是否正常。之后再在idea中配置。

单击idea的“Run”,然后选择“edit setting”,进入下面的界面:

此时我们要首先选择左上方的“+”,在列表中找到“tomcat server”(注意不要和TomEE server混了)。

然后配置右侧的相关内容。这里图中标记处默认的端口号是8080,但是8080经常会和其他服务冲突,因此这里改成了9091。

这里还要注意deployment下的这个配置:

保持与全面访问路径一致。

最后我们打开index.jsp页面,增加如下内容:

<html>
  <head>
    <title>Hello world</title>
  </head>
  <body>
Hello world
  </body>
</html>

之后启动tomcat,在浏览器输入:http://localhost:9091/webtest/就可以看到一个“Hello world"的信息。

2 Java web是如何工作的

有了上面的环境之后,那如何实现展示的内容与后台Java交互呢?我们知道有两种常用的技术,一种是JSP,一个是直接写Servlet。JSP其实就是在静态页面里嵌入Java代码,而Servlet则是在Java代码里嵌入静态代码,例如常见的JSP页面一般是这样的:

<%@ page import="com.lqc.pojo.Person" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
    <%
        Person person = new Person();
        person.setName("哥好帅!");
        person.setPhones(new String[]{"11111111111","13333333333","13666666666"});

        List<String> cities = new ArrayList<String>();
        cities.add("北京");
        cities.add("上海");
        person.setCities(cities);

        Map<String,Object>map = new HashMap<>();
        map.put("key1","value1");
        map.put("key2","value2");
        person.setMap(map);

        pageContext.setAttribute("p", person);
    %>

    输出Person:${ p }<br/>
    输出Person的name属性:${p.name} <br>
    输出Person的pnones数组属性值:${p.phones[2]} <br>
</body>
</html>

而典型的Servlet代码是这样的:

public class HelloServlet extends HttpServlet {

   public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应内容类型
        response.setContentType("text/html");

        // 实际的逻辑是在这里
        PrintWriter out = response.getWriter();
        out.println("<h1> servlet Hello World  </h1>");
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    public void destroy() {
        // ....
    }
}

此时还要在web.xml中增加相关的配置信息:

 <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.lqc.webtest.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>

这时候,然后重启tomat,输入地址http://localhost:9091/webtest/helloServlet,就可以看到页面展示了“servlet Hello World”。

上面的代码不管是在JSP中嵌套Java代码,还是在Servlet中嵌套静态代码,如果到工程里这么干,肯定都是灾难,虽然可以使用EL等优化,但是对于变成来说仍然非常不友好。典型的情况有:

1.前端必须会后台的技术,后台也必须会前端的技术,不利用不同技术栈的人相互合作。

2.即使懂相关技术非常容易错,即使错了也无法很好的定位。

3.很难扩展和维护。

为了解决这个问题 ,必须要实现前后端代码的分离,该如何分离呢?其实思路非常简单,我们上面输入的请求地址即使不用浏览器也能请求的,例如可以使用curl命令:

这里同样返回了结果“<h1> servlet Hello World </h1>”。既然这样,那我前端工程只要能发送和接收http请求就可以了?入参和出参可以双方协定, 只要规则一致就可以正确相互解析了?其实前后端分离,或者动静分离,都是这个原理。之后前端和后端就分道扬镳了,前端有VUE等框架,而后台则更多。

动静分离之后就没问题了吗?当然不是,后台要干的事情其实非常多,要处理用户请求,要执行很多业务处理、要负责数据库管理等等,还是太多了,那怎么办呢?这时候MVC模式就开始大量应用了,Java中最为典型的就是Struts2和SpringMVC,这个曾经被使用了很多年,估计现在很多公司的老项目还有其身影,使用MVC框架的的好处有:

  1. 允许更改视图层代码而不用重新编译模型和控制器代码;
  2. 允许使用各种不同样式的视图来访问同一个服务器端的代码;
  3. 使降低开发和维护用户接口的技术含量成为可能;
  4. 使开发时间得到相当大的缩减等。

与此同时,为了处理数据库管理的麻烦,就诞生了专门的框架,这就是持久化框架(ORM),最为典型的就是Hibernate、Mybatis和SpringJDBC Tempalte。由于Hibernate封装过度,导致框架过重,很多优化等不方便,所以逐步被Mybatis等取代。

有了MVC框架和ORM框架,就够了吗?还不是,问题还有很多,其中最典型的问题是其配置问题,例如你要在Struts.xml中配置每个对象和实现类的映射关系,例如:

<!--配置package,必须继承Struts-default-->
<struts>
  <package name="struts2" extends="struts-default">
  <!--配置按action,名字hello是访问URL使用的:hello.action-->

    <action name="hello" class="org.yangjq.HelloAction">
    <result name="success">/success.jsp</result>
    <result name="error">/error.jsp</result>
    </action>
  </package>
</struts>

Spring是如何管理用户的类的,这是一个很常见的面试题。其实管理的就是类似上面的Struts.xml里的配置,随着Spring的不断完善,衍生出来的功能越来越多,功能越来越强,甚至很多人“只知Spring,不知Java Web”。

不过呢,Spring管理我们的类也需要一大堆的配置文件,这个过程仍然是非常痛苦,所以后面就逐步有了SpringBoot,SpringBoot使用自动装载等机制帮助我们省去了大量而繁琐的配置问题,很多时候我们只要加一个注解或者包扫描就可以使用了,这个我们后面再说。

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵横千里,捭阖四方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值