Struts2 ( 二 )

Result结果配置

全局结果

package标签中配置global-results标签java

<package name="xxx" namespace="/" extends="struts-default">
	<global-results>
		<result name="xxx">xxx.jsp</result>
	</global-results>
</package>

做用是为package中配置的全部action提供全局的返回结果页面web

局部结果

action标签中配置result标签json

<action name="xxx" method="xxx"
	class="xxx">
	<result>xxx.jsp</result>
</action>

做用是为当前action配置结果页面缓存

结果类型

结果类型是在父类配置struts-default中定义的,struts框架默认实现了绝大多数的。
经常使用的结果类型有:服务器

  1. dispatcher:转发。为result标签的默认值。app

    <result type="dispatcher">xxx.jsp</result>

    由action转发到jsp。框架

    result标签中配置的结果必须是jsp页面jsp

  2. chain:转发。ide

    <result type="chain">
    	<param name="actionName">xxx.action</param>
    </result>

    由action转发到action。函数

    result标签中配置的结果必须是action

  3. redirect:重定向。

    <result type="redirect">
    	<param name="location">xxx.jsp</param>
    </result>

    由action重定向到jsp。

    result标签中配置的结果必须是jsp页面

  4. redirectAction:重定向。

    <result type="redirectAction">
    	<param name="actionName">xxx.action</param>
    </result>

    由action重定向到action。

    result标签中配置的结果必须是action

  5. stream: 结果为文件流。文件下载

    <result name="success" type="stream">
    	<param name="contentType">image/jpeg</param>
    	<param name="inputName">imageStream</param>
    	<param name="contentDisposition">attachment;filename="document.pdf"</param>
    	<param name="bufferSize">1024</param>
    </result>

    contentType:下载文件类型

    contentDisposition:下载到客户端时,客户端文件名称

    bufferSize:读文件的缓存大小

    inputName:对应要输出到客户端流声明的名称

  6. json:转发。

    <package name="xxx" namespace="/xxx" extends="json-default">
    	<action name="json" method="xxx"
    		class="org.itpx.struts.action.JsonAction">
    		<result name="success" type="json">
    			<param name="encoding">utf-8</param>
    			<param name="root">jsonObject</param>
    		</result>
    	</action>	
    </package>

    由action转发到json结果

    encoding:配置编码格式

    root:配置对象。action类中必须提供一个和root值相同的属性名称,且须要提供getter方法。

  7. jsonActionRedirect: 重定向。

    <action name="xxx" method="xxx"
    		class="org.ithpx.struts.action.JsonAction">
    		<result name="success" type="jsonActionRedirect">
    			xxx.action
    		</result>
    </action>

    由action重定向到json结果。

json Plugin的加载

  1. 拷贝struts2-json-plugin-xxx.jar
  2. 让package继承json-default

Struts与Servlet交互对接

解决的问题

客户端与服务端交互时,一般会带参数过来,服务器也会回写数据给客户端。在此过程当中,参与着请求,和响应,以及会话。servlet在此过程当中提供了HttpServletRequest做为获取请求数据的方案,HttpServletResponse做为响应的方案,HttpSession负责了会话方案。Struts实际上是基于servlet实现的web框架,他须要遵循规则提供请求,响应和会话的API供开发人员使用,所以Struts针对这一问题提供了本身的一套API封装,提供了多种方式的访问。

ActionContext

  1. ActionContext对象实例获取

    ActionContext context = ActionContext.getContext();

    ActionContext是绑定在当前线程中的。框架在请求线程开启时,将ActionContext实例对象就绑定上来了,所以咱们能够经过静态方法直接获取

  2. 请求参数的得到

    Map<String, Object> parameters = context.getParamters();

    至关于Servlet中的request.getParamters()方法

  3. 数据回显到页面

    context.put(key, value);

    至关于Servlet中的request.setAttribute()方法

ServletActionContext

  1. Servlet继承子ActionContext,所以具有ActionContext的一切功能。
  2. ServletActionContext是对ActionContext功能的扩展,提供了多个静态方法。
  3. 请求得到
    HttpServletRequest request = ServletActionContext.getRequest();
  4. 响应得到
    HttpServletResponse response = ServletActionContext.getResponse();

接口实现类得到

  • ServletContextAware
  • ServletRequestAware
  • ServletResponseAware
  • ParameterAware
  • SessionAware
  • ApplicationAware
  • PrincipalAware

Struts数据的封装

静态参数封装

  1. 页面表单
    <input type="text" name="name">
    <input type="text" name="password">
  2. action标签中配置param标签
    <param name="name" />
    <param name="password" />
  3. action类
    private String name;
    private String password;
    public void setName(String name) {
    this.name = name;
    }
    public void setPassword(String password) {
    this.password = password;
    }
    1. 要求页面表单中的key和param标签中name一致
    2. 要求页面表单中的key和aciotn类中的属性名一致
    3. action类中的属性须要提供setter方法

属性驱动:基本数据类型封装

  1. 页面表单
    <input type="text" name="name">
    <input type="text" name="password">
  2. action类
    private String name;
    private String password;
    public void setName(String name) {
    this.name = name;
    }
    public void setPassword(String password) {
    this.password = password;
    }
    1. 要求页面中提供的key和action类中属性名称必须一致
    2. action类中必须提供属性的setter方法

页面表达式:对象封装

  1. 页面表单
    <input type="text" name="user.name">
    <input type="text" name="user.password">
  2. action类
    private User user;
    public void setUser(User user) {
    this.user = user;
    }
    public User getUser() {
    return user;
    }
    1. 页面中的key至关于对象.属性
    2. action中的对象名称须要要和页面中key的对象名称相同
    3. action中的对象中的属性名称要和页面中key的对象的属性相同
    4. action中的对象必须提供无参构造函数
    5. action中的对象必须提供getter和setter

模型驱动:对象封装

  1. 页面表单
    <input type="text" name="name">
    <input type="text" name="password">
  2. Aciton类须要实现ModelDriven接口,而且实现接口方法
    public class Action03 extends ActionSupport implements ModelDriven<User> {
    private User user;
    @Override
    public User getModel() {
    	if (user == null) {
    		user = new User();
    	}
    	return user;
    }
    }

    页面中的key的名称须要和模型对象的名称一致

List数据

  1. 页面表单
    <input type="text" name="list[0].name">
    <input type="text" name="list[0].age">
    <input type="text" name="list[1].name">
    <input type="text" name="list[1].age">
  2. action类
    public class DataAction05 extends ActionSupport {
    	private List<User> list;
    	public List<User> getList() {
    		return list;
    	}
    	public void setList(List<User> list) {
    		this.list = list;
    	}
    	public String test() {
    		System.out.println(list);
    		return SUCCESS;
    	}
    }

Map数据

  1. 页面表单
    <input type="text" name="map['a'].name">
    <input type="text" name="map['a'].age">
    <input type="text" name="map['b'].name">
    <input type="text" name="map['b'].age">
  2. action类
    public class DataAction05 extends ActionSupport {
    	private Map<String, User> map;
    	public Map<String, User> getMap() {
    		return map;
    	}
    	public void setMap(Map<String, User> map) {
    		this.map = map;
    	}
    }

类型转换器

解决的问题

客户端传输过程当中传输特定类型的字符串时,到action类中须要转换为对应的对象时,中间的转换的问题。
主要解决的是对象类型的转换

配置方案

  1. 新建一个类继承StrutsTypeConverter,实现内部方法
    public class DateConversion extends StrutsTypeConverter {
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
    	if (values != null && values.length > 0) {
    		String dateString = values[0];
    		try {
    			return sdf.parse(dateString);
    		} catch (ParseException e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    	return null;
    }
    @Override
    public String convertToString(Map context, Object o) {
    	if (o != null && o instanceof Date) {
    		return sdf.format(o);
    	}
    	return null;
    }
    }
  2. 在项目的src下新建xwork-conversion.properties,在其中配置要转换的类型
    java.util.Date=org.itheima.struts.action.DateConversion

UnknowHandler未知处理器

解决的问题

UnknowHandler未知处理器是用来解决,用请求未知Action,或指定action里的未知方法,或者action处理结束以后返回一个未知result时,没有结果等状况的

UnknownHandler接口

接口提供了三个方法要求子类实现。

  • handleUnknownAction:当用户请求了未知的action时的回调。
  • handleUnknownActionMethod: 当用户请求了Action中未知方法的回调。目前被废弃了
  • handleUnKnownResult: 当action处理结束后返回未知result的回调。

使用步骤

  1. 新建一个类实现UnknowHandler接口
  2. 根据需求实现接口中的方法
    • handleUnknownAction内部实现

      String newNamespace = "/unknow";
      String newActionName = "test";
      ConfigurationManager cfgManager = Dispatcher.getInstance().getConfigurationManager();
      RuntimeConfiguration runtimeCfg = cfgManager.getConfiguration().getRuntimeConfiguration();
      ActionConfig actionConfig = runtimeCfg.getActionConfig(newNamespace, newActionName);
      return actionConfig;

      若是没有找到请求的action,经过此方法转到配置的新的action中。

      所以,须要在配置中配置一个新的action。

    • handleUnKnownResult内部实现

      String location = "/unknowresult.jsp";
      return new ServletDispatcherResult(location);

      若是action处理了,结果为为未知类型。
      出问题的基本都是开发人员在开发过程当中的编码不仔细的问题。
      此类问题开发阶段就要被扼杀。

  3. struts.xml中用bean标签配置加载此实现的对象

    <bean name="handler" type="com.opensymphony.xwork2.UnknownHandler"
    	class="org.itheima.struts.handler.MyunkownHandler"></bean>
  4. 新建unkown-hanlder-ref标签注册此bean
    <unknown-handler-stack>
    	<unknown-handler-ref name="handler" />
    </unknown-handler-stack>

Exception捕获

解决的问题

当action代码执行中出现异常时,错误信息会反馈到客户页面,用户体验很差

局部异常捕获

  • action标签中配置exception-mapping标签
    1
    2
    3<result name="xxx" type="redirect">/xxx.jsp</result>
    <exception-mapping result="xxx"
    exception="java.lang.Throwable" />
  • exception-mapping标签中的result属性指向捕获异常后出错的页面结果。
  • exception-mapping标签中的exception属性指的是要捕获那种异常。

全局异常捕获

  • package标签中配置global-exception-mapping标签
    <global-results>
    	<result name="xxx">xxx.jsp</result>
    </global-results>
    <global-exception-mappings>
    	<exception-mapping result="xxx"
    			exception="java.lang.Throwable">
    	</exception-mapping>
    </global-exception-mappings>
  • global-exception-mapping标签中的result属性指向捕获异常后出错的页面结果。
  • global-exception-mapping标签中的exception属性指的是要捕获那种异常。

异常显示

异常捕获的做用是为了提示用户界面的显示结果,但若是出错了,开发人员是要知道错误日志的。

若是要开启错误日志,在action标签中配置以下:

<interceptor-ref name="defaultStack">
	<param name="exception.logEnabled">true</param>
	<param name="exception.logLevel">error</param>
</interceptor-ref>
相关文章
相关标签/搜索