一、Struts2执行流程: 

  1.客户端初始化一个指向servlet容器(tomcat)的请求;

  2.这个请求经过一系列过滤器(Filter);

  3.接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请求是否需要调用某个Action;

  4.如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy;

  5.ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类;

  6.ActionProxy调用invoke方法创建一个ActionInvocation的实例。

  7.递归调用,判断是否还有下一个拦截器,当没有了下一个拦截器,就执行Action的业务方法;

  8.一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链;

  9.返回结果的时候依旧经过一系列拦截器。

  请求 ---- StrutsPrepareAndExecuteFilter 核心控制器 ----- Interceptors 拦截器(实现代码功能,只访问action时执行 ) ----- Action 的execuute --- 结果页面 Result

二、在web.xml 配置struts2 前端控制器 (Filter)

<filter>

<filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

三、struts2 常量配置 (键值对 properties)

  struts2 默认常量 在 default.properties 中配置

  常用常量

  <constant name="struts.i18n.encoding" value="UTF-8"/>  ----- 相当于request.setCharacterEncoding("UTF-8"); 解决post请求乱码

  <constant name="struts.action.extension" value="action,,"/>  --- 访问struts2框架Action访问路径 扩展名 (要求)

  * struts.action.extension=action,, 默认以.action结尾扩展名 和 不写扩展名 都会分发给 Action

  <constant name="struts.serve.static.browserCache" value="false"/> false不缓存,true浏览器会缓存静态内容,产品环境设置true、开发环境设置false

  <constant name="struts.devMode" value="true" />  提供详细报错页面,修改struts.xml后不需要重启服务器 (要求)

   <action>的name 和 <package>的namespace属性 共同决定 Action的访问路径 !!!!!!!!

  例如 :

  <package name="usermanager" namespace="/user" extends="struts-default">

  <action name="hello" class="cn.itcast.struts2.demo1.HelloAction">

  访问路径 /user/hello.action

  3) <action> 元素配置默认值

<package> 的namespace 默认值 /

  <action> 的class 默认值 ActionSupport 类

  <result> 的 name 默认值 success

  <action> 的method默认值execute

4、 struts2 配置文件分离

通过 <include file="struts-part1.xml"/> 将struts2 配置文件 拆分

分离配置文件的原则:按模块进行分离,再统一组装到struts.xml  (<include>标签)

五、 Action的访问

HTTP请求 提交 Struts2 StrutsPrepareAndExecuteFilter 核心控制器 ------ 请求分发给不同Action

1、 让请求能够访问Action  ----- Action书写方式 三种

第一种 Action可以是 POJO  ((PlainOldJavaObjects)简单的Java对象) ---- 不需要继承任何父类,实现任何接口

* struts2框架 读取struts.xml 获得 完整Action类名

* obj = Class.forName("完整类名").newInstance();

* Method m = Class.forName("完整类名").getMethod("execute");  m.invoke(obj); 通过反射 执行 execute方法

第二种 编写Action 实现Action接口

Action接口中,定义默认五种 逻辑视图名称

public static final String SUCCESS = "success";  // 数据处理成功 (成功页面)

public static final String NONE = "none";  // 页面不跳转  return null; 效果一样

public static final String ERROR = "error";  // 数据处理发送错误 (错误页面)

public static final String INPUT = "input"; // 用户输入数据有误,通常用于表单数据校验 (输入页面)

public static final String LOGIN = "login"; // 主要权限认证 (登陆页面)

* 五种逻辑视图,解决Action处理数据后,跳转页面

第三种 编写Action  继承ActionSupport  (推荐)

在Action中使用 表单校验、错误信息设置、读取国际化信息 三个功能

2、 Action中方法调用

1) 在配置 <action> 元素时,没有指定method属性, 默认执行 Action类中 execute方法

<action name="request1" class="baoming.demo3.RequestAction1" />

2) 在<action> 元素内部 添加 method属性,指定执行Action中哪个方法

<action name="regist" class="baoming.demo4.RegistAction" method="regist"/> 执行 RegistAction 的regist方法

3) 使用通配符* ,简化struts.xml配置

<a href="${pageContext.request.contextPath }/user/customer_add.action">添加客户</a>

<a href="${pageContext.request.contextPath }/user/customer_del.action">删除客户</a>

struts.xml

<action name="customer_*" class="baoming.struts2.demo4.CustomerAction" method="{1}"></action>   ---  {1}就是第一个* 匹配内容

Action 构造方法调用几次?是否为单例

Action的生命周期?

因为每次请求都会调用构造方法,说明它是多实例的,不存在线程并发访问时的冲突问题

Struts1会不会存在线程安全问题?Struts1是单例的,会存在线程并发访问时的安全问题

3、 动态方法调用 (零配置路线)

访问Action中指定方法,不进行配置

1) 在工程中使用 动态方法调用 ,必须保证 struts.enable.DynamicMethodInvocation = true 常量值为true

2) 在action的访问路径 中 使用 "!方法名"

页面

<a href="${pageContext.request.contextPath }/user/product!add.action">添加商品</a>

配置

<action name="product" class="bao.struts2.demo4.ProductAction"></action>

执行 ProductAction 中的 add方法

六、在Action中使用Servlet API

1、 在Action 中解耦合方式 间接访问 Servlet API  --------- 使用 ActionContext 对象

在struts2 中 Action API 已经与 Servlet API 解耦合 (没有依赖关系 )

* Servlet API 常见操作 : 表单提交请求参数获取,向request、session、application三个范围存取数据

actionContext = ActionContext.getContext();

actionContext.getParameters(); 获得所有请求参数Map集合

actionContext.put("company", "数据"); / actionContext.get("company") 对request范围存取数据

3) actionContext.getSession(); 获得session数据Map,对Session范围存取数据

actionContext.getSession().put("key","value");

4) actionContext.getApplication(); 获得ServletContext数据Map,对应用访问存取数据

actionContext.getApplication().put("key","value");

*本质分析是否存在线程安全问题? 不会有 答案原码:ActionContext  (使用ThreadLocal存储相关的值)

3、 在Action中直接通过 ServletActionContext 获得Servlet API

ServletActionContext.getRequest() : 获得request对象 (session)

ServletActionContext.getResponse() : 获得response 对象

ServletActionContext.getServletContext() : 获得ServletContext对象

* 静态方法没有线程问题,ThreadLocal

七、 结果页面的配置

Action处理请求后, 返回字符串(逻辑视图名), 需要在struts.xml 提供 <result>元素定义结果页面

1、 局部结果页面 和 全局结果页面

<action name="result" class="bao.struts2.demo6.ResultAction">

<!-- 局部结果  当前Action使用 -->

<result name="success">/demo6/result.jsp</result>

</action>

<global-results>

<!-- 全局结果 当前包中 所有Action都可以用-->

<result name="success">/demo6/result.jsp</result>

</global-results>

2、 结果页面跳转类型

* 在struts-default.xml 定义了 一些结果页面类型

* 使用默认type 是 dispatcher 转发 (request.getRequestDispatcher.forward)

1)  dispatcher :Action 转发给 JSP

2)  chain :Action调用另一个Action (同一次请求)

<result name="success" type="chain">hello</result>  hello是一个Action的name

3) redirect : Action重定向到 JSP

<result name="success" type="redirect">hello.action</result>  hello是一个Action的name

4) redirectAction :Action重定向到另一个Action

<result name="success" type="redirectAction">hello</result>

Action : 可以作为模型,也可以是控制器 

属性驱动 和 模型驱动

第一种 :Action 本身作为model对象,通过成员setter封装 (属性驱动 )

页面:

用户名  <input type="text" name="username" /> <br/>

Action :

public class RegistAction1 extends ActionSupport {

private String username;

public void setUsername(String username) {

this.username = username;

}

}

  * struts2  Action 是多实例

 struts1 Action 是单例的

第二种 :创建独立model对象,页面通过ognl表达式封装 (属性驱动)

页面:

用户名  <input type="text" name="user.username" /> <br/>  ----- 基于OGNL表达式的写法

Action:

public class RegistAction2 extends ActionSupport {

private User user;

public void setUser(User user) {

this.user = user;

}

public User getUser() {

return user;

}

}

问题: 谁来完成的参数封装

<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

第三种 :使用ModelDriven接口,对请求数据进行封装 (模型驱动 ) ----- 主流

页面:

用户名  <input type="text" name="username" /> <br/>

Action :

public class RegistAction3 extends ActionSupport implements ModelDriven<User> {

private User user = new User(); // 必须手动实例化

public User getModel() {

return user;

}

}

* struts2 有很多围绕模型驱动的特性

* <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> 为模型驱动提供了更多特性

对比第二种、第三种 : 第三种只能在Action中指定一个model对象,第二种可以在Action中定义多个model对象

<input type="text" name="user.username" />

<input type="text" name="product.info" />

属性驱动和模型驱动都是框架的拦截器来帮助实现的。

 数据类型转换问题

1、 struts2 内部提供大量类型转换器,用来完成数据类型转换问题

boolean 和 Boolean

char和 Character

int 和 Integer

long 和 Long

float 和 Float

double 和 Double

Date 可以接收 yyyy-MM-dd格式字符串  (yyyy/MM/dd不能转)

数组  可以将多个同名参数,转换到数组中

集合  支持将数据保存到 List 或者 Map 集合

案例: 输入合法年龄和生日可以自动转换

当输入abc 转换为 int类型 age时

Caused by: java.lang.NoSuchMethodException: bao.struts2.demo3.CustomerAction.setAge([Ljava.lang.String;

分析: 输入20 ,转换 int类型20  --- setAge(int)

输入abc,转换int 出错 ---- setAge(String) ----- 报错方法不存在异常

2、 自定义类型转换器 (了解

1) 自定义类型转换器

第一种 实现TypeConverter接口

convertValue(java.util.Map<java.lang.String,java.lang.Object> context, java.lang.Object target, java.lang.reflect.Member member, java.lang.String propertyName, java.lang.Object value, java.lang.Class toType)

第二种 继承 DefaultTypeConverter

convertValue(java.util.Map<java.lang.String,java.lang.Object> context, java.lang.Object value, java.lang.Class toType)

第三种 继承 StrutsTypeConverter

convertFromString(java.util.Map context, java.lang.String[] values, java.lang.Class toClass)  --- 请求封装

convertToString(java.util.Map context, java.lang.Object o)   --- 数据回显

类型转换器 一直都是双向转换

页面提交请求参数,封装到model --- 需要转换

model数据 需要在页面 回显  ---- 需要转换

2) 以 1990/10/10 为例,自定义日期转换器,完成转换  第二种方法

public Object convertValue(Map<String, Object> context, Object value,

Class toType) {

// 根据toType判断 是请求封装 还是 数据回显

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

if (toType == Date.class) {

// 请求参数封装 (value是字符串)

String[] params = (String[]) value;

String strVal = params[0]; // 转换为 日期类型

try {

return dateFormat.parse(strVal);

} catch (ParseException e) {

e.printStackTrace();

}

} else {

// 回显(value是 Date)

Date date = (Date) value;

return dateFormat.format(date);

}

return null;

}

3) 注册类型转换器

局部注册 : 只对当前Action有效 (针对属性)

全局注册 : 针对所有Action的日期类型有效 (针对类型 )

局部注册 : 在Action类所在包 创建 Action类名-conversion.properties , 格式 : 属性名称=类型转换器的全类名

全局注册 : 在src下创建 xwork-conversion.properties ,格式 : 待转换的类型=类型转换器的全类名

3、 类型转换中错误处理

通过分析拦截器作用,得知当类型转换出错时,自动跳转input视图 ,在input视图页面中 <s:fieldError/> 显示错误信息

* 在Action所在包中,创建 ActionName.properties,在局部资源文件中配置提示信息 : invalid.fieldvalue.属性名= 错误信息

校验器

1、 校验的分类 : 客户端数据校验 和 服务器端数据校验

客户端数据校验 ,通过JavaScript 完成校验 (改善用户体验,使用户减少出错 )

服务器数据校验 ,使用框架内置校验功能 (struts2 内置校验功能 ) ----- 必须的

2、 struts2 支持校验方式

代码校验 :在服务器端通过编写java代码,完成数据校验

配置校验 :XML配置校验(主流) 和 注解配置校验

4、 XML配置方式 数据校验 (企业主流校验)

代码校验 不适用于大型项目, 流程数据复杂时,开发量和维护量 都会很大

xml配置校验原理 : 将很多校验规则代码已经写好,只需要在xml中定义数据所使用校验规则就可以了

步骤一 :编写jsp

步骤二 :编写Action 继承ActionSupport 或者 实现 Validateable 接口

步骤三 :封装请求参数

* 使用xml校验 必须提供get方法

步骤四 :编写校验规则xml文件

在Action所在包 编写 Action类名-validation.xml 对Action所有业务方法进行校验

引入DTD

------ xwork-core-2.3.7.jar 中 xwork-validator-1.0.3.dtd

<!DOCTYPE validators PUBLIC

"-//Apache Struts//XWork Validator 1.0.3//EN"

"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

内置校验器定义文件

xwork-core-2.3.7.jar 中 /com/opensymphony/xwork2/validator/validators/default.xml

内建校验器

* required (必填校验器,要求被校验的属性值不能为null)

* requiredstring (必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)

* stringlength (字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)

* regex (正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)

* int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)

* double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)

* fieldexpression (字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)

* email(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)

* url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)

* date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)

案例

required  必填校验器

<field-validator type="required">

<message>性别不能为空!</message>

</field-validator>

requiredstring  必填字符串校验器

<field-validator type="requiredstring">

<param name="trim">true</param>

<message>用户名不能为空!</message>

</field-validator>

stringlength:字符串长度校验器

<field-validator type="stringlength">

<param name="maxLength">10</param>

<param name="minLength">2</param>

<param name="trim">true</param>

<message><![CDATA[产品名称应在2-10个字符之间]]></message>

</field-validator>

int:整数校验器

<field-validator type="int">

<param name="min">1</param>

<param name="max">150</param>

<message>年龄必须在1-150之间</message>

</field-validator>

date: 日期校验器

<field-validator type="date">

<param name="min">1900-01-01</param>

<param name="max">2050-02-21</param>

<!-- OGNL表达式在配置文件中的写法-->

<message>生日必须在${min}到${max}之间</message>

</field-validator>

url:  网络路径校验器

<field-validator type="url">

<message>数据的主页地址必须是一个有效网址</message>

</field-validator>

email:邮件地址校验器

<field-validator type="email">

<message>电子邮件地址无效</message>

</field-validator>

regex:正则表达式校验器

<field-validator type="regex">

<param name="expression"><![CDATA[^13\d{9}$]]></param>

<message>手机号格式不正确!</message>

</field-validator>

fieldexpression : 字段表达式校验

<field-validator type="fieldexpression">

<param name="expression"><![CDATA[(password==repassword)]]></param>

<message>两次密码输入不一致</message>

</field-validator>

如何对指定的方法校验 ??? 格式  Action类名-ActionName(<action>元素name属性)-validation.xml

例如 : 校验AddCustomerAction中execute方法  配置 <action name="addcustomer" ...method="regist"/>

校验文件名字: AddCusotmerAction-addcustomer-validation.xml

 国际化信息显示

1、 国际化原理 ? 什么是国际化 ?

同一款软件 可以为不同用户,提供不同语言界面  ---- 国际化软件   internationalization  --i18n    本地化localization  l10n

需要一个语言资源包(很多properties文件,每个properties文件 针对一个国家或者语言 ,通过java程序根据来访者国家语言,自动读取不同properties文件 )

2、 资源包编写

properties文件命名 :  基本名称_语言(小写)_国家(大写).properties

例如 :

messages_zh_CN.properties 中文中国

messages_en_US.properties 英文美国

4、 struts2 框架国际化配置

第一种 全局国际化信息文件 (所有Action都可以使用 ) ------- 最常用

* properties文件可以在任何包中

* 需要在struts.xml 中配置全局信息文件位置

struts.xml

<constant name="struts.custom.i18n.resources" value="messages"></constant>   messages.properties 在src根目录

<constant name="struts.custom.i18n.resources" value="bao.resources.messages"></constant>   messages.properties 在 bao.resources 包

国际化信息

在Action中使用  : this.getText("msg");

在jsp中使用  :<s:text name="msg" />

在配置文件中(校验xml) : <message key="agemsg"></message>

 自定义拦截器

拦截器 的使用 ,源自Spring AOP(面向切面编程)思想

拦截器 采用 责任链 模式

*  在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。

*  责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行

在struts2 中可以定义很多个拦截器,将多个拦截器按照特定顺序 组成拦截器栈 (顺序调用 栈中的每一个拦截器 )

拦截器与拦截器栈的区别?

拦截器:<interceptor>   拦截器栈:<interceptor-stack>

从功能上看,拦截器栈本身就是一个功能更加强大的拦截器

从结构上看,拦截器栈是由多个拦截器有序组织在一起

配置一个拦截器:<interceptor>

拦截器栈:<interceptor-stack>

在栈中引入一个定义好的拦截器<interceptor-ref name=""/>

定义默认的拦截器栈:<default-interceptor-ref name=""/>

类的写法

1、 struts2 所有拦截器 都必须实现 Interceptor 接口

2、 AbstractInterceptor 类实现了 Interceptor 接口. 并为 init, destroy 提供了一个空白的实现

所有实际开发中,自定义拦截器 只需要 继承 AbstractInterceptor类, 提供 intercept 方法实现

3、 常用struts2 拦截器

<interceptor-ref name="modelDriven"/> 模型驱动

<interceptor-ref name="fileUpload"/> 文件上传

<interceptor-ref name="params"> 参数解析封装

<interceptor-ref name="conversionError"/> 类型转换错误

<interceptor-ref name="validation"> 请求参数校验

<interceptor-ref name="workflow"> 拦截跳转 input 视图

Oracle和MySQL 作为应用数据库区别

mysql存在数据库概念,在企业开发中,针对一个项目创建一个单独数据库,创建单独用户, 为用户授予数据库权限 ,

oracle 一个数据库就是一个服务,在这个库中可以存在很多用户,每个用户有单独表空间 ,针对一个项目,只需要创建一个用户

Struts2 框架 上传与下载

文件上传

1) 企业常用文件上传技术 : jspSmartUpload(主要应用 JSP model1 时代) 、 fileupload (Apache commons项目中一个组件)、 Servlet3.0 集成文件上传 Part类

2) 文件上传  enctype="multipart/form-data"  是 MIME协议定义多部分请求体 (消息体)

3) 上传页面编写

存在 <input type="file" name="upload"/> 上传项,必须提供name属性

表单提交方式 必须 post 提交

表单编码类型 enctype="multipart/form-data"

4) Struts2 对文件上传的支持

提供 FileUpload 拦截器,用于解析 multipart/form-data 编码格式请求,解析上传文件的内容

fileUpload拦截器 默认在 defaultStack 栈中, 默认会执行的

在Action需要对上传文件内容进行接收

页面:

<input type="file" name="upload" />

Action :

public class UploadAction extends ActionSupport {

// 接收上传内容

// <input type="file" name="upload" />

private File upload; // 这里变量名 和 页面表单元素 name 属性一致

private String uploadContentType;//MIME类型   image/jpeg  text/html

private String uploadFileName;

}

* 格式 : 上传表单项name属性 + ContentType 、 上传表单项name属性 + FileName

* 为三个对象 提供 setter 方法

通过FileUtils 提供 copyFile 进行文件复制,将上传文件 保存到服务器端

5) Struts2 上传文件过程中错误处理

配置 input 视图 ,作为上传出错后 跳转页面

在文件上传时,如果发生错误 ,fileUpload拦截器 会设置错误信息,workflow拦截器 跳转到 input 视图

通过 struts.multipart.maxSize 常量设置文件上传总大小限制

* struts.multipart.maxSize=2097152 默认上传文件总大小 2MB

* 超过文件总大小,跳转input 视图, 通过 <s:actionError /> 回显错误信息

在struts.xml 设置上传总大小

<constant name="struts.multipart.maxSize" value="20000000"></constant>

设置上传文件总大小,对所有上传form有效,只想对当前form进行设置,可以设置fileUpload拦截器属性

FileUpload 拦截器有 3 个属性可以设置.

* maximumSize: 上传文件的最大长度(以字节为单位), 默认值为 2 MB

* allowedTypes: 允许上传文件的类型, 各类型之间以逗号分隔  image/jpeg,text/html

* allowedExtensions: 允许上传文件扩展名, 各扩展名之间以逗号分隔

如果针对fileUpload 进行参数设置,当出错时,在页面通过 <s:fieldError /> 回显错误信息

文件下载

文件下载原理:

1.一个流  输出流

2.两个头  response.setHeader("Content-Type","application/octet-stream");

response.setHeader("Content-Disposition","attachment;filename=1.jpg");

1) struts2 完成文件下载,通过 结果集类型 (Result Type) stream 来完成的

struts-default.xml 定义 <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>

2) 使用Stream结果集 完成文件下载

文件下载原理: 服务器读取下载文件内容,通过Response响应流写回, 设置 ContentType、 ContentDisposition 头信息

public class StreamResult extends StrutsResultSupport {

protected String contentType = "text/plain"; // contentType头信息  (下载文件对应 MIME协议规定类型 )

* html --- text/html . txt--- text/plain

protected String contentDisposition = "inline"; // ContentDisposition头信息 (下载文件打开方式 inline浏览器内部打开, attachment 以附件形式打开)

protected String inputName = "inputStream";  // 需要Action中 提供 getInputStream 方法 返回 InputStream 提供下载文件 内容

}

Action 提供 InputStream  返回值 getInputStream 方法 ------- 指定下载文件流

配置 stream 结果集 参数 <param name="contentType">${contentType}</param> ---- 在Action 中提供 getContentType

*  ServletActionContext.getServletContext().getMimeType(filename);

配置 stream 结果集 参数 <param name="contentDisposition">attachment;filename=${filename}</param> ---- 在Action 提供 getFilename

* 下载附件名乱码问题 , IE和火狐 解决不同

public String encodeDownloadFilename(String filename, String agent)

throws IOException {

if (agent.contains("Firefox")) { // 火狐浏览器

filename = "=?UTF-8?B?"

+ new BASE64Encoder().encode(filename.getBytes("utf-8"))

+ "?=";

} else { // IE及其他浏览器

filename = URLEncoder.encode(filename, "utf-8");

}

return filename;

}

Struts2龙之总结的更多相关文章

  1. atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException

    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException #--现象 java.lang.NullPoint ...

  2. Struts2(五)

    以下内容是基于导入struts2-2.3.32.jar包来讲的 1.文件上传 A.单文件上传 <body> <form action="${pageContext.requ ...

  3. Atitit.struts2体系结构大总结

    Atitit.struts2体系结构大总结 1. 国际化与异常处理 2 2. 第5章 拦截器 2 3. 第7章 输入校验 2 4. 避免表单重复提交与等待页面 2 5. Struts 2对Ajax的支 ...

  4. atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31

    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerExceptionv2 q31 1. #--现象 java.lang. ...

  5. 知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I

    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerExceptionv2 q31 1. #--现象 java.lang. ...

  6. JavaWeb_(Struts2框架)拦截器interceptor

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  7. JavaWeb_(Struts2框架)Ognl小案例查询帖子

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  8. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  9. 菜鸟学Struts2——Interceptors

    昨天学习Struts2的Convention plugin,今天利用Convention plugin进行Interceptor学习,虽然是使用Convention plugin进行零配置开发,这只是 ...

随机推荐

  1. LeetCode OJ 152. Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  2. UVALive 6948 Jokewithpermutation 深搜

    题意就是把一段序列拆成从1到n的形式 一开始暴力了一下 后来发现bug太多一定是思路不对…… #include<stdio.h> #include<iostream> #inc ...

  3. Gentoo本地化设置--时区、时钟、字体、中文环境

    时区 你需要选择时区让系统知道你的地理位置,以保持正确的时间.在/usr/share/zoneinfo中查找你的时区.然后在/etc/conf.d/clock中设置时区.请忽略/usr/share/z ...

  4. NYOJ-1036 非洲小孩(贪心)

    非洲小孩 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 家住非洲的小孩,都很黑.为什么呢?第一,他们地处热带,太阳辐射严重.第二,他们不经常洗澡.(常年缺水,怎么洗 ...

  5. md5校验问题

    描述: 最近跟同事做数据对接,接收完数据,有个md5校验,发现总是对不上 首先把解密之后的明文直接写成变量在md5的工具类main函数执行,发现居然对上了, 然后测试环境debug接收的文件,md5加 ...

  6. HTML+CSS Day10实例

    1.家居大视野 效果图: 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...

  7. JPA 系列教程19-jpa-uuid主键生成策略

    ddl语句 CREATE TABLE `t_user` ( `id` varchar(32) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY K ...

  8. 在CentOS7部署zookeeper集群以及简单API使用

    一.部署zookeeper集群 zookeeper是一个针对大型分布式系统的协调系统,提供的功能有统一名称服务.分布式同步等. 1.上传zk安装包 2.解压     tar -xzvf zookeep ...

  9. hibernate在配置文件中配置对象关系映射文件即hbm文件路径的写法

    hbm文件如果在src下,则<mapping resource="*.hbm.xml"/> 如果在实体类包中,则<mapping resource="c ...

  10. MAC图片格式转换

    OS X下有一个sips的程序可以用来处理图片. sips的名称功能非常强大,参考 帮助文档 . 这里我们只用到其中的一个功能,转换图片格式. 命令参考: sips  - s format jpeg  ...