Search code examples
javastrutsstruts-1

Struts 1 dynamically set the input attribute of the action


I'm developing a Java Library project with Struts 1 (I know it is old, but this is a school project).

I created a DispatchAction to handle the Book requests for different methods (add, edit, delete) with op parameter.

The add method works fine because it has url like /book.do?op=add , but edit has a conceptual problem with a dynamic url like book.do?op=edit&id=1 :

if the validation find some errors, how can the action know where redirect? The input attribute is static, but the page that sends the request has a dynamic url.

I have this in my 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>

What I want to know is: this is the best way to do this kind of thing? Or there are simpler ways to do it?

Can I set the value of the input attribute in a dynamic way?

If you want you can check the entire project code on GitHub: https://github.com/JCPP/JAthenaeum

UPDATE 1

My problem is to redirect to a dynamic url like this: book.do?op=edit&id=1, after validation. The book that you can change can has a different id (29, 50, 49). The input attribute in this case is narrow.

Thanks


Solution

  • There are some things to set. First things first.

    Struts-config

    In BookAction the application will show the form, while in BookActionDo it will update the book in the database.

    <!-- 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" />
    

    Here it tells to struts to not validate the form with validate="false".

    Actions

    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);
     }
    }
    

    Here it checks if validate of the form returns some ActionErrors. If yes it create an ActionRedirect with the id parameter, otherwise it tries to update the book.

    So when it creates the url, ActionRedirect will redirect to: /book.do?op=edit&id=<book_id>.