精华内容
下载资源
问答
  • IT软件项目开发总结报告

    热门讨论 2011-06-05 17:33:34
    说明编写这份项目开发总结报告的目的,指出预期的阅读范围。 1.2背景 说明: a. 本项目的名称和所开发出来的软件系统的名称; b. 此软件的任务提出者、开发者、用户及安装此软件的计算中心。 1.3定义 列出本文件...
  • 总结报告 java项目总结总结报告 篇一JAVA年终工作总结 篇一it行业java程序员个人年度总结 个人工作总结 时间一晃而过转眼间到公司已经5个月了这是我人生中弥足珍贵的一段经历在这段时间里各级领导在工作上给予了我极...
  • HowToDoIt 组织 的第一个项目, 一个简单的 MVC 展示应用. 实现项目需要响应发送到 GET / 端点的请求并显示一个主页 显示 Hello World - 其中 World 可以被 who 查询参数的值替代 [可选] 显示应用版本 ...

    1. 介绍

    HelloWorld 是一个HowToDoIt 组织的第一个项目, 一个简单的 MVC 展示应用. 实现项目需要响应发送到 GET / 端点的请求并显示一个主页

    1. 显示 Hello World - 其中 World 可以被 who 查询参数的值替代
    2. [可选] 显示应用版本
    3. [可选] 显示框架版本
    4. [可选] 使用模板引擎生成主页

    2. 实现

    下面是所有参与项目的链接:

    3. 源码一览

    3.1 ActFramework

    public class AppEntry {
    
        /**
         * The home (`/`) endpoint.
         *
         * @param who
         *      request query parameter to specify the hello target.
         *      default value is `World`.
         */
        @GetAction
        public void home(@DefaultValue("World") @Output String who) {}
    
        public static void main(String[] args) throws Exception {
            Act.start();
        }
    
    }
    

    ActFramework 的实现相当简单, 使用了一个类来启动并响应请求.

    ActFramework 使用 Rythm 模板引擎生成主页

    <!DOCTYPE html>
    <html lang="en">
    @args String who
    <head>
      <title>Hello World - ActFramework</title>
    </head>
    <body>
      <h1>Hello @who</h1>
      <div>@act.Act.appVersion().getVersion()</div>
      <p>
        Powered by ActFramework @act.Act.VERSION.getVersion()
      </p>
    </body>
    </html>
    

    ActFramwork 项目实现了所有的需求, 包括可选项.

    值得注意的是 ActFramework 使用了 osgl-version 来管理应用版本, 无需编码即可直接从项目的 pom.xml 定义中拿到版本号, 对应用开发来说非常便利: 直接使用 Act.appVersion() 即可拿到应用定义在 pom.xml 文件的版本号. 作为比较, 获得 ActFramework 框架版本号的方法是访问 Act.VERSION 常量.

    ActFramework 实现提供的独特优势: 使用 yaml 文件实现了端到端自动化测试.

    Scenario(Hello World):
      description: a web page says Hello
      interactions:
        - description: send request to the app without parameter
          request:
            method: GET
            url: /
          response:
            html:
              h1: Hello World
              head title:
                - contains: Hello World
                - contains: ActFramework
              p:
                <any>:
                  - contains: Powered by ActFramework
        - description: send request to the app with [who = ActFramework]
          request:
            method: GET
            url: /?who=ActFramework
          response:
            html:
              h1: Hello ActFramework
    

    3.2 Blade

    public class Application {
    
        private static void index(RouteContext ctx) {
    
            String message = "Hello " + ctx.request().query("who", "World");
    
            ctx.attribute("message", message);
            ctx.attribute("appVersion", WebContext.blade().env("app.version", "default version"));
            ctx.attribute("bladeVersion", Const.VERSION);
            ctx.render("index.html");
        }
    
        public static void main(String[] args) {
            Blade.of()
                    .get("/", Application::index)
                    .start(Application.class, args);
        }
    
    }
    

    Blade 也使用了一个 Java 源码就实现了所有的特性, 代码非常优雅. Blade 使用了类似 velocity 的模板引擎生成主页:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
    </head>
    <body>
        <h1>${message}</h1>
        Build By ${name} ${version}
    </body>
    </html>
    

    和 ActFramework 的实现不同, Blade 没有从 pom.xml 文件中获取应用版本信息, 而是在额外的配置文件中定义应用版本.

    3.3 JFinal

    public class HellWorldController extends Controller {
    	public void index(@Para(value="who", defaultValue="World")String who){
    		setAttr("who",who).render("index.html");
    	}
    }
    
    public class ProjectConfig extends JFinalConfig{
    
    	public static void main(String[] args) {
            JFinal.start("src/main/webapp", 8000, "/");
        }
    	
    	public void configRoute(Routes me) {
    		me.setBaseViewPath("/WEB-INF/views").add("/", HellWorldController.class);
    	}
    	
    	public void configConstant(Constants me) {
    	}
    
    	public void configEngine(Engine me) {
    	}
    
    	public void configPlugin(Plugins me) {
    	}
    
    	public void configInterceptor(Interceptors me) {
    	}
    
    	public void configHandler(Handlers me) {
    	}
    }
    

    JFinal 使用了两个 Java 文件, 其中的 Controller 类非常简洁. 不过额外的 ProjectConfig.java 类让整个项目看上去就稍稍繁复了一点点.

    JFinal 使用自己的 Enjoy 模板引擎生成主页:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>HelloWorld</title>
    </head>
    <body>
    <h1>Hello,#(who ?? 'UNKNOWN')!!^_^</h1>
    <form action="/">
            <fieldset>
                <legend>Say Hello To The World</legend>
                <div>who: <input type="text" name="who"/></div>
                <input type="submit" value="==问好==">
              </fieldset>
            </body>
    </form>
    <div style="text-align:center;color:red;padding:10px;">Power By JFinal#(com.jfinal.core.Const::JFINAL_VERSION)</div>
    </html>
    

    JFinal 提供了框架版本号,但没有提供应用版本号

    3.4 Nutz

    @IocBean
    public class MainLauncher {
        
        @Inject
        protected PropertiesProxy conf;
    
        @At("/")
        @Ok("jst:/index.html")
        public NutMap index(String who) throws IOException {
            NutMap re = new NutMap();
            re.put("who", Strings.sBlank(who, "world"));
            re.put("self_version", conf.get("app.build.version", "未知"));
            re.put("nutz_version", Nutz.version());
            return re;
        }
    
        public static void main(String[] args) throws Exception {
            new NbApp().run();
        }
    
    }
    

    Nutz 的实现和 Blade/ActFramwork 一样都是一个文件解决问题. Nutz 也从 pom.xml 文件中获取项目版本号.

    Nutz's 用来生成主页的模板代码:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Hello ${=obj.who}</title>
    </head>
    <body>
    <h1>Hello ${=obj.who}!</h1>
    <h3>Self Version: ${obj.self_version}</h3>
    <h3>Nutz Version: ${obj.nutz_version}</h3>
    </body>
    </html>
    

    3.5 Play

    @Singleton
    class HomeController @Inject()(cc: ControllerComponents, config: Configuration) extends AbstractController(cc) {
      val version = config.get[String]("version")
    
      def index(who: String) = Action {
        Ok(views.html.index(who, version, PlayVersion.current))
      }
    
    }
    

    和其他所有实现不一样, Play 使用的是 Scala. 代码看上去非常少, 不过对我这个 Javaer 来说还是稍微有点眼生的感觉. Play 的实现也包括了展现 app 和框架版本号, play 没有使用定义在 sbt 脚步中的版本, 而是从 app 配置文件中获取版本号, 稍稍重复了一点.

    Play 用来生成页面的模板有两个文件:

    @(title: String)(content: Html)
    
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>@title</title>
        </head>
        <body>
            @content
        </body>
    </html>
    
    @(who: String, version: String, playVersion: String)
    
    @main("Hello World - Play"){
    <h1>Hello @who</h1>
    <div>@version</div>
    <p>
     Powered by Play @playVersion
    </p>
    }
    

    Play 实现提供了自动化测试方案:

    class UnitSpec extends PlaySpec with Results {
    
      "HomeController" should {
    
        "return a valid result with action" in {
          val config = Configuration(ConfigFactory.load("application"))
          val controller = new HomeController(stubControllerComponents(), config)
          val result = controller.index("world")(FakeRequest())
          status(result) mustEqual OK
          contentAsString(result) must include ("Hello World")
        }
      }
    }
    
    class FunctionalSpec extends PlaySpec with GuiceOneAppPerSuite {
    
      "HomeController" should {
    
        "render the index page" in {
          val home = route(app, FakeRequest(GET, "/?who=World")).get
    
          status(home) mustBe Status.OK
          contentType(home) mustBe Some("text/html")
          contentAsString(home) must include ("Hello World")
        }
    
      }
    }
    
    class BrowserSpec extends PlaySpec
      with OneBrowserPerTest
      with GuiceOneServerPerTest
      with HtmlUnitFactory
      with ServerProvider {
    
      "Application" should {
    
        "work from within a browser" in {
    
          go to ("http://localhost:" + port)
    
          pageSource must include ("Hello World")
        }
      }
    }
    

    3.6 Redkale

    @RestService(name = " ")
    public class HelloWorldService implements Service {
    
        private String appVersion = "1.0.0";
    
        @Override
        public void init(AnyValue conf) {
            String path = "/META-INF/maven/org.redkalex.htdi/htdi-hello/pom.properties";
            InputStream in = this.getClass().getResourceAsStream(path);
            if (in != null) {
                Properties props = new Properties();
                try {
                    props.load(in);
                    in.close();
                } catch (Exception e) {
                }
                this.appVersion = props.getProperty("version", "未知");
            }
        }
    
        @RestMapping(name = "index.html", auth = false)
        public HttpResult<String> index(String who) throws IOException {
            if (who == null || who.isEmpty()) who = "World";
            String body = "<!DOCTYPE html>\n"
                + "<html>\n"
                + "<head>\n"
                + "<meta charset=\"UTF-8\">\n"
                + "<title>Hello " + who + "</title>\n"
                + "</head>\n"
                + "<body>\n"
                + "<h1>Hello " + who + "!</h1>\n"
                + "<h3>Project Version: " + appVersion + "</h3>\n"
                + "<h3>Redkale Version: " + Redkale.getDotedVersion() + "</h3>\n"
                + "</body>\n"
                + "</html>";
            return new HttpResult<>("text/html;charset=utf8", body);
        }
    
    }
    

    Redkale 实现直接使用字串拼接输出而不是模板引擎. 对于 HelloWorld 这样的项目这样做完全没有问题. 不过稍微正式一点的项目这样会死人的吧. Redkale 的作者强调 Redkale 的应用更多偏向于数据服务, 同时也提到如果需要模板引擎应用可以很方便地集成三方产品.

    Redkale 实现了展示应用和框架版本的需求.

    3.7 SprintBoot

    @SpringBootApplication
    public class App extends SpringBootServletInitializer implements WebApplicationInitializer {
    
        public static void main( String[] args )
        {
            SpringApplication.run(App.class, args);
        }
    }
    
    @Controller
    public class HelloController {
        @RequestMapping("/")
        public ModelAndView sayHello() {
            ModelAndView view = new ModelAndView("/sayHello.html");
            view.addObject("message", "Hello world"); 
            view.addObject("name", "Spring Boot");
            view.addObject("version", "2.x");
            return view;
        }
    }
    

    SpringBoot 的实现也很容易理解. 使用了 2 个源代码文件, 一个是启动入口, 另一个是响应处理器.

    SprintBoot 使用 Beetl 引擎来生成主页:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    </head>
    <body>
    	<h1>${message}</h1>
    	Build By ${name} ${version}
    </body>
    </html>
    

    SprintBoot 硬编码了框架版本, 没有显示应用版本.

    SprintBoot 实现提供了单元测试.

    @RunWith(SpringRunner.class)
    @WebMvcTest(HelloController.class)
    public class MvcTest{
        @Autowired
        private MockMvc mvc;
        @Test
        public void testHello() throws Exception {
          
            String viewName = mvc.perform(get("/")).andReturn().getModelAndView().getViewName();
            Assert.assertEquals("/sayHello.html", viewName);
        }
    }
    

    这个测试条件比较有趣, 检查是否使用了正确的 view 模板, 并没有针对真正的需求进行测试

    3.8 TIO-MVC

    @RequestPath(value = "/")
    public class HelloController {
    	@RequestPath(value = "")
    	public HttpResponse index(HttpRequest request, String who) throws Exception {
    		String name = StrUtil.isBlank(who) ? "World" : who;
    		String html = "<title>Hello " + name + "</title><h1>Hello " + name + "</h1>";
    		html += "<div>" + HowToDoTioStarter.APP_NAME + " " + P.p.getStr("app.version") + "</div>";
    		html += "<div>Powered by <a href='https://t-io.org' target='_blank'>" + HttpConst.SERVER_INFO + " " + SysConst.TIO_CORE_VERSION + "</a></div>";
    		return Resps.html(request, html);
    	}
    }
    
    public class P {
    	public static Props p = new Props("classpath:app.properties");
    }
    
    public class HowToDoTioStarter {
    	public static final String APP_NAME = "how to do it : tio-mvc";
    	
    	public static HttpConfig httpConfig;
    
    	public static HttpRequestHandler requestHandler;
    
    	public static HttpServerStarter httpServerStarter;
    
    	public static ServerGroupContext serverGroupContext;
    
    	public static void init() throws Exception {
    		httpConfig = new HttpConfig(P.p.getInt("http.port"), null, null, null);
    //		httpConfig.setPageRoot(P.p.getStr("http.page"));//html/css/js等的根目录,支持classpath:,也支持绝对路径
    //		httpConfig.setMaxLiveTimeOfStaticRes(P.p.getInt("http.maxLiveTimeOfStaticRes"));
    //		httpConfig.setPage404(P.p.getStr("http.404"));
    //		httpConfig.setPage500(P.p.getStr("http.500"));
    		httpConfig.setUseSession(false);
    		httpConfig.setCheckHost(false);
    
    		String[] scanPackages = new String[] { HelloController.class.getPackage().getName() };//tio mvc需要扫描的根目录包,会递归子目录
    		Routes routes = new Routes(scanPackages);
    		requestHandler = new DefaultHttpRequestHandler(httpConfig, routes);
    
    		httpServerStarter = new HttpServerStarter(httpConfig, requestHandler);
    		serverGroupContext = httpServerStarter.getServerGroupContext();
    		serverGroupContext.setUseQueueSend(true);
    		httpServerStarter.start(); //启动http服务器
    	}
    	
    	public static void main(String[] args) throws Exception {
    		init();
    	}
    }
    

    TIO-MVC 的实现代码行数和 JFinal 实现相近. 控制器本身的代码相对简单, 只是实现中有一些 boilerplate 代码, 和其他实现比较起来稍显臃肿.

    和 Redkale 一样, TIO-MVC 的实现选择使用字串拼接来生成主页; 另外 TIO-MVC 的应用版本是硬编码在代码中的.

    4. 启动

    4.1 启动 ActFramework

    ActFramework 提供了不同脚本来实现不同模式的启动:

    4.1.1 开发模式

    image

    image

    4.1.2 e2e 测试模式

    使用 e2e 模式启动应用可以启动后立刻运行自动化测试脚本:

    image

    4.1.3 产品模式

    image

    image

    4.2 Blade

    Blade 没有提供启动脚本, 不过 README 文件提供了启动步骤

    image

    image

    4.3 JFinal

    在启动 JFinal 项目的时候我们遇到了一点麻烦, 因为 JFinal build 的包是用来部署到 servlet 容器里面的, 我们不太想去和 Tomcat 之类的东西打交道, 所以在 JFinal 项目里面添加了插件:

    		<plugins>
    		  <plugin>
    		    <groupId>org.mortbay.jetty</groupId>
    		    <artifactId>jetty-maven-plugin</artifactId>
    		    <version>8.1.8.v20121106</version>
    		    <configuration>
    		        <stopKey>stop</stopKey>
    		        <stopPort>5599</stopPort>
    		        <webAppConfig>
    		            <contextPath>/</contextPath>
    		        </webAppConfig>
    		        <scanIntervalSeconds>5</scanIntervalSeconds>
    		        <connectors>
    		            <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
    		                <port>80</port>
    		                <maxIdleTime>60000</maxIdleTime>
    		            </connector>
    		        </connectors>
    		    </configuration>
    		  </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.2.1</version>
                    <configuration>
                        <executable>java</executable>
                        <arguments>
                            <argument>-Xms512m</argument>
                            <argument>-Xmx512m</argument>
                            <argument>-classpath</argument>
                            <classpath/>
                            <argument>htdi.jfinal.hellworld.config.ProjectConfig</argument>
                        </arguments>
                    </configuration>
                </plugin>
    	</plugins>
    

    之后我们就可以直接启动了:

    image

    image

    4.4 Nutz

    Nutz 也是通过 README 文件提供了启动步骤. Nutz 启动信息比较多, 没法截屏:

    luog@luog-X510UQR:~/p/htdi/nutz-hello-world$ mvn -q clean compile nutzboot:run
    [INFO ] 07:55:50.685 org.nutz.boot.banner.SimpleBannerPrinter.printBanner(SimpleBannerPrinter.java:34) - 
     _   _ ______                                      ___   
    | \ | || ___ \  ______ ______ ______ ______ ______| \ \  
    |  \| || |_/ / |______|______|______|______|______| |\ \ 
    | . ` || ___ \  ______ ______ ______ ______ ______| | > >
    | |\  || |_/ / |______|______|______|______|______| |/ / 
    \_| \_/\____/                                     |_/_/  
      
    :: Nutz Boot ::   (2.3-SNAPSHOT)
    
    [INFO ] 07:55:50.736 org.nutz.ioc.loader.annotation.AnnotationIocLoader.<init>(AnnotationIocLoader.java:50) -  > scan 'htdi.nutz.helloworld'
    [INFO ] 07:55:50.738 org.nutz.ioc.loader.annotation.AnnotationIocLoader.addClass(AnnotationIocLoader.java:98) -    > add 'mainLauncher                            ' - htdi.nutz.helloworld.MainLauncher
    [INFO ] 07:55:50.740 org.nutz.ioc.loader.annotation.AnnotationIocLoader.<init>(AnnotationIocLoader.java:50) -  > scan 'org.nutz.boot.starter'
    [INFO ] 07:55:50.750 org.nutz.ioc.loader.annotation.AnnotationIocLoader.addClass(AnnotationIocLoader.java:98) -    > add 'nutFilterStarter                        ' - org.nutz.boot.starter.nutz.mvc.NutFilterStarter
    [INFO ] 07:55:50.753 org.nutz.ioc.loader.annotation.AnnotationIocLoader.addClass(AnnotationIocLoader.java:98) -    > add 'whaleFilterStarter                      ' - org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter
    [INFO ] 07:55:50.754 org.nutz.ioc.loader.annotation.AnnotationIocLoader.addClass(AnnotationIocLoader.java:98) -    > add 'jettyStarter                            ' - org.nutz.boot.starter.jetty.JettyStarter
    [INFO ] 07:55:50.765 org.nutz.ioc.loader.annotation.AnnotationIocLoader.addClass(AnnotationIocLoader.java:98) -    > add 'nbServletContextListener                ' - org.nutz.boot.starter.servlet3.NbServletContextListener
    [INFO ] 07:55:50.767 org.nutz.ioc.loader.annotation.AnnotationIocLoader.addClass(AnnotationIocLoader.java:98) -    > add 'jstViewStarter                          ' - org.nutz.boot.starter.jst.JstViewStarter
    [INFO ] 07:55:50.777 org.nutz.boot.NbApp.prepare(NbApp.java:279) - Configure Manual:
    |id  |key                                     |required  |Possible Values     |Default   |Description         |                                starters|
    |----|----------------------------------------|----------|--------------------|----------|--------------------|----------------------------------------|
    |0   |jetty.contextPath                       |no        |                    |/         |上下文路径               |org.nutz.boot.starter.jetty.JettyStarter|
    |1   |jetty.gzip.enable                       |no        |                    |false     |是否启用gzip            |org.nutz.boot.starter.jetty.JettyStarter|
    |2   |jetty.gzip.level                        |no        |                    |-1        |gzip压缩级别            |org.nutz.boot.starter.jetty.JettyStarter|
    |3   |jetty.gzip.minContentSize               |no        |                    |512       |gzip压缩最小触发大小        |org.nutz.boot.starter.jetty.JettyStarter|
    |4   |jetty.host                              |no        |                    |0.0.0.0   |监听的ip地址             |org.nutz.boot.starter.jetty.JettyStarter|
    |5   |jetty.http.idleTimeout                  |no        |                    |300000    |空闲时间,单位毫秒           |org.nutz.boot.starter.jetty.JettyStarter|
    |6   |jetty.httpConfig.blockingTimeout        |no        |                    |-1        |阻塞超时                |org.nutz.boot.starter.jetty.JettyStarter|
    |7   |jetty.httpConfig.headerCacheSize        |no        |                    |8192      |头部缓冲区大小             |org.nutz.boot.starter.jetty.JettyStarter|
    |8   |jetty.httpConfig.maxErrorDispatches     |no        |                    |10        |最大错误重定向次数           |org.nutz.boot.starter.jetty.JettyStarter|
    |9   |jetty.httpConfig.outputAggregationSize  |no        |                    |8192      |输出聚合大小              |org.nutz.boot.starter.jetty.JettyStarter|
    |10  |jetty.httpConfig.outputBufferSize       |no        |                    |32768     |输出缓冲区大小             |org.nutz.boot.starter.jetty.JettyStarter|
    |11  |jetty.httpConfig.persistentConnectionsEnabled|no        |                    |true      |是否启用持久化连接           |org.nutz.boot.starter.jetty.JettyStarter|
    |12  |jetty.httpConfig.requestHeaderSize      |no        |                    |8192      |请求的头部最大值            |org.nutz.boot.starter.jetty.JettyStarter|
    |13  |jetty.httpConfig.responseHeaderSize     |no        |                    |8192      |响应的头部最大值            |org.nutz.boot.starter.jetty.JettyStarter|
    |14  |jetty.httpConfig.securePort             |no        |                    |          |安全协议的端口,例如8443      |org.nutz.boot.starter.jetty.JettyStarter|
    |15  |jetty.httpConfig.secureScheme           |no        |                    |          |安全协议,例如https        |org.nutz.boot.starter.jetty.JettyStarter|
    |16  |jetty.httpConfig.sendDateHeader         |no        |                    |true      |是否发送日期信息            |org.nutz.boot.starter.jetty.JettyStarter|
    |17  |jetty.httpConfig.sendServerVersion      |no        |                    |true      |是否发送jetty版本号        |org.nutz.boot.starter.jetty.JettyStarter|
    |18  |jetty.maxFormContentSize                |no        |                    |1gb       |表单最大尺寸              |org.nutz.boot.starter.jetty.JettyStarter|
    |19  |jetty.page.404                          |no        |                    |          |自定义404页面,同理,其他状态码也是支持的|org.nutz.boot.starter.jetty.JettyStarter|
    |20  |jetty.page.java.lang.Throwable          |no        |                    |          |自定义java.lang.Throwable页面,同理,其他异常也支持|org.nutz.boot.starter.jetty.JettyStarter|
    |21  |jetty.port                              |no        |                    |8080      |监听的端口               |org.nutz.boot.starter.jetty.JettyStarter|
    |22  |jetty.staticPath                        |no        |                    |          |额外的静态文件路径           |org.nutz.boot.starter.jetty.JettyStarter|
    |23  |jetty.staticPathLocal                   |no        |                    |          |静态文件所在的本地路径         |org.nutz.boot.starter.jetty.JettyStarter|
    |24  |jetty.threadpool.idleTimeout            |no        |                    |60000     |线程池idleTimeout,单位毫秒 |org.nutz.boot.starter.jetty.JettyStarter|
    |25  |jetty.threadpool.maxThreads             |no        |                    |500       |线程池最大线程数maxThreads  |org.nutz.boot.starter.jetty.JettyStarter|
    |26  |jetty.threadpool.minThreads             |no        |                    |200       |线程池最小线程数minThreads  |org.nutz.boot.starter.jetty.JettyStarter|
    |27  |jetty.welcome_files                     |no        |                    |index.html,index.htm,index.do|WelcomeFile列表       |org.nutz.boot.starter.jetty.JettyStarter|
    |28  |nutz.mvc.whale.enc.input                |no        |                    |UTF-8     |在其他Filter之前设置input编码|org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter|
    |29  |nutz.mvc.whale.enc.output               |no        |                    |UTF-8     |在其他Filter之前设置output编码|org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter|
    |30  |nutz.mvc.whale.http.hidden_method_param |no        |                    |          |隐形http方法参数转换所对应的参数名 |org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter|
    |31  |nutz.mvc.whale.http.method_override     |no        |                    |false     |是否允许使用X-HTTP-Method-Override|org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter|
    |32  |nutz.mvc.whale.upload.enable            |no        |                    |false     |是否启用隐形Upload支持      |org.nutz.boot.starter.nutz.mvc.WhaleFilterStarter|
    |33  |web.session.timeout                     |no        |                    |30        |Session空闲时间,单位分钟    |org.nutz.boot.starter.jetty.JettyStarter|
    [INFO ] 07:55:50.782 org.nutz.ioc.impl.NutIoc.<init>(NutIoc.java:130) - ... NutIoc init complete
    [INFO ] 07:55:50.825 org.eclipse.jetty.util.log.Log.initialized(Log.java:193) - Logging initialized @2378ms to org.eclipse.jetty.util.log.Slf4jLog
    [INFO ] 07:55:50.987 org.eclipse.jetty.server.Server.doStart(Server.java:374) - jetty-9.4.11.v20180605; built: 2018-06-05T18:24:03.829Z; git: d5fc0523cfa96bfebfbda19606cad384d772f04c; jvm 1.8.0_171-b11
    [WARN ] 07:55:51.173 org.eclipse.jetty.annotations.AnnotationParser.asmVersion(AnnotationParser.java:95) - Unknown asm implementation version, assuming version 393216
    [INFO ] 07:55:51.173 org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:489) - Scanning elapsed time=0ms
    [INFO ] 07:55:51.177 org.eclipse.jetty.webapp.StandardDescriptorProcessor.visitServlet(StandardDescriptorProcessor.java:283) - NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
    [INFO ] 07:55:51.185 org.eclipse.jetty.server.session.DefaultSessionIdManager.doStart(DefaultSessionIdManager.java:365) - DefaultSessionIdManager workerName=node0
    [INFO ] 07:55:51.185 org.eclipse.jetty.server.session.DefaultSessionIdManager.doStart(DefaultSessionIdManager.java:370) - No SessionScavenger set, using defaults
    [INFO ] 07:55:51.187 org.eclipse.jetty.server.session.HouseKeeper.startScavenging(HouseKeeper.java:149) - node0 Scavenging every 660000ms
    [INFO ] 07:55:51.202 org.nutz.mvc.NutFilter._init(NutFilter.java:85) - NutFilter[nutz] starting ...
    [INFO ] 07:55:51.207 org.nutz.mvc.impl.NutLoading.load(NutLoading.java:55) - Nutz Version : 1.r.66-20180614 
    [INFO ] 07:55:51.207 org.nutz.mvc.impl.NutLoading.load(NutLoading.java:56) - Nutz.Mvc[nutz] is initializing ...
    [INFO ] 07:55:51.207 org.nutz.mvc.config.AbstractNutConfig.getAppRoot(AbstractNutConfig.java:82) - /WEB-INF/ not Found?!
    [INFO ] 07:55:51.210 org.nutz.mvc.impl.NutLoading.evalUrlMapping(NutLoading.java:159) - Build URL mapping by org.nutz.mvc.impl.UrlMappingImpl ...
    [INFO ] 07:55:51.232 org.nutz.mvc.impl.NutActionChainMaker.getProcessorByName(NutActionChainMaker.java:72) - Optional processor class not found, disabled : org.nutz.integration.shiro.NutShiroProcessor
    [INFO ] 07:55:51.254 org.nutz.mvc.impl.NutActionChainMaker.getProcessorByName(NutActionChainMaker.java:72) - Optional processor class not found, disabled : org.nutz.plugins.validation.ValidationProcessor
    [INFO ] 07:55:51.262 org.nutz.mvc.impl.NutLoading.evalUrlMappingluog@luog-X510UQR:~/p/htdi/nutz-hello-world$ mvn -q clean compile nutzboot:run
    (NutLoading.java:221) - Found 1 module methods
    [INFO ] 07:55:51.263 org.nutz.mvc.impl.NutLoading.load(NutLoading.java:141) - Nutz.Mvc[nutz] is up in 56ms
    [INFO ] 07:55:51.277 org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:851) - Started o.e.j.w.WebAppContext@d2b229c{/,[],AVAILABLE}
    [INFO ] 07:55:51.288 org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:289) - Started ServerConnector@32a11092{HTTP/1.1,[http/1.1]}{127.0.0.1:8080}
    [INFO ] 07:55:51.288 org.eclipse.jetty.server.Server.doStart(Server.java:411) - Started @2842ms
    [INFO ] 07:55:51.291 org.nutz.boot.NbApp.execute(NbApp.java:213) - NB started : 702ms
    

    image

    4.5 Play

    Play 的实现使用了 sbt, 第一次运行简直就是灾难, 花了至少半个小时才能启动. 不过第一次之后就都很好了:

    image

    image

    4.6 Redkale

    和大部分实现项目一样, Redkale 在 README 中提供了如何启动应用的方法. 我们可以很容易启动 Redkale 项目:

    image

    image

    4.7 SpringBoot

    启动 SpringBoot 项目没有什么问题:

    image

    image

    4.8 TIO-MVC

    TIO-MVC 实现稍微有一点不一样. 使用 mvn clean package 构建项目包之后我们需要到 /target/htdi-tio-helloworld 目录然后运行 startup.sh 启动应用:

    image

    image

    5. 一些数据比较

    image

    注意

    1 SpringBoot 提供了单元测试用例, 不过该测试只检查是否加载了正确的模板文件, 并没有检查输出是否满足需求 2 测试环境: 操作系统: LinuxMint 19, 硬件: i7 8550U + 16GB RAM + SSD

    转载于:https://my.oschina.net/greenlaw110/blog/1916863

    展开全文
  • 项目开发总结报告(样本标准),这里只是一个规范的样本标准,希望对大家有用,主要是针对IT软件的。包括:对开发工作评价、产品质量的评价、经验与教训等
  • 项目总结报告(小米商城)

    千次阅读 2016-11-18 19:08:30
    引言: 首先、这次报告写得有些越权了,因为这次我不是主要的负责人,二是参与...为知笔记、W3C手册、以及各种IT类资料和博文开发工作评价 这是第二次项目、相对于上一次来说有了很大的进步、但是也出了不少问题;比

    引言:
    首先、这次报告写得有些越权了,因为这次我不是主要的负责人,二是参与了其中一部分的工作;总之种种原因吧、不说了;看我报告!!!!

    背景:

    项目名称:小米商城(电商网站)
    类别:功能类
    项目组成员:王华桥、黄海帮(负责人)、杜克灿、颜洁、李金烁

    参考资料
    为知笔记、W3C手册、以及各种IT类资料和博文

    开发工作评价
    这是第二次项目、相对于上一次来说有了很大的进步、但是也出了不少问题;比如缺少的一些部分和章节、这跟我们对IT行业的认识不足有很大关系;希望在今后的工作中不断的进步。

    对产品功能的评价
    由于时间的缘故、这次项目要在很短的时间内完成;所以有些功能不够完善也在情理之中;
    首先是小米商城的首页、图片特别多、头部的效果比较复杂、所以我们在做的时候砍掉了一些复杂的特效。我们怎么能够和小米团队相比较呢是吧;

    然后是MIUI部分,这部分是本人做的。其中有一个特效比较烦人,我纠结了两天才攻破,我已经把具体问题的解决放在这里

    其他页面也有可圈可点的经验总结;待其他成员总结给我再一一补充

    项目经验总结
    在一个项目的开发中,文档的书写是极为重要的一项工作。因为,某些文档就是我们在开发后期与客户沟通的可寻依据、也是我们程序员在编码过程中要用到的重要文档。我们绝对不能认为,凭借我们的大脑来记录所有的开发需求。即使,你说你是天才,你要用你那颗爱因斯坦的大脑来记录所有的开发需求,那也是不可能的,人的精力总是有限的。这就要求我们在需求调研中做好需求文档的记录和整理。

    展开全文
  • IT项目管理个人报告

    2020-08-04 21:28:00
    一、大作业承担角色 1.1 产品服务收集 需求:以中山大学为研究对象,以信息技术服务本科生为内容,调查梳理中山大学为...IT项目管理课程为我们讲述了项目过程组,即包括项目启动过程组、规划过程组、执行过程组、监控

    一、大作业承担角色

    1.1 产品服务收集

    • 需求:以中山大学为研究对象,以信息技术服务本科生为内容,调查梳理中山大学为学生提供的软件产品、在线服务。
    • 方法:使用系统手段来收集、整理这些产品与服务。按时间轴为主线梳理产品与服务。
    • 最后结果:在这里插入图片描述

    1.2 项目管理文档的编写

    • 组内其他同学编写思维导图和WBS、甘特图和网络图、成本模型和成本基线图、项目章程等,我负责收集与梳理、总结编写成项目管理文档

    二、管理方法与经验

    • IT项目管理课程为我们讲述了项目过程组,即包括项目启动过程组、规划过程组、执行过程组、监控过程组、收尾过程组,以及几大知识体系,既包括项目范围管理、项目时间管理、项目成本管理、项目质量管理、项目风险管理、项目人力资源管理与项目沟通管理等。
    • 在项目的启动阶段,我觉得最重要的是弄清楚项目的目标和项目的范围。也就是说,项目需求应该需要有明确的任务和时间约束,以便于人力的安排与任务的分发。在七月份的时候我来到腾讯实习,可以感受到这里对项目迭代的任务需求会划分的很细,通过滚动规划,让需求细节尽量在大方向之中。
    • 在项目管理中,如今十分流行敏捷开发。因为敏捷开发随时应对变化,注重实用性而不是文档。需求不断变化迭代,任务的分发通过开会一起商量评估。但是在实习的过程中,可以感受到这样的开发方式需要在大家水平相当的情况下,对于像我这样的实习生或校招新人其实并不是很友好,中间开发过程中存在一定的漏洞,文档有时候还是需要的。
    • 在项目变更中,需要对风险有一定的考评。在实习的过程中,由于是新项目,可以在许多框架细节上去尝试很多新事物,但是尝试之前会经过大家的头脑风暴,需要去考量与其他框架的区别,优点等。这个过程需要避免所谓的权威,应该实事求是。
    展开全文
  • 第六章 项目时间管理 项目时间管理 –定义:确保项目按时完成所需的过程 –七个主要过程: ...A....B....C....D....E....F....G....–项目进度模型的开发 ...–在开发项目进度模型中使用到达地方法和工具 ...–报告格式 –过程描...

    第六章 项目时间管理

    1. 项目时间管理

      –定义:确保项目按时完成所需的过程

      –七个主要过程:
      A. 计划进度管理
      B. 定义活动
      C. 排序活动
      D. 估算活动资源
      E. 估算活动工期
      F. 制订进度计划
      G. 控制进度
      在这里插入图片描述

    1. 计划进度管理

      –项目进度模型的开发

      –在开发项目进度模型中使用到达地方法和工具

      –精度水平和计量单位

      –控制阈值

      –性能测量的规则

      –报告格式

      –过程描述

    2. 活动(Activity )

      –定义:工作的组成要素,通常出现在WBS中,有预计的工期、成本和资源要求,也被称为任务(task)

      –活动清单(Activity list):是包含在项目进度中的活动列表

      –活动属性(Activity attributes):提供了与进度相关的更多信息

      –里程碑(milestone):项目中一个通常没有工期的重要事件,它本身更像一个标志来帮助识别相关的活动

    3. 排序活动(Sequencing Activities)

      –依赖(dependency)或关系(relationship)与项目活动或任务的排序相关。分为强制(Mandatory)依赖、自由(Discretionary)依赖、外部(External)依赖

      –网络图(network diagram):
      是项目活动之间的逻辑关系或者顺序的示意性表示。它有几种主要的格式:
      A. 双代号网络图(Activity-On-Arrow)或箭线图法(Arrow Diagramming Method)
      在这里插入图片描述

      B. 前导图法(Precedence Diagramming Method)
      在这里插入图片描述

    1. 估算活动资源

      –资源分解结构(resource breakdown structure)是一种层次结构,可以按照种类和类型确定项目的资源

    2. 估算活动工期

      –工期(duration):包括活动上花费的实际时间和占用时间

      –人工量(effort):完成任务所需要的工作天数或者工作小时

      –三点估算(Three-Point Estimates):包括乐观、最可能和悲观的估算

    3. 制订进度

      –甘特图(Gantt Charts):提供了一套显示项目进度信息的标准格式,通过以日历的模式列出项目活动及其相应的起止日期

      –关键路径法(Critical Path Method):是一种网络图技术,用于预测整个项目的工期。项目的关键路径决定了项目最早完成时间的活动序列,是网络图的最长路径。

      –一些概念:
      A. 计算关键路径:找出工期最长的路径
      B. 自由时差(free slack)或自由浮动时间(free float):紧后工作最早开始时间-本工作的最早结束时间
      C. 总时差(total slack)或浮动时间(total float):min(最迟结束时间-最早结束时间,最迟开始时间-最早开始时间)
      D. 使用关键路径来缩短项目的进度:赶工(crashing)、快速跟进(fast tracking)
      在这里插入图片描述
      –关键链调度(Critical Chain Scheduling):一种进度计划方法,在创建项目进度时考虑有限的资源,并且将缓冲包括进来以保护项目。使用约束理论(Theory of Constraints);将多任务(multitasking)最小化

      –计划评审技术(Program Evaluation and Review Technique,PERT)
      在这里插入图片描述

    1. 进度控制的建议(Schedule Control Suggestion)

      –按计划执行现实性检查

      –允许突发事件

      –不要计划让所有人都始终以100%的量工作

      –与干系人举行进度会议,并在沟通进度问题时保持清楚诚实

    展开全文
  • 体验TAPD软件的功能,并做出产品特色的报告。 整理出TAPD软件支持的业务以及内含的实用工具。 第三次团队作业: 撰写“收集需求”的方法文档。 主要对问卷调查这个收集需求的方法进行深挖。 总结问卷调查方法的...
  • IT项目管理》总结:项目沟通管理

    千次阅读 2009-10-21 22:37:00
    10/21/2009 10:33:15 PM 沟通失败常常是项目——特别是IT项目——成功的最大的威胁。沟通是保持项目顺利进行的润滑剂。沟通计划编制包括信息发送、绩效报告和管理收尾,它需要确定项目干系人的信息和沟通需求。沟通...
  • 完成作业的过程中,我总结出了一些项目管理经验如下。 需求控制 在项目开发过程中,需求的影响非常大。项目经理在项目开始阶段就应当整理出明确、详细、清晰的需求,舍弃模糊、不必要的需求。每个需求既要满足用户,...
  • 报告简要回顾我在整个项目中的参与情况,详细描述我的开发任务(技术报告),并讨论一些心得体会。 项目参与过程 作业一:参与第一次小组会议,共同确定了要实现的产品及其主要功能,明确了小组内分工。 作业...
  • IT项目管理表格

    2013-10-25 10:21:51
    导言.IT项目的生命期 第一章.IT项目的启动阶段 1.1 可行性研究报告框架 1.2 项目章程 1.3 项目整体风险水平...4.13 最终项目内部总结报告模板 4.14 最终项目用户移交报告模板 附录.项目管理主要网站 参考文献
  • it项目管理表格.zip

    2019-09-19 11:17:47
    文档: 第一章.IT项目的启动阶段 1.1 可行性研究报告框架 1.2 项目章程 1.3 项目整体风险水平定性分析表 1.4 多项目风险情况一览表 ...4.13 最终项目内部总结报告模板 4.14 最终项目用户移交报告模板
  • IT项目管理

    2013-03-20 08:34:27
    假如现在让我写一份关于IT项目管理的报告,我该怎样写?我能写出什么样的水平?  我觉得 IT项目管理是项目管理中一个很难的版块,它会比一般的项目管理难一点。 IT项目管理类似于传统的项目的管理,又不同于传统...
  • IT项目管理模板

    2012-09-04 09:26:17
    操作手册(GB8567——88).doc 测试分析报告(GB8567——88).doc 测试计划(GB8567——88).doc 概要设计说明书(GB8567——88).doc ...项目开发总结报告(GB8567——88).doc 用户手册(GB8567——88).doc
  • IT项目管理表格下载

    2010-04-19 17:27:53
    │ 4.13 最终项目内部总结报告模板.doc │ 4.14最终项目用户移交报告模板.doc │ 4.2 IT项目产品质量评审表.doc │ 4.3 软件验收单.doc │ 4.4 设备验收单.doc │ 4.5 IT项目内部验收报告模板.doc │ 4.6 最终项目...
  • IT软件项目管理表格

    热门讨论 2010-07-28 10:16:47
    目 录 导言.IT项目的生命期 第一章.IT项目的启动阶段 1.1 可行性研究报告框架 1.2 项目章程 1.3 项目整体风险水平定性...4.13 最终项目内部总结报告模板 4.14 最终项目用户移交报告模板 附录.项目管理主要网站
  • it项目验收--流程

    2013-12-03 14:18:00
    IT项目验收流程 IT项目验收流程说明 由于IT项目验收一般均比较复杂,因此,一般将IT项目的验收划分为四个阶段:验收准备、初步验收、最终验收、报告总结。(见划分请参见...
  • 这些实践包括:1,使用inch-pebbles进行工作量评估2,使项目组成员的状态可见,促使项目成员及时报告自己的状态,帮助他们解决问题,而不是追问进度。评估任何他们提交的东西,并给予及时的反馈和意见。3,如果必须...
  • IT项目管理开发文档

    2011-01-17 14:03:33
    操作手册、测试分析报告、测试计划、、概要设计说明书、开发进度月报、可行性研究报告、模块开发卷宗、软件需求说明书、数据库设计说明书、数据...的实例、详细设计说明书、项目开发计划、项目开发总结报告、用户手册
  • 华润集团IT规划报告

    2011-01-16 19:53:10
    华润集团IT规划报告.润联给华润做的,共51页,包含了项目实施,项目规划,经验总结,未来目标等各方面内容
  • it项目管理表格(各阶段)

    热门讨论 2008-11-20 16:42:45
    目 录 导言.IT项目的生命期 第一章.IT项目的启动阶段 1.1 可行性研究报告框架 1.2 项目章程 ...4.13 最终项目内部总结报告模板 4.14 最终项目用户移交报告模板 附录.项目管理主要网站 参考文献
  • │ 4.13 最终项目内部总结报告模板.doc │ 4.14最终项目用户移交报告模板.doc │ 4.2 IT项目产品质量评审表.doc │ 4.3 软件验收单.doc │ 4.4 设备验收单.doc │ 4.5 IT项目内部验收报告模板.doc │ 4.6 最终项目...
  • it程序员月工作总结精选范文 光阴如梭,x月份工作转瞬即将成为历史,身为程序员现对月工作做出如下总结,欢迎大家阅读~ it程序员月工作总结精选范文 1、正义erp项目的编码工作。从了解新疆正义项目的背景、及计划...

空空如也

空空如也

1 2 3 4 5
收藏数 93
精华内容 37
关键字:

it项目总结报告