JavaEE心得体会

2022-01-31 00:00:00 心得体会 JavaEE

JavaEE 技术心得体会
1 前端开发
1 简介
前端开发是创建Web页面或app等前端界面呈现给用户的过程,通过HTML,CSS及JS以及衍生出来的各种技术、框架、解决方案,来实现互联网产品的用户界面交互。它从网页制作演变而来,名称上有很明显的时代特征。在互联网的演化进程中,网页制作是Web1.0时代的产物,早期网站主要内容都是静态,以图片和文字为主,用户使用网站的行为也以浏览为主。随着互联网的发展和HTML5、CSS3的应用,现代网页更加美观,交互效果显著,功能更加强大。
通俗点讲,前端是制作与用户交互的界面,通过W3C规定的html和css以及javascript来完成。前期可以通过html和css来编写静态网页,同时可以配合js和jquery,ajax来实现动态网页。后期直接使用 bootstrap,easyui,adminlte,vue 等框架编写。

2 HTML
HTML 是用来描述网页的一种语言。
HTML 指的是超文本标记语言 (Hyper Text Markup Language)
HTML 不是一种编程语言,而是一种标记语言 (markup language)
标记语言是一套标记标签 (markup tag)
HTML 使用标记标签来描述网页

注意事项:
定义锚。
定义粗体字。

单标签 定义简单的折行。
定义按钮 (push button)。

定义文档中的节。 不赞成使用。定义文字的字体、尺寸和颜色。 定义供用户输入的 HTML 表单。

定义 HTML 标题。 定义斜体字。 定义内联框架。 定义图像。 定义输入控件。

定义段落。

3 CSS
层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。
CSS 能够对网页中元素位置的排版进行像素级精确控制,支持几乎所有的字体字号样式,拥有对网页对象和模型样式编辑的能力。

注意事项:
class属性:允许向一组在class属性上具有相同值的元素应用声明,body内的所有元素都有class属性,以句点开头。
id属性: 类似于class属性,但有一点重要的不同之处:id属性的值在整篇文档中必须是唯一的,以#开头。
类选择器中还需要注意“,”和“ ”(空格)的区别:一个代表并列,一个表示在上个标签下发挥作用。
4 JavaScript
JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。
注意事项:
Window 对象: 负责操作浏览器窗口,负责窗口状态,开闭等。
Document 对象:负责操作浏览器载入的文档(HTML文件),从属于window。
History 对象:可以代替后退(前进)按钮访问历史记录,从属于window。
Location 对象: 访问地址栏,也是从属于 window。

2 后端开发
1 servlet
(1)http协议:
什么是http协议?
就是W3C制定的规范
规定了浏览器和服务器如何通信及数据格式
如何通信?
建立连接
发送请求
返回响应
关闭连接
采用这种格式的好处?
一次请求一次连接,以便降低服务器压力。
开发过程中用到的:
使用request处理(接收)请求数据
使用response处理(拼接)响应数据
(2)生命周期:
A: 加载和实例化
Servlet容器负责加载和实例化Servlet。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Servlet实例。当Servlet容器启动后,它必须要知道所需的Servlet类在什么位置,Servlet容器可以从本地文件系统、远程文件系统或者其他的网络服务中通过类加载器加载Servlet类,成功加载后,容器创建Servlet的实例。因为容器是通过Java的反射API来创建Servlet实例,调用的是Servlet的默认构造方法(即不带参数的构造方法),所以我们在编写Servlet类的时候,不应该提供带参数的构造方法。

B: 初始化
在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,如建立数据库的连接,获取配置信息等。对于每一个Servlet实例,init()方法只被调用一次。在初始化期间,Servlet实例可以使用容器为它准备的ServletConfig对象从Web应用程序的配置信息(在web.xml中配置)中获取初始化的参数信息。在初始化期间,如果发生错误,Servlet实例可以抛出ServletException异常或者UnavailableException异常来通知容器。ServletException异常用于指明一般的初始化失败,例如没有找到初始化参数;而UnavailableException异常用于通知容器该Servlet实例不可用。例如,数据库服务器没有启动,数据库连接无法建立,Servlet就可以抛出UnavailableException异常向容器指出它暂时或永久不可用。

C:请求处理
Servlet容器调用Servlet的service()方法对请求进行处理。要注意的是,在service()方法调用之前,init()方法必须成功执行。在service()方法中,Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。在service()方法执行期间,如果发生错误,Servlet实例可以抛出ServletException异常或者UnavailableException异常。如果UnavailableException异常指示了该实例永久不可用,Servlet容器将调用实例的destroy()方法,释放该实例。此后对该实例的任何请求,都将收到容器发送的HTTP 404(请求的资源不可用)响应。如果UnavailableException异常指示了该实例暂时不可用,那么在暂时不可用的时间段内,对该实例的任何请求,都将收到容器发送的HTTP 503(服务器暂时忙,不能处理请求)响应。

D:服务终止
当容器检测到一个Servlet实例应该从服务中被移除的时候,容器就会调用实例的destroy()方法,以便让该实例可以释放它所使用的资源,保存数据到持久存储设备中。当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。如果再次需要这个Servlet处理请求,Servlet容器会创建一个新的Servlet实例。在整个Servlet的生命周期过程中,创建Servlet实例、调用实例的init()和destroy()方法都只进行一次,当初始化完成后,Servlet容器会将该实例保存在内存中,通过调用它的service()方法,为接收到的请求服务。

(3)页面跳转两种方式
A:RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
B:调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
C:RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使用HttpServletResponse.sendRedirect方法。
(4)过滤器
基本定义:
Filter是在Servlet 2.3之后增加的新功能,当需要限制用户访问某些资源或者在处理请求时提前处理某些资源的时候,就可以使用过滤器完成。
过滤器是以一种组件的形式绑定到WEB应用程序当中的,与其他的WEB应用程序组件不同的是,过滤器是采用了“链”的方式进行处理的。

实现过滤器:
在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口即可,此接口定义了三个操作方法:
public void init(FilterConfig filterConfig) throws ServletException
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException
public void destroy()
FilterChain接口的主要作用是将用户的请求向下传递给其他的过滤器或者是Servlet:
public void doFilter(ServletRequest request,ServletResponse response) throws IOException,ServletException
2 JSP
(1)JavaBean
JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。
(2)jstl和el
el表达式的使用:

1)访问bean的属性
    方式一:
     u s e r . n a m e , 容 器 会 依 次 从 p a g e C o n t e x t , r e q u e s t , s e s s i o n , a p p l i c a t i o n 中 查 找 ( g e t A t t r i b u t e ) 绑 定 名 称 为 u s e r 的 对 象 , 并 调 用 该 对 象 的 g e t N a m e 方 法 , 最 后 输 出 。 并 且 比 较 友 好 , 找 不 到 对 象 会 将 n u l l 转 换 成 ” ” 空 字 符 串 输 出 。 但 是 一 定 要 有 g e t 方 法 , 如 果 找 不 到 g e t 方 法 , 还 是 会 e r r o r 500 错 误 。         指 定 查 找 范 围 : p a g e S c o p e , r e q u e s t S c o p e , s e s s i o n S c o p e , a p p l i c a t i o n 来 指 定 , 例 如 {user.name},容器会依次从pageContext,request,session,application中查找(getAttribute)绑定名称为user的对象,并调用该对象的getName方法,最后输出。并且比较友好,找不到对象会将null转换成””空字符串输出。但是一定要有get方法,如果找不到get方法,还是会error500错误。     指定查找范围:pageScope,requestScope,sessionScope,application来指定,例如 user.name,pageContext,request,session,application(getAttribute)usergetNamenullgetgeterror500    pageScope,requestScope,sessionScope,application{sessionScope.user.name},就算session找不到,其他地方也不找了。
    方式二:
     u s e r [ ” n a m e ” ]         {user[“name”]}      user[name]    {user.interest[0]},可以访问数组下标,要有get方法。
  2)进行一些简单的运算,运算的结果可以给jsp标签的属性赋值,也可以直接输出。
    a.算术运算 ± */ %
     1 + 1 直 接 输 出 2 , 没 有 字 符 串 拼 接 . {1+1}直接输出2,没有字符串拼接 . 1+12.{“2”+“4”}输出6
    b.关系运算 > < = == >= !=
      KaTeX parse error: Expected ‘EOF’, got ‘&’ at position 26: …rue     c.逻辑运算 &̲& || !       {1<2 && 2>3} false
    d.empty运算
      用来判断集合是否为空,或者是否是一个空字符串

<%
        List list1=new ArrayList();
        request.setAttribute(“list”,list1);
        request.setAttribute(“str2”,””);
         e m p t y l i s t / / 输 出 t r u e                 {empty list} //输出true          emptylist//true        {empty str2}//输出true
         e m p t y n u l l / / 输 出 t r u e                 {empty null}//输出true          emptynull//true        {empty aaa}//输出true,容器找不到aaa这个绑定名也会true
      %>
3)读取请求参数值 e3.jsp?username=Sally
      a. p a r a m . u s e r n a m e 等 价 于 r e q u e s t . g e t P a r a m e t e r ( ” u s e r n a m e ” ) ;             b . {param.username}等价于request.getParameter(“username”);       b. param.usernamerequest.getParameter(username);      b.{paramValues.city}等价于request.getParamterValues(“city”);

jstl标签

将jstl相关的jar文件拷贝到WEB-INF/lib下,如果使用javaee5.0,已包含jstl相关的jar文件。一般不需要再拷贝。使用taglib指令,导入相应的标签。
<%@taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
jstl的核心标签:

1)if
  <c:if test=” u s e r . g e n d e r = = ′ m ′ ” > 男 < / c : i f >     < c : i f t e s t = ” {user.gender == ‘m’}”>男</c:if>   <c:if test=” user.gender==m></c:if>  <c:iftest={user.gender != ‘m’}”>女</c:if>
  <c:if test=” u s e r . g e n d e r = = ′ m ′ ” v a r = ” f l a g ” s c o p e = ” r e q u e s t ” > 男 < / c : i f > 等 价 于 r e q u e s t . s e t A t t r i b u t e ( ” f l a g ” , 运 行 结 果 t r u e / f a l s e ) , s c o p e 可 以 写 p a g e , s e s s i o n , a p p l i c a t i o n     < c : i f t e s t = ” {user.gender == ‘m’}” var=”flag” scope=”request”>男</c:if> 等价于request.setAttribute(“flag”,运行结果true/false) ,scope可以写page,session,application   <c:if test=” user.gender==mvar=flagscope=request></c:if>request.setAttribute(flag,true/false),scopepage,session,application  <c:iftest={!flag}”>女</c:if> 通过上面一行的flag结果来判断

2)choose 相当于if{} elseif{} else{}
  when可以出现1次或者多次。当test属性为true时,会执行该分支。
  otherwise可以出现0次或者1次。表示例外。
  <c:choose>
    <c:when test=” u s e r . g e n d e r = = ′ m ′ ” > 男         < / c : w h e n >         < c : w h e n t e s t = ” {user.gender == ‘m’}”>男     </c:when>     <c:when test=” user.gender==m>    </c:when>    <c:whentest={user.gender == ‘f’}”>女
    </c:when>
    <c:otherwise>保密
    </c:otherwise>
  </c:choose>

3)forEach标签,用来遍历集合或者数组。每次从集合或者数组中取一个元素,然后将其绑定到pageContext上,绑定名由var属性来指定。
  items属性用来指定要遍历的集合活着数组,可以使用el表达式。
  var属性用来指定绑定名,绑定范围固定是pageContext.
  varStatus属性:用来制定一个绑定名,绑定范围固定是pageContex。绑定值是一个特殊的对象,该对象提供了一些方法,用来获得当前遍历的状态。getIndex():获得当前被遍历的元素的下标(从0开始)。getCount():获得当前是第几次遍历(从1开始)
  <c:forEach items=”” var=”” varStatus=””>
</c:forEach>

2.自定义标签 简单标签(new) 复杂标签(old)
  step1,写一个java类,继承SimpleTagSupport类。
  step2.orerride doTag方法,在该方法里面编写处理逻辑。
step3,描述标签(.tld文件)

3 Struts2
(1) Action
action是struts2的核心,所有用户请求都需要使用action处理并返回数据。

Struts2创建action的四种方式:

第一种方式:

index.jsp页面:

struts2创建action的第1种方式

<?xml version=”1.0″ encoding=”UTF-8″ ?>

TestAction1.java里:(普通Java类)

package com.xsl.action;
//Struts2任何一个普通的Java类都可以成为Action
public class TestAction1 {
public String execute(){
System.out.println(“struts2创建action的第1种方式。”);
return “success”;
}
}

第二种方式:

index.jsp页面:

struts2创建action的第2种方式

<?xml version=”1.0″ encoding=”UTF-8″ ?> /success.jsp

TestAction2.java里:(继承Action类)
package com.xsl.action;
import com.opensymphony.xwork2.Action;
public class TestAction2 implements Action {
public String execute() throws Exception {
System.out.println(“struts2创建action的第2种方式。”);
return SUCCESS;
}
}

第三种方式:

index.jsp页面:

struts2创建action的第3种方式

<?xml version=”1.0″ encoding=”UTF-8″ ?> /success.jsp

TestAction3.java里:(继承ActionSupport类)
package com.xsl.action;
import com.opensymphony.xwork2.ActionSupport;
public class TestAction3 extends ActionSupport {
public String test1(){
System.out.println(“struts2创建action的第3种方式。”);
return SUCCESS;
}
}

第四种方式:

index.jsp页面:

struts2创建action的第3.1种方式

<?xml version=”1.0″ encoding=”UTF-8″ ?> /success.jsp

TestAction3.java同上

(2)标签库
一、struts2标签定义文件在struts2-core-2.0.11.1\META-INF 下面,文件名为struts-tags.tld
二、如果工程使用了servlet2.3规范,要做两件事,就能在工程中使用struts2标签了
1: 在web.xml中增加标签库的定义

/struts-tags
/WEB-INF/lib/struts2-core-2.0.11.1.jar

/struts-tags 是struts2标签库默认的URI,建议使用这个名称
2 在JSP中使用taglib编译指令导入标签库 <%@ taglib prefix=“s” uri=”/struts-tags” %>

三、如果使用servlet2.4规范,不须要在web.xml中增加标签库定义,只要做一件事,就行
1 在JSP中使用taglib编译指令导入标签库 <%@ taglib prefix="s" uri="/struts-tags" %>

标签库:

A:
<s:a href=””></s:a>—–超链接,类似于html里的
<s:action name=””></s:action>—–执行一个view里面的一个action
<s:actionerror/>—–如果action的errors有值那么显示出来
<s:actionmessage/>—–如果action的message有值那么显示出来
<s:append></s:append>—–添加一个值到list,类似于list.add();
<s:autocompleter></s:autocompleter>—–自动完成<s:combobox>标签的内容,这个是ajax

B:
<s:bean name=””></s:bean>—–类似于struts1.x中的,JavaBean的值

C:
<s:checkbox></s:checkbox>—–复选框
<s:checkboxlist list=””></s:checkboxlist>—–多选框
<s:combobox list=””></s:combobox>—–下拉框
<s:component></s:component>—–图像符号

D:
<s:date/>—–获取日期格式
<s:datetimepicker></s:datetimepicker>—–日期输入框
<s:debug></s:debug>—–显示错误信息
<s:div></s:div>—–表示一个块,类似于html的

<s:doubleselect list=”” doubleName=”” doubleList=””></s:doubleselect>—–双下拉框

E:
<s:if test=””></s:if>
<s:elseif test=””></s:elseif>
<s:else></s:else>—–这3个标签一起使用,表示条件判断

F:
<s:fielderror></s:fielderror>—–显示文件错误信息
<s:file></s:file>—–文件上传
<s:form action=””></s:form>—–获取相应form的值

G:
<s:generator separator=”” val=””></s:generator>—-和<s:iterator>标签一起使用

H:
<s:head/>—–在里使用,表示头文件结束
<s:hidden></s:hidden>—–隐藏值

I:
<s:i18n name=””></s:i18n>—–加载资源包到值堆栈
<s:include value=””></s:include>—–包含一个输出,servlet或jsp页面
<s:inputtransferselect list=””></s:inputtransferselect>—–获取form的一个输入
<s:iterator></s:iterator>—–用于遍历集合

L:
<s:label></s:label>—–只读的标签

M:
<s:merge></s:merge>—–合并遍历集合出来的值

O:
<s:optgroup></s:optgroup>—–获取标签组
<s:optiontransferselect doubleList=”” list=”” doubleName=””></s:optiontransferselect>—–左右选择框

P:
<s:param></s:param>—–为其他标签提供参数
<s:password></s:password>—–密码输入框
<s:property/>—–得到’value’的属性
<s:push value=””></s:push>—–value的值push到栈中,从而使property标签的能够获取value的属性

R:

<s:radio list=””></s:radio>—–单选按钮
<s:reset></s:reset>—–重置按钮

S:
<s:select list=””></s:select>—–单选框
<s:set name=””></s:set>—–赋予变量一个特定范围内的值
<s:sort comparator=””></s:sort>—–通过属性给list分类
<s:submit></s:submit>—–提交按钮
<s:subset></s:subset>—–为遍历集合输出子集

T:
<s:tabbedPanel id=””></s:tabbedPanel>—–表格框
<s:table></s:table>—–表格
<s:text name=””></s:text>—–I18n文本信息
<s:textarea></s:textarea>—–文本域输入框
<s:textfield></s:textfield>—–文本输入框
<s:token></s:token>—–拦截器
<s:tree></s:tree>—–树
<s:treenode label=””></s:treenode>—–树的结构

U:
<s:updownselect list=””></s:updownselect>—–多选择框
<s:url></s:url>—–创建url

(3)ActionContext,OGNL
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
ActionContext是Strust2中的内置对象,通过该对象可以获得之前Servlet中的对象,比如:requst对象,response对象…
actioncontext充当OGNL的context。是action的上下文,也可以叫做action的数据中心,本质是一个map,在其中,所有的数据都存放在这里,那其中到底存放了哪些东西呢,actionContext中存放数据的方式又是怎样的?
  actionContext是一个map,所以其中都是以键值对的形式存储对象,request、session、application这种我们熟知的作用域,注意是作用域,而不是对象,
paramters:这个是表单提交的参数,全部都会放到这个map中,attr(attributes):三个作用域所有的属性都会放在该map下,如果有重复的,那么以request域中的为准。
VALUE_STACK:值栈,存放着valueStack对象,也就是说,通过ActionContext能够获取到valueStack。如果我们使用actionContext.put(); 那么会将该键值对直接放入到ActionContext下,注意:除了request外,其他都可以直接通过getXxx()获得。而想要获取request作用域,必须通过key值的方式来获取。 ActionContext.getContext().get(“request”); struts2对request进行了增强。从这里actionContext中是不能直接获取到的,request进行了怎样的增强呢?
比如actionContext中put了一个普通的key和value,该键值对并没有在request域中,但是在jsp中,通过在request域查找key,也能找到该键值对,底层进行了两步:第一步:从request域中查找数据,第二步:如果没有找到,将从值栈中执行findValue()。这样就解释了为什么通过ActionContext不能直接获取request,并且为什么不在request作用域中的数据,而通过在request域中查找也能够获取到。
(4)拦截器
java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器):

(必须加,否则出错) 也可以改为对全局Action设置自己需要的拦截器,如下: 在struts.xml里面定义全局的配置设置 0 (这句是设置所有Action自动调用的拦截器堆栈) struts-action.xml里面配置Action如下: (这里扩展struts.xml里面定义的配置就可以了) /jsp/smeishop/admin/index.jsp /jsp/smeishop/admin/logon.jsp /jsp/smeishop/admin/logon.jsp /jsp/smeishop/admin/logon.jsp

(5)文件上传下载
一.单个文件上传:
1.文件上传需要两个jar包:

在Action中使用了三个属性封装文件信息
File类型的XXX属性,与表单的File控件的name属性一样,用于封装File控件对应的文件内容
String类型的xxxFileName属性,该属性名称由前面的File类型属性和FileName组合,是固定的语法,是封装File控件对应文件的文件名
String类型的XXXContentType属性,同样由xxx属性和ContentType组合而成,是固定语法,封装File控件对应文件的文件类型

配置action:

/upload
success.jsp

二.多个文件上传
只需在上传Action中将原本处理单个文件的操作改成对集合操作即可。
其他的都跟单个上传的一样。
配置action:

/upload
success.jsp

三.文件下载
文件下载需要InputStream,首先在文件下载Action中提供一个获得InputStream的方法,通过输入流可以获取希望下载的文件内容。通过Context得到下载文件的实际路径,构建一个InputStream输入流实现文件的下载读取。在配置文件中,同样对Action进行配置,并对stream结果类型的参数进行设置。ContentType参数决定了下载文件的类型,不同的文件类型对应的参数值也是不同的。通常情况下,ContentType参数直接设置为application/octet-stream即可。contentDisposition参数由两部分组成,前面的部分表示处理文件的形式,如attachement表示在下载时弹出对话框,提出用户保存或直接打开该文件;而后一部分表示下载文件的文件名称。两部分之间用“;”进行分隔。然后开发一个简单的下载页面,在页面中设置一个超链接,通过超链接请求下载Action。

(6)验证表单和框架
表单数据验证是很常见的功能,通常前端页面会有一次 js验证,但是后台也需要进行一次验证,这不依赖于前台验证,是保险的做法。

同时,我们后台验证输入数据的合法性,如果按照以前的servlet方法,显而易见是非常麻烦的,我们既要获取表单数据,又要进行String类型的表单数据进行数据类型转换,再进行数据合法性验证,然后还要将非法数据的提示信息打印到页面上提示用户输入非法,这显得很忙,很累。

因此,Struts2为我们提供了一些数据验证手段,特别是Struts2的验证框架, 可以有效为我们减少重复性的操作。

  1. Action重写的validate() 方法或使用validateXXX()方法
    validate的意思就是验证。我们的Action通常会集成ActionSupport这个类,这个类有很多有用的方法,其中,validate()验证方法就是其中之一。validate()方法会在action前自动执行。

这样重写validate()方法后,对于Action里的任何方法,都会先执行validate()方法验证。实际上,一个Action里会有很多个方法,但是并不是每个方法都需要同样的验证方式,因此,就出现了根据方法不同设定不同验证方法的方式。
validateXXX(),可以针对特定的方法使用特定的验证方法,其余没有什么变化。这个方法直接定义即可,同样会在XXX()方法前执行验证。
如果两个验证方法都存在,执行顺序是先执行validateXXX(),再执行通用的validate()方法。

2.使用Struts2验证框架
尽管使用validate()方法比起自己实现验证要方便的多,但是依然存在代码不能重用的缺点,很多aciton方法都需要同样的验证,但又要在不同的action里重复写多次validate()方法。
因此,就出现了Struts2的验证框架。

对于struts2,我了解到它出现了两次高危漏洞,就算以后再用,也肯定要升级到2.5的。
5 Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

ORM:

工作原理:

Hibernate: 目前最流行的开源ORM框架,已经被选作JBoss的持久层解决方案,整个Hibernate的项目也一并投入了JBoss的怀抱,而Jboss又加入了Red Hat组织,因此Hibernate属于Red Hat组织的一部分,Hibernate灵巧的数据,优秀的性能,还有丰富的文档。

Session和SessionFactory:
session是一次浏览器和服务器的交互的会话,是一种服务区存储数据的方式,每次我们访问一个页面,如果有开启session,也就是有session_start() 时,就会自动生成一个session_id 来标注是这次会话的唯一ID,同时也会自动往cookie里写入一个名字为PHPSESSID的变量,它的值正是session_id,当这次会话没结束,再次访问的时候,服务器会去读取这个PHPSESSID的cookie是否有值有没过期,如果能够读取到,则继续用这个session_id,如果没有,就会新生成一个session_id,同时生成PHPSESSID这个cookie。由于默认生成的这个PHPSESSID cookie是会话,也就是说关闭浏览器就会过期掉,所以,下次重新浏览时,会重新生成一个session_id,用来标识绑定一个用户的。
SessionFactory接口:
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象,需要注意的是SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
SessionFactory就是一个用于创建Hibernate的Session对象的工厂。SessionFactory通常是在应用启动时创建好的,应用程序中的代码用它来获得Session对象。作为一个单个的数据存储,它也是 线程安全的,所以多个线程可同时使用同一个SessionFactory。Java JEE应用一般只有一个SessionFactory,服务于客户请求的各线程都通过这个工厂来获得Hibernate的Session实例。

配置文件
在hibernate中,我们主要使用两种配置文件:
1.核心配置文件——hibernate.cfg.xml(主要描述Hibernate的相关配置)
2.映射配置文件——xxx.hbm.xml映射配置文件——xxx.hbm.xml

对于Hibernate的核心配置文件它有两种方式:
1.hibernate.cfg.xml
2.hibernate.properties
我们在开发中使用比较多的是hibernate.cfg.xml这种方式,原因是它的配置能力更强,并且易于修改。

com.mysql.jdbc.Driver jdbc:mysql:///hibernate root 123456

true

true

<propertyname=“hibernate.dialect”>org.hibernate.dialect.MySQLDialect

update

映射配置文件的名称是:类名.hbm.xml,它一般放置在实体类所在的包下。这个配置

文件的主要作用是建立表与类之间的映射关系。

配置文件的类型:
对于type属性它的取值可以有三种:
1.Java中的数据类型
2.Hibernate中的数据类型
3.SQL的数据类型

一级缓存和二级缓存:
1:Hibernate的一级缓存:
  1.1:使用一级缓存的目的是为了减少对数据库的访问次数,从而提升hibernate的执行效率;(当执行一次查询操作的时候,执行第二次查询操作,先检查缓存中是否有数据,如果有数据就不查询数据库,直接从缓存中获取数据);
   1.2:Hibernate中的一级缓存,也叫做session的缓存,它可以在session范围内减少数据库的访问次数,只在session范围内有效,session关闭,一级缓存失败;
  1.3:一级缓存的特点,只在session范围有效,作用时间短,效果不是特别明显,在短时间内多次操作数据库,效果比较明显。
  1.4:当调用session的save/saveOrUpdate/get/load/list/iterator方法的时候,都会把对象放入session缓存中;
  1.5:session的缓存是由hibernate维护的,用户不能操作缓存内容;如果想操作缓存内容,必须通过hibernate提供的evict/clear方法操作
  1.6:缓存相关的方法(在什么情况下使用上面方法呢?批量操作情况下使用,如Session.flush();先与数据库同步,Session.clear();再清空一级缓存内容):
    session.flush();让一级缓存与数据库同步;
    session.evict();清空一级缓存中指定的对象;
    session.clear();清空一级缓存中所有的对象;
懒加载概念:当用到数据的时候才向数据库查询,这就是hibernate的懒加载特性。
二级缓存:
  Hibernate提供了基于应用程序级别的缓存即为二级缓存,可以跨多个session,即不同的session都可以访问缓存数据。 这个缓存也叫二级缓存。
  Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果想用二级缓存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。
6 Mybatis
轻量级持久化框架
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

关键配置

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.15.173:3306/mybatis
username=root
password=123456
mapper映射文件
Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。
映射文件中有很多属性,常用的就是parameterType(输入类型)、resultType(输出类型)、resultMap()、rparameterMap()。
#{}与KaTeX parse error: Expected ‘EOF’, got ‘#’ at position 3: {}#̲{}实现的是向prepareS…{}和#{}不同,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值, pojoparameterType{}括号中只能是value。使用 不 能 防 止 s q l 注 入 , 但 是 有 时 用 {}不能防止sql注入,但是有时用 sql{}会非常方便。
逆向工程
Mybatis 官方提供了逆向工程,可以针对数据库表自动生成Mybatis执行所需要的代码(包括mapper.xml、Mapper.java、pojo)。
所需要的jar包:

7 SSH
SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。SSH客户端适用于多种平台。几乎所有UNIX平台—包括HP-UX、Linux、AIX、Solaris、Digital UNIX、Irix,以及其他平台,都可运行SSH。
SSH(Struts,Spring,Hibernate或SpringMVC,Spring,Hibernate) Struts进行流程控制,Spring进行业务流转,Hibernate进行数据库操作的封装。
Struts:
Struts对Model,View和Controller都提供了对应的组件。 分为Struts1和Struts2,区别甚大。
Action,这个类通常由用户提供,该控制器负责接收来自ActionServlet的请求,并根据该请求调用模型的业务逻辑方法处理请求,并将处理结果返回给JSP页面显示。

Model部分:
由ActionForm和JavaBean组成,其中ActionForm用于封装用户的请求参数,封装成ActionForm对象,该对象被ActionServlet转发给Action,Action根据ActionForm里面的请求参数处理用户的请求。
JavaBean则封装了底层的业务逻辑,包括数据库访问等。
View部分:
该部分采用JSP(或HTML、PHP……)实现。
Struts提供了丰富的标签库,通过标签库可以减少脚本的使用,自定义的标签库可以实现与Model的有效交互,并增加了现实功能。对应上图的JSP部分。

Controller组件:
Controller组件有两个部分组成——系统核心控制器,业务逻辑控制器。
系统核心控制器,对应上图的ActionServlet。该控制器由Struts框架提供,继承HttpServlet类,因此可以配置成标注的Servlet。该控制器负责拦截所有的HTTP请求,然后根据用户请求决定是否要转给业务逻辑控制器。
业务逻辑控制器,负责处理用户请求,本身不具备处理能力,而是调用Model来完成处理。对应Action部分。

Spring
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用

面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。
Hibernate
Hibernate的核心接口一共有5个,分别为:Session、SessionFactory、Transaction、Query和Configuration。这5个核心接口在任何开发中都会用到。通过这些接口,不仅可以对持久化对象进行存取,还能够进行事务控制。下面对这五个核心接口分别加以介绍。
·Session接口和SessionFactory接口已介绍过
·Configuration接口:Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。在Hibernate的启动的过程中,Configuration类的实例首先定位映射文档位置、读取配置,然后创建SessionFactory对象。
Transaction接口:Transaction接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。
在Struts + Spring + Hibernate的组合框架模式中,三者各自的特点:Struts 的MVC设计模式可以使我们的逻辑变得很清晰。
Spring 的IOC和AOP可以使我们的产品在最大限度上解藕。
hibernate的当然就是实体对象的持久化了
典型的J2EE三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。
表现层是传统的JSP技术,自1999年问世以来,经过多年的发展,其广泛的应用和稳定的表现,为其作为表现层技术打下了坚实的基础。
中间层采用的是流行的Spring+Hibernate,为了将控制层与业务逻辑层分离,又细分为以下几种。
Web层,就是MVC模式里面的“C”(controller),负责控制业务逻辑层与表现层的交互,调用业务逻辑层,并将业务数据返回给表现层作组织表现,该系统的MVC框架采用Struts。
Service层(就是业务逻辑层),负责实现业务逻辑。业务逻辑层以DAO层为基础,通过对DAO组件的正面模式包装,完成系统所要求的业务逻辑。
DAO层,负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。
PO,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库,该系统采用Hibernate作为ORM框架。
Spring的作用贯穿了整个中间层,将Web层、Service层、DAO层及PO无缝整合,其数据服务层用来存放数据。
一个良好的框架可以让开发人员减轻重新建立解决复杂问题方案的负担和精力;它可以被扩展以进行内部的定制化;并且有强大的用户社区来支持它。框架通常能很好的解决一个问题。然而,你的应用是分层的,可能每一个层都需要各自的框架。仅仅解决UI问题并不意味着你能够很好的将业务逻辑和持久性逻辑和UI 组件很好的耦合。
不可否认,对于简单的应用,采用ASP或者PHP的开发效率比采用J2EE框架的开发效率要高。甚至有人会觉得:这种分层的结构,比一般采用JSP + Servlet的系统开发效率还要低。
心得体会:
所谓,师傅领进门,修行靠自身。感谢老师在这一学期的陪伴,让我获取了不小的进步。尽管路途仍然遥远,但您为我们指明了方向,我相信我们在这一方向下学习,一定会取得不小的成绩。
最后,希望以后能在未来的道路上能再次有你的陪伴。

    原文作者:IT成就未来
    原文地址: https://blog.csdn.net/weixin_46229392/article/details/104093651
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章