- SSH框架的合成及GiuHub源码详见另一篇博客:搭建SSH框架
1. Struts2学习:
1-1. 搭建Struts2框架:
1)新建Web项目,导入Struts2运行的类库(Struts2.5以后xwork-core.jar集成到struts-core.jar中,不用导入)-->Build Configuration Path关联类库。
2)在web.xml中配置核心过滤器:
</web-app>
......
<!-- 配置核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3)创建控制器struts.xml(<!DOC…>里面的内容不能缺失,否则报错):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="struts" extends="struts-default">
<action name="register" class="day01.RegisterAction">
<result name="success">/day01/register_success.jsp</result>
<result name="error">/day01/register_error.jsp</result>
</action>
</package>
</struts>
4)构造 jsp页面、action类。
5)出现的问题解决方案:
- java.lang.NoClassDefFoundError: Lorg/apache/logging/log4j/Logger解决办法:https://blog.csdn.net/Ricardo_MLi/article/details/72748256
- There is no Action mapped for namespace / and action name解决办法:https://blog.csdn.net/dhaoxiansheng/article/details/54585243
1-2. Struts数据交互:
1)JSP将数据传递给Action类的两种方式:
- 直接传递对应的属性给Action类(属性名必须一一对应);
- jsp传递给Action的实体类,Action再从实体类中取出相应的数据进行操作,从而实现底层业务与逻辑处理的分离开发。
//在jsp提交页面的定义:
<input type = "text" name = "manager.username" />
<input type ="password" name = "manager.password" />
//Manager是一个实体类,包含jsp页面传过来的属性的定义
//在Action类中,主要代码逻辑如下:
private Manager manager;
public void setManager(Manager manager){
this.manager = manager;
}
public Manager getManager(){
return this.manager;
}
System.out.println(this.manager.getUsername() + " " + this.manager.getPassword() );
2)Action将数据传递给JSP页面
- 通过在Action处理调用Service层,Service层再调用DAO层获取数据;
- 将Action类获取的数据封装成List转发给JSP页面;
- JSP页面通过JSTL和EL表达式将获取的封装的数据进行显示。
3)Action调用servlet的API保存信息
- 例:保存用户信息:
//1.在Action的execute()方法里面保存jsp页面的信息供后续使用
//1-1 通过上下文获取信息
Map<String,Object> session = ActionContext.getContext().getSession();
session.put("username", username);
//1-2 或者通过request(response、cookie的获取方式相同)保存信息,作用范围不同的区别
//获取request对象的MAP
Map<String,Object> request = (Map<String, Object>) ActionContext.getContext().get("request");
//将用户名保存到request对象的MAP中
request.put("username", username);
//2. 在jsp页面中通过EL表达式调用session / ... 中的信息
${sessionScope.username} / ${username}
- 类似于通过Servlet调用API保存信息再转发:
@WebServlet("/login.action") //相当于struts.xml定义的action
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.....
//创建session域对象,把user信息存储到session里面
request.getSession().setAttribute("session_user", user);
//携带用户名的值跳转到首页
request.getRequestDispatcher("index.action").forward(request, response);
.....
}
- 另一种方式是通过ServletActionContext同样获取,但其耦合性比较高,不推荐使用。
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
1.3 Struts2.xml文件的配置
1)配置说明:
<result name="success" type=" ">/day01/register_success.jsp</result>
<result name="error" type=" ">/day01/register_error.jsp</result>
- name 对应的是从Action返回的信息字符串;
- < result >value< /result >的value指向请求转发的路径;
- type默认情况下是dispatcher,类似于Servlet中的请求转发:request.getRequestDispatcher("/xxx.jsp / xxx.action").forward(request,response),数据可以通过request转发,但是它们的路径没有发生改变;
- 当type = " redirect"时,表示该请求方式是重定向,数据不会通过request转发,路径发生了改变。
关于请求转发与重定向:https://blog.csdn.net/meiyalei/article/details/2129120
2)配置文件学习说明 1 :
规范化包的存放,其中namespace指定访问的路径,可不指定该属性,访问时路径名应指定namespace:…/admin/userlist.action
3)配置文件学习说明 2 之动态方法调用:
动态调用Action里面的方法,实现代码重用,逻辑分离
-
在Action类里面添加实现的方法,返回值为String类型
-
在struts.xml配置文件中修改默认的动态调用值为 true,定义action的name(不能一样),class,method以及返回的处理结果result的跳转页面。
-
访问路径:·····/namespace/actionName ! methodName.action
4) struts通配符的使用:struts通配符的使用应该提前约定好,避免出现用法的差异造成代码混乱,struts通配符的使用能减少action的定义,减少struts.xml中代码的冗余。
- 配置通配符
- 前端访问实例:
- 访问地址:向访问哪个方法就直接加哪个方法。
5)struts中默认的action配置【注意对应包的namespace】
6)struts中的常量配置- 页面乱码的配置:在后台数据提交给客户端的时候经常出现页面乱码的问题,可以每次在action里面进行转码
request.setCharacterEncoding("UTF-8")
;但比较麻烦,因此可以在控制器struts.xml做常量配置,实现一次配置多页面使用的效果:<contant name="struts.i18n.encoding" value="UTF-8" />
- 动态调用的配置:如在struts中配合通配符使用时应该设置动态调用属性:
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
- 调试模式的配置:设置调试模式,当页面或者服务器出现错误时,错误会显示在页面,方便开发的调试,亦称开发者模式:
<constant name="struts.devMode" value="true" />
- web容器自动重新加载的配置:当修改struts.xml配置文件时,没必要每次都重新启动服务器,此时需要设置reload常量配置:
<constant name="struts.configuration.xml.reload" value="true" />
- 页面乱码的配置:在后台数据提交给客户端的时候经常出现页面乱码的问题,可以每次在action里面进行转码
1.4 代理模式:
1)代理模式的使用有利于实现主体功能扩展,而代理角色对象不需要改变的情况,达到功能与实现的降耦合的优点:
2)动态代理模式:动态生成代理对象&#x