在前面我们介绍了网络与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.打开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页面,增加如下内容:
Hello world
Hello world
之后启动tomcat,在浏览器输入:http://localhost:9091/webtest/就可以看到一个“Hello world"的信息。
有了上面的环境之后,那如何实现展示的内容与后台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" %>
<%
Person person = new Person();
person.setName("哥好帅!");
person.setPhones(new String[]{"11111111111","13333333333","13666666666"});
List cities = new ArrayList();
cities.add("北京");
cities.add("上海");
person.setCities(cities);
Mapmap = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
person.setMap(map);
pageContext.setAttribute("p", person);
%>
输出Person:${ p }
输出Person的name属性:${p.name}
输出Person的pnones数组属性值:${p.phones[2]}
而典型的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(" servlet Hello World
");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
public void destroy() {
// ....
}
}
此时还要在web.xml中增加相关的配置信息:
helloServlet
com.lqc.webtest.HelloServlet
helloServlet
/helloServlet
这时候,然后重启tomat,输入地址http://localhost:9091/webtest/helloServlet,就可以看到页面展示了“servlet Hello World”。
上面的代码不管是在JSP中嵌套Java代码,还是在Servlet中嵌套静态代码,如果到工程里这么干,肯定都是灾难,虽然可以使用EL等优化,但是对于变成来说仍然非常不友好。典型的情况有:
1.前端必须会后台的技术,后台也必须会前端的技术,不利用不同技术栈的人相互合作。
2.即使懂相关技术非常容易错,即使错了也无法很好的定位。
3.很难扩展和维护。
为了解决这个问题 ,必须要实现前后端代码的分离,该如何分离呢?其实思路非常简单,我们上面输入的请求地址即使不用浏览器也能请求的,例如可以使用curl命令:
这里同样返回了结果“
动静分离之后就没问题了吗?当然不是,后台要干的事情其实非常多,要处理用户请求,要执行很多业务处理、要负责数据库管理等等,还是太多了,那怎么办呢?这时候MVC模式就开始大量应用了,Java中最为典型的就是Struts2和SpringMVC,这个曾经被使用了很多年,估计现在很多公司的老项目还有其身影,使用MVC框架的的好处有:
与此同时,为了处理数据库管理的麻烦,就诞生了专门的框架,这就是持久化框架(ORM),最为典型的就是Hibernate、Mybatis和SpringJDBC Tempalte。由于Hibernate封装过度,导致框架过重,很多优化等不方便,所以逐步被Mybatis等取代。
有了MVC框架和ORM框架,就够了吗?还不是,问题还有很多,其中最典型的问题是其配置问题,例如你要在Struts.xml中配置每个对象和实现类的映射关系,例如:
/success.jsp
/error.jsp
Spring是如何管理用户的类的,这是一个很常见的面试题。其实管理的就是类似上面的Struts.xml里的配置,随着Spring的不断完善,衍生出来的功能越来越多,功能越来越强,甚至很多人“只知Spring,不知Java Web”。
不过呢,Spring管理我们的类也需要一大堆的配置文件,这个过程仍然是非常痛苦,所以后面就逐步有了SpringBoot,SpringBoot使用自动装载等机制帮助我们省去了大量而繁琐的配置问题,很多时候我们只要加一个注解或者包扫描就可以使用了,这个我们后面再说。