分类 Java Web 下的文章

《Head First Java》知识点整理

这本书看过有一段时间了,因为一直做PHP方向,没有去深入使用Java,所以现在对Java的了解维持在一个能读懂Java语法的程度。毕竟很多书都是拿Java作为代码的主要语言的。但是现在可能去做一些Java相关的开发了,所以把这本书重新温习一下是非常有必要的。


第一章:基本概念
主要介绍了Java的代码是什么样的和控制语句,因为这本书是Head First嘛,所以这方面讲的比较粗略。
第二章:类与对象
众所周知,Java里面只有类和对象(但是不代表一定用了对象的方式去思考)。这一章开始介绍类和对象相关的知识。
第三章:primitive主数据类型和引用
和其他语言类似,Java里面还是没有把基本数据类型直接包装成类,依旧分成了了primitive主数据类型和引用。然后,这一章还讲到了Java数组方面的知识。
第四章:方法操作实例变量
这一章讲到了对象的属性和方法,可以了解一下,还提到了一下变量的比较(==和equals())。
第五章:编写程序
凭借上面几章学习的基本知识,我们可以开始编写程序了。当然,没有泛型&继承&异常,更没有网络&GUI&持久化,我们能写的程序会功能非常简单。但是,这确实是一个完整的Java程序,而且开发流程值得初学者借鉴。


第六章:认识Java的API
本章给我们带来了增强版的程序,用到了Java的类库中一个名为ArrayList的数据结构。然后,自然而然引申到了Java API库的简单介绍。

java.util.ArrayList
取代数组的数据结构,具有非常好的扩展性。

第七章:继承和多态
现在我们需要面对的是面向对象的三大特性之二,剩下的一个在第二章已经讲过了。继承是为了复用产生的特性,多态是继承和接口自然而然引申出来的特性。
第八章:接口和抽象类
因为继承的设计到现在还没有一个统一的答案,Java使用的是单继承多接口的设计思路。抽象类不能实例化,只能用来被继承;接口类似于抽象类。两者区别是抽象类是用来extends(只有一个),接口被用来implements(可以多个);接口里面所有方法都没有实体,抽象类部分方法没有实体。
第九章:构造器和垃圾收集器
构造器算是面向对象的基本配置了。然后我们来看对象什么时候被回收,这边介绍了一种最简单的GC方式:被引用次数为零。
第十章:数字和静态
因为Java都是对象,但是我们会经常需要函数而不是对象,怎么办?只有用对象构筑函数集合,那就是静态方法,除此以外还有静态变量。

java.lang.Math
关于数学的静态函数集合。
java.lang.Interger(Boolean, Character, Byte, Short, Long, Float, Double)
primitive主函数类型的包装库。
java.lang.String
String.format()静态方法可以将数字进行格式化。
java.util.Calendar(Date)
使用Calendar来从操作时间。

第十一章:异常处理
什么情况下使用异常?大多数的书籍对这一点含糊其词。这边主要介绍了Java的异常的语法,还用了一个例子来说明该如何使用。


第十二章 图形用户接口
如何使用Java来构建图形界面程序,然后因为用到了内部类,所以也提及了一下。

javax.swing.*
java.awt.event.*
java.awt.*

第十三章 swing
学习如何使用swing组件来进行布局,以及介绍了swing的几个常用组件。
第十四章 序列化和文件的输入/输出
介绍了Java的序列化反序列化和文件的输入输出相关的内容。

java.io.*

第十五章 网络和线程
主要介绍了Socket连接在客户端和服务端的使用,然后在客户端引申出线程,然后引申出对象锁的概念。

java.net.*
java.lang.thread

第十六章 集合和泛型
主要介绍了多种集合数据类型,不过这边引申了泛型的概念。不过总觉得泛型作为Java非常重要的一部分,放到这边来讲不太好。

java.util.Collections
java.util.HashSet
java.util.TreeSet
java.util.HashMap
java.util.LinkedList
java.util.LinkedHashMap


第十七章 包、jar存档文件和部署
第十八章 远程部署的RMI

Java Servlet&JSP Web开发

最近几周读了《Head First Servlets&JSP》一书,有一些想法,所以想记录下来。
因为自己主要擅长PHP开发,所以会与PHP做对比。

其实Servlet的doPost和doGet等方法非常符合REST这种设计理念,这点不得不佩服Servlet当初的设计者。
Servlet应该叫做应用控制器(application controller),因此没有前端控制器(front controller)。
对比PHP,PHP在非框架开发也是通过应用控制器这种模式进行开发的,与Servlet颇为类似。
但是与PHP不同的是,PHP根本没有REST思想,想怎么命名应用控制器都可以。
Servlet如果设计得当,就会得到符合REST风格的应用控制器。
但是可能性比较小,估计至少90%的项目都和PHP差不多,命名乱成一团。

然后再来看路由,相比于非框架的PHP,访问的地址就是文件名,Servlet的路由和现代框架风格比较相似。
Servlet用了路由来决定URL地址对应的Servlet,在当时确实是一种很现代的思想。
路由只是Servlet配置的一部分,除了路由以外,Servlet的还有很多配置项也都是配置在web.xml文件里面的。
因为毕竟编译语言,写在xml文件里面就免除了重新编译的麻烦。
书中还介绍了一种使用配置文件的数据生成全局对象的方法,但是这种方法产生的对象因为多线程共享,所以可能会有线程安全问题,值得注意。

再来说一下Servlet的官方视图JSP。请牢记,JSP就是一个Servlet,它会执行时编译成Servlet。
本质上来说Servlet采用的这种JSP的方式是这样的:
本来Servlet有一个函数比如叫做render(HttpServletReqeust req, HttpServletResponse res){}。
这个函数里面写了各种out.println("")之类的输出语句,用来构成一个网页。
但是大家有没有发现,这个render函数无法被多个Servlet重用,那么为了视图的重用,怎么办呢?
于是这个函数就被分离出来,形成一个单独的视图Servlet,这个函数内有一个函数类似render函数。
然后控制器Servlet在执行完了之后会把数据添加到req的属性中去,并把req和res传递给视图Servlet。
视图Servlet收到req和res后,就会从req获取数据渲染并传递给res,就是我们看到的网页。
但是视图Servlet写起来太麻烦了,写一个网页相比单纯的HTML要花费太多功夫,怎么办呢?
jSP的设计中想到的方法很简单,那就是先写HTML风格的页面脚本,然后把这个页面脚本编译成Servlet。
一次请求Servlet的处理过程是这样的:
系统会根据你的请求的URL通过路由找到对应的控制器Servlet;
控制器Servlet处理完成后,会把数据设置为Request的属性,然后把请求转发给视图Servlet;
如果视图Servlet没有找到,只有JSP文件,那么就会把JSP编译成视图Servlet;
视图Servlet会根据请求信息和控制器保存的属性信息渲染页面,形成我们看到的网页。

除此以外,Servlet还有一个非常特殊的特性叫做监听器,它会监听系统中的多种事件,满足我们在事件前后执行的需求。
当然,监听器用的比较少,不过有机会还是会用得上的。

《Head First Servlets & JSP》笔记

第一章:
P17 content-type(内容类型)响应首部的值成为MIME类型。
P21 端口是一个16位数,标识服务器硬件上一个特定的软件程序。TCP端口只是一个数字而已。

第二章:
P37 Servlet也需要帮助。请求到来时,必须有人实例化servlet,或者至少要建一个新的线程处理这个请求,必须有人调用Servlet的doPost()或doGet()方法。
P41 容器提供的功能:通信支持、生命周期管理、多线程支持、声明方式实现安全、JSP支持。
P44 在Servlet从容器中得到的响应对象中,可以拿到一个PrintWriter。使用这个PrintWriter能够将HTML文本输出到响应对象。
P49 除了把URL映射到实际的Servlet,还可以使用部署描述文件对Web应用的其他方面进行定制,包括安全角色、错误页面、标记库、初始配置信息等。
P49 实际上,容器使用了一组很复杂的规则来寻找匹配的servlet,它会根据客户请求提供的URL查找位于服务器某个位置的一个具体Java类。
P65 一个完全兼容的J2EE应用服务器必须有一个Web容器和一个EJB容器(以及其他一些部件,包括JNDI和JMS实现)。Tomcat是一个Web容器,而不是完整的J2EE应用服务器,因为Tomcat没有EJB容器。

第三章:
P80 要记住,最后servlet要从请求接受一个参数,在模型上调用一个方法,把信息保存在JSP能找到的一个位置上,再把请求转发给JSP。
P86 servlet把请求转发给JSP。然后,JSP从请求对象得到数据。
P88 容器提供了一种称为“请求分派”的机制 ,允许容器管理的一个组件调用另一个组件。
P89 RequestDispatcher view = request.getReqeustDispatcher("result.jsp");view.forward(request, response);

第四章:
P95 容器根据请求中的URL查找正确的servlet,为这个请求创建或分配一个线程,并调用servlet的service()方法(确定调用哪个Servlet方法)。
P96 service()方法结束,所以线程要么撤销,要么返回到容器管理的一个线程池。
P97 你可能听过别人这么说,“servlet的每个实例……”。但这种说法是错误的。任何servlet类都不会有多个实例,只有一种特殊情况除外。
P104 每个Servlet都有一个ServletConfig对象,每个Web应用有一个ServletContext对象。
P108 对,除了GET和POST之外,确实还有其他一些HTTP 1.1方法,包括HEAD、TRACE、OPTIONS、PUT、DELETE和CONNECT。
P118 如果没有在表单中之处method="POST",就会默认为HTTP GET请求。
P119 单个参数可以有多个值!这说明需要一个返回数组的getParameterValues(), 而不是返回String的getParameter()。
P123 还有可能创建一个servlet来处理计算机驱动的请求,其中请求体包含要处理的文本或二进制内容。
P123 既然客户对服务器是远程的,所以getRemotePort()是指“得到客户的端口“。getLocalPort()和getServerPort()的差别很微妙,getServerPort() 是”请求原来发送到哪个端口“,getLocalPort()是指”请求最后发送到哪个端口“。
P126 使用响应对象向客服发回数据会对响应调用两个方法:setContentType()和getWriter(),在此之后,只需要完成I/O将HTML写至流。
P132 不过ServletResponse接口只提供了两个流可供选择: ServletOutputStream用于输出字节,PrintWriter用于输出字符数据。
P132 PrintWriter实际上”包装“了ServletOutputStream,也就是说,PrintWriter有ServletOutputStream的一个引用,而且会把调用委托给ServletOutputStream。
P133 setHeader()会覆盖现有的值;addHeader()会增加另外一个值。

P157 上下文初始化参数与servlet初始化参数很类似,只不过上下文参数对整个Web应用可用,而不是针对一个servlet。
P165 她想监听一个上下文初始化事件,这样就能得到上下文初始化参数,并在应用为客户提供服务之前运行一些代码。

P236 禁用cookie的用户会忽略"Set-Cookie"响应首部。
P238 此时,容器并不知道cookie是否工作,所以向客户返回第一个响应时,它会同时尝试cookie和URL重写这两种做法。
P239 根本就不能对静态页面完成URL重写!使用URL重写只有一种可能,这就是作为会话一部分的所有页面都是动态生成的!
P253 但是不存在setCookie()方法。只有一个addCookie()方法!