Introduction to Pop Framework

Download pop2.0.2.jar
View API online

How to create the model and the JSP view for a web page in Pop:

  1. Insert the pop2.0.2.jar and commons-logging.jar and log4j-1.2.15.jar into the lib directory of your web application.
  2. Create a servlet in your web application, which class is pop.mvc.MVCServlet. Please declare it in your web.xml file, and then set it as a welcome file.
  3. Create a class abc.def.MyModel1 which represents the model of a web page. And then use @BeanDef to annotate it:
    package abc.def; @BeanDef(value=MVCServlet.DEFAULT_BEAN, scope=PrototypeScope.class)
    public class MyModel1() {...}
  4. Create a JSP as the view for the web page. The JSP should be located at abc/def/MyModel1.jsp under your web content directory.
  5. Use <jsp:useBean name="model" type="abc.def.MyModel1"> in MyModel1.jsp to bind the model with the view.
  6. In the JSP file, please use the Java variable model to referent the model object
  7. Run the web application, you may find that the abc/def/MyModel1.jsp is loaded automatically, and the no-arg constructor of the class MyModel1 is invoked automatically to construct a page model-object. The model object is bound to the JSP through the <jsp:useBean> declaration, as a result, the JSP can show the model object properly.
  8. You can use @BeanDef to annotate a class or a constructor or a static method. In fact, annotating a class is same to use @BeanDef to annotate its no-arg constructor.

How to create hyperlink between two web pages:

  1. Suppose we have created the views and the models for abc.def.MyModel1 and abc.def.MyModel2, and now we want to create a hyperlink from MyModel1 to MyModel2
  2. Open the class abc.def.MyModel2
  3. Create a constructor (or a static method) and then use @BeanDef to annotate it:
    @BeanDef(value="link1", scope=PrototypeScope.class)
    public MyModel2() {...}

    or
    @BeanDef(value="link1", scope=PrototypeScope.class)
    public static MyModel2 myLinkToModel2() {...}

  4. In JSP abc/def/MyModel1.jsp, define an anchor (<a>):
    <a href="?beanName=link1">Click Me</a>

    or define a <form>:
    <form action="">
        <input type="hidden" name="beanName" value="link1"/>
        <input type="submit" value="Click Me"/>
    </form>
  5. Run the web application. When user clicks the 'Click Me' anchor or button, the corresponding constructor or static method will be invoked to generate a model of type abc.def.MyModel2. The view abc/def/MyModel2.jsp of the model will be rendered to client side.
  6. Please note:

How to transfer parameters along with a hyperlink:

  1. In JSP abc/def/MyModel1.jsp, define a <form>:
    <form action="">
        <input type="hidden" name="beanName" value="link1"/>
        <input name="p1" value="a string value"/>
        <input name="p2" value="3456"/>
        <input type="submit"/>
    </form>

    The parameters p1 and p2 will be transfered to the back end.
  2. Use @BeanDef to annotate a static method (or a constructor), and then define two parameters:
    @BeanDef(value="link1", scope=PrototypeScope.class)
    public static MyModel2 myLinkToModel2(@Param("p1") String param1, @Param("p2") int param2) {...}
  3. Please note:

How to transfer many parameters:

@Param can be used to convert and transfer only one parameter. If the JSP needs to transfer a lot of parameters, @Param is inconvenience. Please use ParamObject instead:

  1. Define a normal Java class which contains all the input-parameters as properties:
    public class InputParams {
        private int p1;
        private double p2;
        private char p3;
        ...

        public void setP1(int p1) {...}
        public void setP2(double p2) {...}
        public void setP3(char p3) {...}
        ...
    }
  2. When defining a bean, please declare a parameter of InputParams and then use @ParamObject to annotate it:
    @BeanDef(value="link1", scope=PrototypeScope.class)
    public static MyModel2 myLinkToModel2(@ParamObject InputParams params) {...}
  3. When the bean is referenced, the names of the properties of the InputParams are used to search the values from the input parameters. The type of the property is used to convert the string value. The property is ignored if the corresponding string-value is null. By this way, many values can be set into a single object.
  4. When using @Param, the value attribute is mandatory. When using @ParamObject, however, you needn't to declare a name.

How to transfer beans:

Not only @Param and @ParamObject, but also @BeanRef can be used to annotate a parameter of a bean. So that another bean can be referenced when the current bean is generated. Here is an example:

@BeanDef(value="link1", scope=PrototypeScope.class)
public static MyModel2 myLinkToModel2(@ParamObject InputParams params, @Param("p6") float param6, @BeanRef MyBeanType beanParam) {...}

For more details, please refer to the next section.

How to create services (or business logics) in Pop:

  1. You have three ways to declare a bean in Pop:
  2. If the parameter list of the method or the constructor is not empty, you can use @BeanRef to annotate a parameter so that to referent a bean. That means when the method or the constructor is invoked, the parameter will be filled by the bean. For example:
    @BeanDef
    public static BeanA myMethod(
            @BeanRef MyClass1 p1,
            @BeanRef("abc") MyClass2 p2,
            @BeanRef(types=MyInterface2.class) MyClass2 p2,
            @BeanRef(value="def", types=MyInterface3.class) MyClass3[] p3)

    That means, before the BeanCenter invokes the method, the 1st parameter will be filled by a bean which type is MyClass1.
    The 2nd parameter will be filled by the bean which value is "abc" and which type is MyClass2.
    The 3rd parameter will be filled by the bean which type is MyInterface3.
    The 4th parameter will be filled by the bean which name is "def" and which type is MyInterface3.
    The found bean must be single. If there are zero or multiple beans found for a parameter, an exception will be thrown.
  3. There are 3 attributes for a @BeanDef:
  4. You can define the scope for a bean. for example:
    @BeanDef(scope=PrototypeScope.class)
    The scope attribute of a @BeanDef annotation must be an implementation of Scope The predefined Scope implementations are:
  5. You have three ways to referent a bean (or say, to implement Dependency Injection or Inversion Of Control):
  6. Normally, you are encouraged to implement an interface in the class of a bean, and then use that interface when referencing the bean through @BeanRef. This can help you to build an extendible web application with high maintainability. For example, when you change the bean implementation from the old class to a new one, you needn't to change the type of the corresponding references.
    Moreover, when using the AOP feature of Pop described in the below sections, the interface of a bean is mandatory.

How to customize a view:

Be default, MVCServlet uses the package name of the model to locate the JSP file. For example, the JSP file for model abc.def.MyModel1 is located at abc/def/MyModel.jsp under the web content directory of the web application. If you want to custome the way to find the view for a model, please follow the steps shown in below.

  1. There are two ways for you to define a view for a type of models, these two ways are corresponding to the two ways to create a prototype bean: Here is an example:
    @ViewDef
    public class MyView implements View<MyModelType> {
        ...
    }
  2. The categories attribute of an @ViewDef is used to distinguish different categories of views. The default categories attribute is stored in the constant HTML_PAGE, which is used by all views targeted at normal HTML pages. If you want to build views for IPhone, for example, you need to set all the categories attributes to a same constant, for example, IPHONE.
    It is possible for a model has multiple views in different categories.
  3. If you want to define a view for multiple model types, or if the target model type is different to the type of the bean, you can set the modelTypes attribute of a @ViewDef to the expected model types. If the modelTypes attribute is not defined, the type parameter T of bean implementing the interface View must be a concrete model type. Because otherwise the Pop doesn't know how to find the model for which the view is defined.
  4. For your convenience, Pop predefined some of the implementations for View:

How to create and use AOP(Aspect-Oriented Programming) in Pop:

  1. Build a class to implement AOP. AOPAdapter can help to finish this task.
  2. Call BeanCenter.setAOP(AOP) method to set the AOP object into a bean center. To get a bean center, you either can call its constructor or call the BeanCenterServlet.getBeanCenter() method.
  3. AOP is available only for those beans that implements at least one non-empty interface. When one method of the interface(s) is called over the bean, the AOP takes effects. As a result, Pop suggests you to use an interface to referent a bean even there is no AOP used.
  4. For your convenience, Pop provides some of the predefined implementations for AOP, such as AOPAdapter and DBTransactionAOP.
  5. Normally, an AOP is available for all interfaces of all beans in a BeanCenter. If you want to change this, please implements Judge interface and then call BeanCenter.setJudge(Judge) method to set the Judge object into a BeanCenter.

pop2.0.2.jar   API