Action处理请求参数

时间:2023-03-08 20:34:15

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

第一种方式:<br>
<form action="${pageContext.request.contextPath}/MyAction1" method="post">
  username:<input type="text" name="username"><br>
  password:<input type="password" name="password"><br>
  <input type="submit"><hr>
</form>
public class MyAction1 extends ActionSupport{
private String username;
private String password;
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public String execute() throws Exception {
System.out.println(username+" "+password);
return null;
}
}

  问题: Action封装数据,会不会有线程问题 ?
    struts2 Action 是多实例 ,为了在Action封装数据 (struts1 Action 是单例的 )

  缺点:需要单独定义javaBean,将action中属性copy到javaBean中。
  优点:简单。

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

第二种方式:<br>
<form action="${pageContext.request.contextPath}/MyAction2" method="post">
username:<input type="text" name="user.username"><br>
password:<input type="password" name="user.password"><br>
<input type="submit"><hr>
</form>
public class MyAction2 extends ActionSupport{
private User user;
public void setUser(User user) {
this.user = user;
}
public User getUser() {//不写这个密码获取不到?不懂..希望知道的人留言告知,感谢
return user;
}
public String execute() throws Exception {
System.out.println(user.getUsername()+" "+user.getPassword());
return null;
}
}

  问题: 谁来完成的参数封装
    <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

  优点:简单,解决了第一种封装的问题
  缺点:在页面上使用了ognl表达式,页面不通用了

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

 第三种方式:<br>
<form action="${pageContext.request.contextPath}/MyAction3" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
<input type="submit"><hr>
</form>
public class MyAction3 extends ActionSupport implements ModelDriven<User>{
private User user=new User();
public String execute() throws Exception {
System.out.println(user.getUsername()+" "+user.getPassword());
return null;
}
@Override
public User getModel() {
return user;
}
}

  优点:解决了属性驱动存在的问题
  缺点:一次只能封装一个model对象.

  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" />
 public class StrutsFilter implements Filter {

     public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// 1.强转
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 2.操作
// 2.1 得到请求资源路径
String uri = request.getRequestURI();
String contextPath = request.getContextPath();
String path = uri.substring(contextPath.length() + 1);
// 2.2 使用path去struts.xml文件中查找某一个<action name=path>这个标签
SAXReader reader = new SAXReader();
try {
// 得到struts.xml文件的document对象。
Document document = reader.read(new File(this.getClass().getResource("/struts.xml").getPath()));
Element actionElement = (Element) document
.selectSingleNode("//action[@name='" + path + "']"); // 查找<action
// name='hello'>这样的标签
if (actionElement != null) {
// 得到<action>标签上的class属性以及method属性
String className = actionElement.attributeValue("class"); // 得到了action类的名称
String methodName = actionElement.attributeValue("method");// 得到action类中的方法名称。
// 2.3通过反射,得到Class对象,得到Method对象
Class actionClass = Class.forName(className);
Method method = actionClass.getDeclaredMethod(methodName); // 处理请求参数封装:
Object actionObj = actionClass.newInstance();
// 模型驱动
if (actionObj instanceof MyModelDriven) {
MyModelDriven mmd = (MyModelDriven) actionObj;
BeanUtils.populate(mmd.getModel(),request.getParameterMap());
} else {
// 属性驱动
BeanUtils.populate(actionObj, request.getParameterMap());//
}
// 2.4 让method执行.
String returnValue = (String) method.invoke(actionObj); // 是让action类中的方法执行,并获取方法的返回值。 // 2.5
// 使用returnValue去action下查找其子元素result的name属性值,与returnValue做对比。
Element resultElement = actionElement.element("result");
String nameValue = resultElement.attributeValue("name");
if (returnValue.equals(nameValue)) {
// 2.6得到了要跳转的路径。
String skipPath = resultElement.getText();
request.getRequestDispatcher(skipPath).forward(request,response);
return;
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 3.放行
chain.doFilter(request, response);
}
public void destroy() {}
}

模拟Struts2属性驱动和模型驱动

 public interface MyModelDriven<T> {
public T getModel();
}

MyModelDriven

封装数据到Collection和Map
  1) 封装数据到Collection 对象

 第四种方式(list):<br>
<form action="${pageContext.request.contextPath}/MyAction4" method="post">
username:<input type="text" name="users[0].username"><br>
password:<input type="password" name="users[0].password"><br>
username:<input type="text" name="users[1].username"><br>
password:<input type="password" name="users[1].password"><br>
<input type="submit"><hr>
</form>
public class MyAction4 extends ActionSupport{
private List<User>users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public String execute() throws Exception {
System.out.println(users);
return null;
}
}

  2) 封装数据到Map 对象

 第五种方式(map):<br>
<form action="${pageContext.request.contextPath}/MyAction5" method="post">
username:<input type="text" name="users['zs'].username"><br>
password:<input type="password" name="users['zs'].password"><br>
username:<input type="text" name="users['ls'].username"><br>
password:<input type="password" name="users['ls'].password"><br>
<input type="submit"><hr>
</form>
public class MyAction5 extends ActionSupport{
private Map<String, User>users;
public Map<String, User> getUsers() {
return users;
}
public void setUsers(Map<String, User> users) {
this.users = users;
}
public String execute() throws Exception {
System.out.println(users);
return null;
}
}