Skip to content
This repository has been archived by the owner on Jan 9, 2021. It is now read-only.

YMP框架快速搭建手册

suninformation edited this page Aug 7, 2014 · 5 revisions

框架快速搭建手册

本手册将阐述如下内容:

  • 如何基于YMP框架搭建WEB应用程序;
  • 如何添加事件和异常处理器;
  • 如何开发、配置控制器和视图;
  • 如何实现控制器参数绑定;
  • 如何实现参数验证;
  • 如何实现拦截器;
  • 如何时创建数据库实体;
  • 如何创建和配置存储器;
  • 如何扩展插件模块;
  • 插件的开发流程;

如何基于YMP框架搭建WEB应用程序

  1. 新建Eclipse工程

    STEP 1:选择”Web”->”Dynamic Web Project”,点击”Next”按钮;

    STEP 2:键入工程名称并调整相关设置,点击”Finish”按钮完成;

  2. 调整源码包和编译路径

    STEP 1:打开新建工程”ympweb-demo”的属性设置,将”Default output folder”路径修改为与下图相同的地址:

    STEP 2:移除已存在的”src”源码包,并添加”src/conf”和”src/core”两个源码包路径,修改结果如下图所示,点击”Ok”保存设置;

    FINAL:工程创建完成后,其目录结构如下图所示,其中”src/conf”目录用于存放相关配置文件,”src/core”目录用于存放相关代码;

  3. 添加依赖包,框架所需依赖包复制到”WEB-INF/lib”目录下并刷新工程,如下图所示;

  4. 配置并初始化YMP框架

    STEP 1:修改”web.xml”文件

     <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
             id="WebApp_ID" version="2.5">
         <display-name>ympweb-demo</display-name>
         <listener>
             <listener-class>net.ymate.platform.mvc.web.WebMvcEventListener</listener-class>
         </listener>
         <filter>
             <filter-name>ymatemvc</filter-name>
             <filter-class>net.ymate.platform.mvc.web.DispatcherFilter</filter-class>
         </filter>
         <filter-mapping>
             <filter-name>ymatemvc</filter-name>
             <url-pattern>/*</url-pattern>
             <dispatcher>REQUEST</dispatcher>
             <dispatcher>FORWARD</dispatcher>
         </filter-mapping>
         <welcome-file-list>
             <welcome-file>index.html</welcome-file>
             <welcome-file>index.jsp</welcome-file>
         </welcome-file-list>
     </web-app>
    

    STEP 2:添加”src/conf/ymp-conf.properties”文件

     ymp.dev_model=true
     ymp.module_list=configuration|logger|jdbc|webmvc
     
     ymp.modules.configuration=net.ymate.platform.module.ConfigModule
     ymp.modules.logger=net.ymate.platform.module.LogModule
     ymp.modules.webmvc=net.ymate.platform.module.WebMvcModule
     ymp.modules.jdbc=net.ymate.platform.module.JdbcModule
     
     ymp.configs.configuration.config_home=${root}
     
     ymp.configs.logger.name=default
     ymp.configs.logger.level=debug
     ymp.configs.logger.xml_cfg_file=${user.dir}cfgs/log4j.xml
     ymp.configs.logger.output_path=${user.dir}logs/
     ymp.configs.logger.allow_print_console=true
     
     ymp.configs.webmvc.base.locale=zh_CN
     ymp.configs.webmvc.base.charset_encoding=UTF-8
     ymp.configs.webmvc.base.view_path=/WEB-INF/templates/
     ymp.configs.webmvc.base.restful_model=true
     
     ymp.configs.jdbc.base.show_sql=true
     ymp.configs.jdbc.base.table_prefix=ymweb_
     ymp.configs.jdbc.base.datasource_default=default
     ymp.configs.jdbc.base.datasource_list=default
     ymp.configs.jdbc.datasource.default.driver_class=com.mysql.jdbc.Driver
     ymp.configs.jdbc.datasource.default.connection_url=jdbc:mysql://localhost:3306/ymateweb_v2?useUnicode=true&characterEncoding=UTF-8
     ymp.configs.jdbc.datasource.default.username=root
     ymp.configs.jdbc.datasource.default.password=admin
    

    STEP 3:创建配置体系目录并添加日志配置文件

    添加”src/conf/commons-logging.properties”文件,内容如下:

     org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
    

    在”WEB-INF”目录下添加”cfgs”目录并添加”log4j.xml”文件,内容如下:

     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE log4j:configuration SYSTEM "/org/apache/log4j/xmllog4j.dtd">
     <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
         <appender name="RootFileAppender" class="org.apache.log4j.DailyRollingFileAppender">
             <param name="File" value="${LOGS_DIR}/logger-root.log" />
             <param name="Append" value="true" />
             <param name="DatePattern" value="'.'yyMMddHH" />
             <layout class="org.apache.log4j.PatternLayout">
                 <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss,SSS}] [%p] [%l] %x - %m%n" />
             </layout>
         </appender>
         <appender name="FileAppender" class="org.apache.log4j.DailyRollingFileAppender">
             <param name="File" value="${LOGS_DIR}/logger-default.log" />
             <param name="Append" value="true" />
             <param name="DatePattern" value="'.'yyMMddHH" />
             <layout class="org.apache.log4j.PatternLayout">
                 <param name="ConversionPattern" value="%m%n" />
             </layout>
         </appender>
         <logger name="default">
             <level value="debug" />
             <appender-ref ref="FileAppender" />
         </logger>
         <root>
             <priority value ="debug"/>
             <appender-ref ref="RootFileAppender"/>
         </root>
     </log4j:configuration>
    

    STEP 4:调整后,整个工程结构如下图所示:

    STEP 5:部署到Tomcat容器并启动,检查日志输出,确认框架配置是否成功

如何添加事件和异常处理器

  • STEP 1:创建WebErrorHandler类并实现IWebErrorHandler接口

      public class WebErrorHandler implements IWebErrorHandler {
    
          public void onError(Throwable e) {
              Logs.debug("", e);
          }
    
          public IView onConvention(String requestMapping) {
              return null;
          }
    
          public IView onValidation(Set<ValidateResult> results) {
              return null;
          }
    
      }
    
  • STEP 2:创建WebEventHandler类并实现IWebEventHandler接口

      public class WebEventHandler implements IWebEventHandler {
    
          public void onInitialized() {
          }
    
          public void onDestroyed() {
          }
    
          public void onRequestDestroyed(ServletRequestEvent event) {
          }
    
          public void onRequestInitialized(ServletRequestEvent event) {
          }
    
          public void onSessionCreated(HttpSessionEvent event) {
          }
          public void onSessionDestroyed(HttpSessionEvent event) {
          }
    
          public void onShutdown(ServletContextEvent event) {
          }
    
          public void onStartup(ServletContextEvent event) {
          }
    
      }
    
  • STEP 3:修改”src/conf/ymp-conf.properties”文件,添加相关配置

      ymp.configs.webmvc.base.event_handler_class=net.ymate.web.demo.WebEventHandler
      ymp.configs.webmvc.base.error_handler_class=net.ymate.web.demo.WebErrorHandler
    
  • STEP 4:至此,框架的事件和异常处理器添加完成,整个工程结构如下图所示:

如何开发、配置控制器和视图

  • STEP 1:修改”src/conf/ymp-conf.properties”文件,添加控制器包扫描路径配置

      ymp.configs.webmvc.base.controller_packages=net.ymate.web.demo.controller
    
  • STEP 2:创建控制器包路径和类对象

      @Controller
      public class DemoController {
    
          @RequestMapping("hello")
          @RequestMethod
          public IView hello() {
              return new TextView("Hello, world!");
          }
    
      }
    
  • STEP 3:部署分发到Tomcat容器并启动,通过浏览器访问:

如何实现控制器参数绑定

  • 方式一:绑定请求参数

    • 在控制器中添加如下代码

        @RequestMapping("/hello/sayHi")
        @RequestMethod
        public IView sayHi(@RequestParam String name) {
            return new TextView("Hi, " + name);
        }
      
    • 部署分发到Tomcat容器并启动,通过浏览器访问:

  • 方式二:绑定URL参数

    • 在控制器中添加如下代码

        @RequestMapping("/hello/sayHi/{name}")
        @RequestMethod
        public IView sayHi2(@PathVariable String name) {
            return new TextView("Hi, " + name);
        }
      
    • 部署分发到Tomcat容器并启动,通过浏览器访问:

如何实现参数验证

  • STEP 1:在控制器中添加如下代码

      @RequestMapping("/valid/{name}/{age}")
      @RequestMethod
      @Validation(fullMode = true)
      public IView paramValidator(
          @Validate({
              @ValidateRule(RequriedValidator.NAME),
              @ValidateRule(value = LengthValidator.NAME, params = { "min=3",	"max=6" }) })
          @PathVariable String name, 
    
          @Validate({
              @ValidateRule(RequriedValidator.NAME),
              @ValidateRule(value = NumericValidator.NAME, params = { "min=18",	"max=20" }) })
          @PathVariable String age) {
    
          return new TextView("");
      }
    
  • STEP 2:通过浏览器访问http://localhost:8080/ympweb-demo/valid/lz/13,控制台将抛出如下异常:

      2013-07-28 23:31:44.415[调试][18:WebErrorHandler.onError:44] - 以下是异常(net.ymate.platform.validation.ValidationException:[
      { fieldName : 'age', message : '长度必须介于18和20之间' }, 
      { fieldName : 'name', message : '长度必须介于3和6之间' }])的堆栈信息:
          at net.ymate.platform.mvc.support.RequestExecutor.execute(RequestExecutor.java:125)
          at net.ymate.platform.mvc.web.DispatcherFilter.doFilter(DispatcherFilter.java:125)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
          at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
          at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
          at java.lang.Thread.run(Thread.java:619)
    
  • STEP 3:若希望将验证信息输出到浏览器,可以通过WebErrorHandler类中onValidation方法实现,代码如下:

      public IView onValidation(Set<ValidateResult> results) {
          StringBuilder _sb = new StringBuilder();
          for (ValidateResult _result : results) {
              _sb.append(_result.getMessage()).append("<br/>");
          }
          return new TextView(_sb.toString());
      }
    
  • STEP 4:再次通过浏览器访问:

如何实现拦截器

  • STEP 1:创建拦截器类,用于拦截年龄大于19岁,代码如下:

      @Bean
      public class DemoFilter implements IFilter {
          public IView doFilter(RequestMeta meta, String params) throws Exception {
              Integer _age = Integer.parseInt(StringUtils.defaultIfEmpty((String) WebContext.getContext().get("age"), "0"));
              if (_age > 19) {
                  return new TextView("年龄大于19岁,被拦截");
              }
              return null;
          }
      }
    
  • STEP 2:将@Filter注解添加到控制器方法,修改后代码如下:

      @RequestMapping("/valid/{name}/{age}")
      @RequestMethod
      @Validation(fullMode = true)
      @Filter(DemoFilter.class)
      public IView paramValidator(
          @Validate({
              @ValidateRule(RequriedValidator.NAME),
              @ValidateRule(value = LengthValidator.NAME, params = { "min=3",	"max=6" }) })
          @PathVariable String name, 
          @Validate({
              @ValidateRule(RequriedValidator.NAME),
              @ValidateRule(value = NumericValidator.NAME, params = { "min=18",	"max=20" }) })
          @PathVariable int age) {
    
          return new TextView("你好," + name + ", 你今年" + age + "岁了!");
      }
    
  • STEP 3:再次通过浏览器分别访问:

如何创建数据库实体

  • STEP 1:创建数据库表,假设现在存在如下表结构:

  • STEP 2:为了方便日后对实体类进行扩展,先创建实体基类对象,代码如下:

      public abstract class BaseEntity<PK> implements IEntity<PK> {
    
          private static final long serialVersionUID = 1L;
    
          public BaseEntity() {
          }
    
      }
    
  • STEP 3:创建实体对象,继承BaseEntity抽象类,代码如下:

      @Entity(name = "system_config")
      public class SystemConfigModel extends BaseEntity<String> {
      
          private static final long serialVersionUID = 1L;
          
          @Id
          @Property(name = "id")
          private String id;
          
          @Property(name = "cfg_value")
          private String cfgValue;
          
          @Property(name = "data_type")
          private String dataType;
          
          @Column(name = "remark")
          private String remark;
          
          public SystemConfigModel() {
          }
          
          public SystemConfigModel(String id, String cfgValue, String dataType, String remark) {
              this.id = id;
              this.cfgValue = cfgValue;
              this.dataType = dataType;
              this.remark = remark;
          }
          
          public String getId() {
              return id;
          }
          
          public void setId(String id) {
              this.id = id;
          }
          
          public String getCfgValue() {
              return cfgValue;
          }
          
          public void setCfgValue(String cfgValue) {
              this.cfgValue = cfgValue;
          }
          
          public String getDataType() {
              return dataType;
          }
          
          public void setDataType(String dataType) {
              this.dataType = dataType;
          }
          
          public String getRemark() {
              return remark;
          }
          
          public void setRemark(String remark) {
              this.remark = remark;
          }
          
          public class FIELDS {
              public static final String ID = "id";
              public static final String CFG_VALUE = "cfg_value";
              public static final String DATA_TYPE = "data_type";
              public static final String REMARK = "remark";
          }
          
          public static final String TABLE_NAME = JDBC.TABLE_PREFIX + "system_config";
      
      }
    

如何创建和配置存储器

  • STEP 1:定义存储器接口,代码如下:

      public interface ISystemConfigRepository {
      
          public List<SystemConfigModel> findById(String id, String... filter) throws Exception;
          
          public SystemConfigModel insert(SystemConfigModel model) throws Exception;
          
          public SystemConfigModel update(SystemConfigModel model, String...filter) throws Exception;
          
          public SystemConfigModel delete(SystemConfigModel model) throws Exception;
      
      }
    
  • STEP 2:实现存储器接口,代码如下:

      @Repository
      public class SystemConfigRepository implements ISystemConfigRepository {
      
          public List<SystemConfigModel> findById(String id, String... filter) throws Exception {
              ISession _session = JDBC.openSession();
              try{
                  return _session.find(SystemConfigModel.class, id, filter);
              } finally {
                  _session.close();
              }
          }
          
          public SystemConfigModel insert(SystemConfigModel model) throws Exception {
              ISession _session = JDBC.openSession();
              try{
                  return _session.insert(model);
              } finally {
                  _session.close();
              }
          }
          
          public SystemConfigModel update(SystemConfigModel model, String... filter) throws Exception {
              ISession _session = JDBC.openSession();
              try{
                  return _session.update(model, filter);
              } finally {
                  _session.close();
              }
          }
          
          public SystemConfigModel delete(SystemConfigModel model) throws Exception {
              ISession _session = JDBC.openSession();
              try{
                  return _session.delete(model);
              } finally {
                  _session.close();
              }
          }
    
      }
    
  • STEP 3:需要修改”src/conf/ymp-conf.properties”文件,添加存储器包扫描路径配置:

      ymp.configs.jdbc.base.repository_packages=net.ymate.web.demo.repository
    

如何调用存储器进行数据库操作

  • STEP 1:添加控制器方法,代码如下:

      @RequestMapping("/testdb")
      @RequestMethod
      public IView testRepo() throws Exception {
          SystemConfigModel _model = new SystemConfigModel();
          _model.setId("cfg_username");
          _model.setCfgValue("suninformation");
          
          ISystemConfigRepository _repo = JDBC.getBean(ISystemConfigRepository.class);
          _repo.insert(_model);
          
          _repo.findById("cfg_username", SystemConfigModel.FIELDS.ID);
          
          _model.setCfgValue("suninformation#163.com");
          _repo.update(_model, SystemConfigModel.FIELDS.CFG_VALUE);
          
          _repo.delete(_model);
          
          return new TextView("");
      }
    
  • STEP 2:使用浏览器访问http://localhost:8080/ympweb-demo/testdb,查询日志输出: