J2EE包含13种核心技术规范:
(1)Java Database Connectivity (JDBC)以一种统一的方式来对各种各样的数据库进行存取
(2)Java Naming and Directory Interface (JNDI)用于名字和目录服务,它提供了一致的模型来存取和操作企业级的资源如DNS和LDAP,本地文件系统等
(3)Enterprise Java Beans (EJB) 提供了一个框架来开发和实施分布式商务逻辑,显著地简化了具有可伸缩性和高度复杂的企业级应用的开发
(4)JavaServer Pages (JSPs) 用以创建动态网页
(5)Java servlets提供的功能大多与JSP类似,不过实现的方式不同
(6)Remote Method Invocation (RMI) 在远程对象上调用一些方法,使用了连续序列方式在客户端和服务器端传递数据
(7)Interface Description Language (IDL)将Java和CORBA集成在一起
(8)Java Transaction Architecture (JTA)可以存取各种事务
(9)Java Transaction Service (JTS) 规定了事务管理器的实现方式
(10)JavaMail 用于存取邮件服务器的API,它提供了一套邮件服务器的抽象类
(11)JavaBeans Activation Framework(JAF) JavaMmail利用JAF来处理MIME-编码的邮件附件,MIME的字节流可以被转换成JAVA对象,或者转换自JAVA对象
(12)Java Messaging Service (JMS) 是用于和面向消息的中间件相互通信的应用程序接口(API)(13)Extensible Markup Language (XML)XML是一种可以用来定义其它标记语言的语言
个人学习笔记,看不懂很正常
2019/9/16
- Filter(预处理/后处理)
doFilter(ServletRequest, ServletResponese, FilterChain){
// 本过滤器中预处理逻辑
...
// 通过过滤链 向下一个过滤器传递
chain.doFilter(Request, Response);
// 本过滤器中后处理逻辑
...
}
- Servlet
- 使用GET 和 POST 传递数据有什么不同?
- 如何解决乱码问题?
request.setChracterEncoding("UTF-8");
- 如何读 Servlet 中的参数?
getInitParameter(Key); // 方案1
request.getParameter(Key); // 方案2
// 方案3 通过设置 <servlet-mapping> url 地址导至某个组件
- 构建过滤器链
Mapping
节点中设置多个Filter
,以其设置顺序构成chain
;可加servlet-name
拦截特定servlet
的请求
2019/9/19
- 将该应用程序的路径转换为系统下的绝对路径:
getServletContext().getRealPath(String path)
- 将磁盘中数据缓存在内存中,利用
ByteArrayOutputStream
,读取流链接FileInputStream->BufferedInputStream
...
int r = 0;
while((r = br.read(buffer) != -1)){
baos.write(buffer, 0, r);
}
buffer = baos.toArrayList();
return new ByteArrayInputStream(buffer);
- 读取网站资源
getServletContext().getResoureAsStream(String path)
- 存取资源进全局以供不同用户多个请求
getServletContext().setAttribute(Key, Value)
- 存取资源以供同一用户多个请求
...
HttpSession session = request.getSession();
session.setAttribute(Key, Value);
displayList = result.subList(start, end);
Listener
<Listener>
<Listener-class>CLASSNAME</Listener-class>
</Listener>
// ServletContextListener
contextInitialized(ServletContextEvent);
contextDestroyed(ServletContextEvent);
- JSP - Java Servlet Page
<%@ page import="java.until.*, java.io.*"
pageEncoding = "utf-8"
session = "true"
errorPage = "/error.jsp"
buffer = "none" // 禁用输出缓冲空间
isErrorPage = "true"
include file = "copyright.html" // 复制文件的内容到网页里,静态包含,发生在转换为java文件的过程中,只能包含文本文件
%>
// 上述如果出现异常,将重新定向导向 error.jsp
// jsp implicit objesct : request, response, config, application, session, out(会抛出异常), excepetion(只有错误处理页面才有), pageContext, this
<%
Java statement
%>
2019/9/23
- Adapter 类一般不封装逻辑,只是进行了接口转换,参数转换功能(适配器模式)
- Fascade 类隐藏系统细节,转发函数请求,只包含需要的函数(蒙面模式)
- 请求转发
<%
pageContext("b.jsp");
%>
- 动态包含资源
<jsp: include page = "a.html"/> // 运行过程中包含,将请求交由另外的组件,html做处理等
<% = 5 + 6 %> // jsp表达式,等同于java.out输出
- 声明
<%-- --%> // jsp注释
<%! private int i = 0; %> // 可声明函数,变量
- useBean
<jsp:useBean id = "a" class = "com.abc.Student" scope = "page|request|session|application"/> // scope 是看看在哪个对象的Attribute里面有这个属性
<jsp:getProperty name = "a" property = "age">
<jsp:setProperty name = "a" propertuy = "age" value = "20">
<jsp:setProperty name = "a" propertuy = "age" param = "age"> // 将表单中age参数的数据赋值给 Property 中的数据
<jsp:setProperty name = "a" propertuy = "*" > // 将网页中表单的数据完全同 Property 中的数据名进行匹配,然后进行赋值
- 动态数据
try <% = a.getHint() %>
try <jsp:getProperty name = "a" property = "hint"/>
try ${a.hint}
2019/9/26
- tag (Javax.servlet.jsp.tagext)
精髓之处就是将jsp
中的java
代码通过这个接口写到一个文件里面,美观并且便于复用
// 示范程序 旧版的
// 新版的叫 SimpleTag
public class TimeTag extends TagSupport{
// 继承适配器类而不是直接实现接口
// 需要重写的函数
doStartTag(); // 返回值有三个 SKIP_BODY | EAVL_BODY_INCLUDE | EVAL_BODY_BUFFERED
// 其中最后一个返回值比较奇怪,它会为下面的 java 代码新开辟内存空间运行
// 这个函数在 jsp 中的 <custom tag 时候调用
doEndTag(); // 这个函数在 jsp 中的 custom tag/> 时候调用
}
// 新版的示范程序
public class TimeTag extends SimpleTagSupport{
// 同样是通过继承适配器类进行重写
// 需要注意的是 这里没有 getPageContext() 这个函数,需要使用 getJspContext() 向下强转
public void doTag();
}
public class ResetTag extends SimpleTagSupport{
public void doTag() throws JspException{
NumberGuessBean numguess = (PageContext)getJspContext().getSession().getAttribute("numguess");
numguess.reset();
}
}
- /WEB-INF/a.tld 标记库描述文件
// xml 中声明命名空间,t为命名空间的作用域名,称为前缀;没有前缀的为默认命名空间
<author xmlns:t = "uri1"
xmlns = "uri2">
</author>
// 在 jsp 中导入标记库文件,前缀为t,其中这个前缀类似C++中的作用域
<%@ taglib uri = "/WEB-INF/a.tld(也可写对应的URI)" prefix = "t" %>
// 声明 tag???? 对象??
<tag-lib>
<uri>uri</uri> // 这个节点拿来干嘛的?上网查查。用来标记该tld
<tag>
<name>name</name>
<tag-class>PageTag</tag-class>
<body-content>JSP</body-content>
<Attribute>
<name>data</name> // 该tag对应的java代码里面就必须要有对应的setData函数?
<type>List</type> // 表明资源类型
<required>true</required> // 是否必须提供这个属性
<rtexprval>true</rtexprval> // 是否是动态资源
</Attribute>
</tag>
<tag>
</tag>
</tag-lib>
2019/10/10
- 链接池
java.sql.*
javax.sql.DataSource
java.util.Locale
java.util.ResourceBundle
javax.naming.*
struts 1
mvc: jsp == view; servlet == controler; javaBeans == model
其中复用性最差的就是controler
如何提高controler
的复用性?
降低controler
的粒度;struts
干的就是这个事情,分为前端控制器和后端控制器
其中前端控制器为ActionServlet
, 处理request
, 转换为后端控制器能处理的逻辑
后端控制器为Action
, 调用底层模型
缺点:Action
数量太多…于是有了DispatchAction
2019/10/12
- 基于
struts
的网页开发- 建立一个
j2ee
项目 - 下载
struts
, 解压缩后将Lib
文件夹的jar
包拷贝到web-inf/lib
- 在
web.xml
中部署一个servlet
组件 - 创建后端控制器类,前端控制器调用后端
- 创建
ActionForm
,用于存储从前端传过来的数据以及返回结果
- 建立一个
<web-app>
<servlet>
<servlet-name>s</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet // servlet 作前端控制器
</servlet-class>
<init-param>
<param-name>config</param-name> // 组件执行初始化的时候调用该配置文件进行初始化
<param-value>/WEB-INF/struts-config.xml</param-value> // 名 config 可改;值 ...xml 不可改
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>s</servlet-name>
<url-pattern>*.do</url-pattern> // 将这种样式的请求分发到该 servlet
</servlet-maping>
</web-app>
- 前端控制器如何调用后端控制器?
- 使用接口 Action
- 使用反射机制
// 反射机制演示 慢,但是灵活
Object o = Bean.instantiate(
getClass().getClassLoader(),
className
);
Method method = o.getClass().getMethod(methodName);
method.invoke(...);
- 后端控制器有很多个?为什么?单一的一个功能只有一个控制器相对应?使用 Map<String, Action> 来存储后端控制器
- 如何降低
Action
Actionform
的数量? 使用DispatchAction
- 如何降低
ActionForm
的数量?提高其复用性?内置Map<String, Object>
DynaActionForm