我正在使用Struts 1开发一个Java库项目(我知道它已经很老了,但这是一个学校项目)。
我创建了一个DispatchAction来处理使用 op 参数的不同方法的书籍请求(添加,编辑,删除)。
add方法运行正常,因为它的网址类似于/book.do?op=add,但是编辑在动态网址上存在概念性问题,例如book.do?op=edit&id=1:
如果验证发现了一些错误,那么该动作如何知道在哪里 重定向? input属性是静态的,但发送请求的页面有一个动态URL。
我的struts-config.xml中有这个:
<!-- Base Book Action -->
<action path="/book" type="com.github.jcpp.jathenaeum.actions.BookAction" parameter="op">
<forward name="add" path="page.addBook"/>
<forward name="edit" path="page.editBook"/>
<forward name="delete" path="page.deleteBook"/>
<forward name="viewAll" path="page.viewAllBooks"/>
<forward name="noAuthors" path="page.noAuthors" />
</action>
<!-- Action Book -->
<action
path="/doBook"
type="com.github.jcpp.jathenaeum.actions.BookActionDo"
name="bookForm"
scope="request"
validate="true"
parameter="op">
<forward name="add" path="page.confirmBookInsert"/>
<forward name="edit" path="page.confirmBookInsert"/>
<forward name="success" path="page.confirmBookInsert"/>
<forward name="failed" path="page.failedBookInsert"/>
</action>
我想知道的是:这是做这种事情的最好方法吗?或者有更简单的方法可以做到这一点?
我可以动态设置输入属性的值吗?
如果您愿意,可以在GitHub上查看整个项目代码:https://github.com/JCPP/JAthenaeum
更新1
我的问题是在验证后重定向到这样的动态网址:book.do?op=edit&id=1。您可以更改的书可以具有不同的ID(29,50,49)。在这种情况下,输入属性很窄。
由于
答案 0 :(得分:1)
我认为您不能动态更改input属性的值。
提交表单并验证失败后,会将其重定向到"input"
属性中定义的页面。
我认为不需要动态更改“input”属性。验证失败时,您可以将其重定向回用户输入数据的同一页面,并显示错误消息,显示无效字段。
当您输入无效数据时,您可以在网站的任何“注册/登录”页面中看到此类行为。
修改强>
这是一个解决方法。在映射文件中设置validate="false"
。并从您的操作类调用验证方法。
您还可以更改validate方法的返回类型以满足您的需要(例如,对于字符串)。
因此,在您的操作类中,取决于validate方法返回的值,您可以创建不同的URL并将其转发到那里:
public class MyAction extends DispatchAction{
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response,
ActionMessages messages) throws Exception
MyForm myForm = (MyForm) form;
String url="";
String result = form.validate();
if(result.equals("something")){
url="book.do?op=add&id=" + book.getId();
}else if(result.equals("somethingElse"){
url="book.do?op=edit&id=" + book.getId();
}
RequestDispatcher rd = request.getSession().getServletContext().getRequestDispatcher(url);
rd.forward(request, response);
}
答案 1 :(得分:1)
有一些事情需要设定。首先要做的事情。
在 BookAction 中,应用程序将显示表单,而在 BookActionDo 中,它将更新数据库中的图书。
<!-- Book -->
<action path="/book" type="com.github.jcpp.jathenaeum.actions.BookAction" parameter="op">
<forward name="edit" path="page.book.edit"/>
</action>
<!-- Book Operations -->
<action
path="/doBook"
type="com.github.jcpp.jathenaeum.actions.BookActionDo"
name="bookForm"
scope="request"
validate="false"
parameter="op">
<!-- Edit-->
<forward name="editErrors" path="/book.do?op=edit" redirect="true"/>
<forward name="editSuccess" path="page.book.edit.confirm" />
<forward name="editFailed" path="page.book.edit.failed" />
这里告诉struts不要使用validate="false"
验证表单。
public class BookActionDo extends DispatchAction {
public ActionForward edit(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String actionTarget = null;
HttpSession session = request.getSession();
Book book = new Book();
BookForm uf = (BookForm) form;
//Check the id
if(!uf.validateId(mapping, request).isEmpty()){
actionTarget = "invalidId";
ActionRedirect redirect = new ActionRedirect(mapping.findForward(actionTarget));
return redirect;
}
ActionErrors actionErrors = uf.validate(mapping, request);
int id = Integer.parseInt(request.getParameter("id"));
//If there are some errors, redirect to the form page
if(!actionErrors.isEmpty()){
actionTarget = "editErrors";
session.setAttribute("errors", actionErrors);
session.setAttribute("form", uf);
ActionRedirect redirect = new ActionRedirect(mapping.findForward(actionTarget));
redirect.addParameter("id", Integer.toString(id));
return redirect;
}
if(form != null){
book = new Book(uf);
book.setId(id);
try{
int bookId = (int) BookDAO.update(book);
}catch(Exception e){
actionTarget = "editFailed";
}
}
return mapping.findForward(actionTarget);
}
}
此处它检查表单的验证是否返回一些ActionErrors
。如果是,则使用ActionRedirect
参数创建id
,否则会尝试更新图书。
因此,当它创建网址时,ActionRedirect
会重定向到:/book.do?op=edit&id=<book_id>
。