终于来了。网络应用(第3部分)


我们已经踏上了漫长的软件开发旅程(here is the first article)在我们的虚拟场景中,您在一个开发团队中工作,而您的团队是一个更大的信息技术组织的一部分,并且您已经增强一些代码有一段时间了。它开始只是为了你自己。它可能只有一两个类和一个“main()”方法,但是很有用。

然后,随着时间的推移,它在自己的项目(ShapeCalculatorService)中发展成为一个可重用的组件,具有持久性(带有Hibernate的Spring Data JPA),并且目前在命令行应用程序中使用。

但是对于过去的两篇文章(herehere),并继续此操作,您已被要求为web启用该服务。换句话说,公开所有完全相同的命令行(菜单驱动)特性,但是在网页中。

返回用户界面(页面)

好了,我们终于准备好处理我们的用户界面了。

我想我们需要几页纸来处理:

  • 查看待定请求。

  • 查看计算结果。

  • 也可能是运行/查看结果的组合。

  • 显然,我们需要一个页面来创建请求。

  • 除了我们的索引页面之外的所有内容。

让我们添加一些页面。我从index.jsp复制并创造了pending.jsp、newreq.jsp和results.jsp。

以下是项目目前的情况:

Image title

您可以查看all of the code here

Index.jsp

我们希望我们的index.jsp成为所有其他页面的起点。

让我们回忆一下我们希望这是什么样子:

Image title

Image title

那种外观和感觉,那些标签是在 Bootstrap

我下载了他们的压缩文件,并将CSS和JS文件夹复制到项目的网络内容文件夹下的一个新的“资源”文件夹中。

对于我们想要的风格和标签,我们可以从这里开始w3schools.com。查找“可切换/动态选项卡”。

<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
  <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
  <li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
</ul>

<div class="tab-content">
  <div id="home" class="tab-pane fade in active">
    <h3>HOME</h3>
    <p>Some content.</p>
  </div>
  <div id="menu1" class="tab-pane fade">
    <h3>Menu 1</h3>
    <p>Some content in menu 1.</p>
  </div>
  <div id="menu2" class="tab-pane fade">
    <h3>Menu 2</h3>
    <p>Some content in menu 2.</p>
  </div>
</div>

让我们把以上加到我们的index.jsp。

经过尝试,我们的index.jsp看起来是这样的:

不好。看起来我们丢失了样式表信息。

在index.jsp的< head></head >部分添加以下内容:

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />

我们的下一次尝试也好不到哪里去。看看控制台输出,我们就知道为什么了:

警告:在名为' dispatcher vlet '的调度程序中,找不到与URI[/webapp-p2/resources/CSS/bootstrap . min . CSS]的HTTP请求的映射

WebConfig

我们需要添加以下内容:

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
          .addResourceHandler("/resources/**")
          .addResourceLocations("/resources/");
    }

构建后。部署。启动...

啊...是...好多了。

请注意,文本一直突出到边缘——不太好。我们需要解决这个问题。

Index.jsp

为此,请用以下内容包装我们现在在< body></body >中的所有内容:

<body>

<div class="container">
....   div block ....

</div>

</body>


集成页面

我们希望index.jsp成为一切的中心或焦点。因此,我们需要以某种方式让引导模板的各个< div >部分引用其他页面,或者允许我们嵌入它们。

我留下了原始的模板代码,并添加了我们需要的东西。

        <ul class="nav nav-tabs">
            <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
            <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
            <li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
            <li><a data-toggle="tab" href="#newreq" >Request Calculation</a></li>
            <li><a data-toggle="tab" href="#pening"  >Pending Requests</a></li>
            <li><a data-toggle="tab" href="#results" >Calculated Results</a></li>
        </ul>

        <div class="tab-content">
            <div id="home" class="tab-pane fade in active">
                <h3>HOME</h3>
                <p>Some content.</p>
            </div>
            <div id="menu1" class="tab-pane fade">
                <h3>Menu 1</h3>
                <p>Some content in menu 1.</p>
            </div>
            <div id="menu2" class="tab-pane fade">
                <h3>Menu 2</h3>
                <p>Some content in menu 2.</p>
            </div>

<!-------------------------------------------------------------------------------->
<!-------------------------------------------------------------------------------->
            <div id="newreq" class="tab-pane fade">
                <h3>Request Calculation</h3>
<!--  -->
                <div id="requestFrameDiv" 
                     class="embed-responsive embed-responsive-16by9">
                </div>
<!--  -->
            </div>

<!-------------------------------------------------------------------------------->
<!-------------------------------------------------------------------------------->
            <div id="pending" class="tab-pane fade">
                <h3>Show Current Requests</h3>
<!--  -->
                <div id="pendingFrameDiv" 
                     class="embed-responsive embed-responsive-16by9">
                </div>
<!--  -->
            </div>

<!-------------------------------------------------------------------------------->
<!-------------------------------------------------------------------------------->
            <div id="results" class="tab-pane fade">
                <h3>Run/List Calculations</h3>
<!--  -->
                <div id="resultsFrameDiv" 
                     class="embed-responsive embed-responsive-16by9">
                </div>
<!--  -->
            </div>


        </div>


看起来是这样的:

让我们换一个话题。让我们删除模板代码(“主页”、“菜单1”等)。)并添加我们自己的“主页”、“关于”

以下是选项卡更改(主页,关于)...

            <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
            <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>

 .... more code here....


<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="home" class="tab-pane fade in active">
                <h3>HOME</h3>
                <p>Wecome to The Shape Calculator</p>
                <p/>
                <p>
                This is a project that began as a result of a programming exercise.<br>
                It is probably non-sensical, but it was a good way to review/study<br>
                some technologies such as:
                </p>
                <p>HTML 5, CSS, JS, Bootstrap</p>
                <p>Spring MVC</p>
                <p>JPA / Hibernate / MySQL</p>
                <p>This is a complete web app, front to back</p>
                <p>(there is another that is a webapp client consuming a web service)</p>
            </div>

<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="about" class="tab-pane fade ">
                <h3>About/Usage</h3>
                <p>Wecome to The Shape Calculator</p>
                <p/>
                <p>
                If you first click on either <b>Current Requests</b> or <b>Run/List Results</b>,<br>
                you should not see much.  Once you do a <b>Request Calculation</b>, then <br>
                the requested calculation moves to a pending list. Once you do a <br>
                <b>Run/List..</b> then the pending calculation will disappear.<br>
                You can request multiple calculations, and they will create a list of<br>
                pending requests, and then you can run them all at the same time.<br>
                I purposely put in some random time for each calculation, to simulate<br>
                a long-running process.  I did not have time to add a 'busy' icon<br>
                in the Run/List page.. so you may just see a delay before anything<br>
                appears.
                </p>
                <p>Tested on Chrome 51.0.., IE 11.0.., and Firefox 37.0..
            </div>



此外,如果您尝试单击选项卡,它们不起作用。我们需要添加引导JS代码,并且引导依赖于JQuery。所以我们都需要。

确保在WebContent/resources/js文件夹中有npm.js、bootstrap.min.js(或bootstrap.js)和jquery-x . x . min . js(或jquery-x . x . x . x . js)。

然后,您需要在<标题> </head >部分中引用它们。

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />
<script src="${pageContext.request.contextPath}/resources/js/jquery-2.2.4.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/js/bootstrap.min.js"></script>

<title>Welcome To The Shape Calculator</title>

</head>


现在,当我们尝试它的时候,我们只看到我们需要的标签——并且它们起作用了。

注意:我正在使用引导3.3.6。当我尝试JQuery 3.1.0时,它似乎不起作用。当我尝试JQuery 2.2.4时,它成功了。您的里程可能会有所不同。


好的,我们知道标签是有效的。但是我们还没有加载和显示我们的新页面。

我确信还有其他方法可以做到这一点,但是我选择了动态地将子页面包含到带有一些脚本的iframes中。

    <script>
    function loadNewReqFrame() {
        $("#requestFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/newreq\'></iframe>");
    }
    </script>

    <script>
    function loadCurReqFrame() {
        $("#pendingFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/pending\'></iframe>");
    }
    </script>

    <script>
    function loadResultsFrame() {
        $("#resultsFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/results\'></iframe>");
    }
    </script>


我还必须更改标签标题部分,从这个:

<li><a data-toggle="tab" href="#newreq" >Request Calculation</a></li>
<li><a data-toggle="tab" href="#pending"  >Pending Requests</a></li>
<li><a data-toggle="tab" href="#results" >Calculated Results</a></li>


为此:

<li><a data-toggle="tab" href="#newreq" onClick="loadNewReqFrame()">Request Calculation</a></li>
<li><a data-toggle="tab" href="#pening" onClick="loadCurReqFrame()" >Current Requests</a></li>
<li><a data-toggle="tab" href="#results" onClick="loadResultsFrame()">Run/List Results</a></li>

这里是完整的index.jsp,直到我们的最新变化:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />
<script src="${pageContext.request.contextPath}/resources/js/jquery-2.2.4.min.js"></script>
<!--
<script src="${pageContext.request.contextPath}/resources/js/jquery-3.1.0.min.js"></script>
-->
<script src="${pageContext.request.contextPath}/resources/js/bootstrap.min.js"></script>

<title>Welcome To The Shape Calculator</title>

    <script>
    function loadNewReqFrame() {
        $("#requestFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/newreq\'></iframe>");
    }
    </script>

    <script>
    function loadCurReqFrame() {
        $("#pendingFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/pending\'></iframe>");
    }
    </script>

    <script>
    function loadResultsFrame() {
        $("#resultsFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/results\'></iframe>");
    }
    </script>

</head>
<body>
    <div class="container">

        <H1>Welcome : Static Index Page Text</H1>
        There should be a dynamic message here: [ ${message } ] but is there?

        <ul class="nav nav-tabs">
            <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
            <li><a data-toggle="tab" href="#about" >Usage</a></li>
            <li><a data-toggle="tab" href="#newreq" onClick="loadNewReqFrame()">Request Calculation</a></li>
            <li><a data-toggle="tab" href="#pending" onClick="loadCurReqFrame()" >Pending Requests</a></li>
            <li><a data-toggle="tab" href="#results" onClick="loadResultsFrame()">Calculated Results</a></li>
        </ul>

        <div class="tab-content">

<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="home" class="tab-pane fade in active">
                <h3>HOME</h3>
                <p>Wecome to The Shape Calculator</p>
                <p/>
                <p>
                This is a project that began as a result of a programming exercise.<br>
                It is probably non-sensical, but it was a good way to review/study<br>
                some technologies such as:
                </p>
                <p>HTML 5, CSS, JS, Bootstrap</p>
                <p>Spring MVC</p>
                <p>JPA / Hibernate / MySQL</p>
                <p>This is a complete web app, front to back</p>
                <p>(there is another that is a webapp client consuming a web service)</p>
            </div>

<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="about" class="tab-pane fade ">
                <h3>About/Usage</h3>
                <p>Wecome to The Shape Calculator</p>
                <p/>
                <p>
                If you first click on either <b>Current Requests</b> or <b>Run/List Results</b>,<br>
                you should not see much.  Once you do a <b>Request Calculation</b>, then <br>
                the requested calculation moves to a pending list. Once you do a <br>
                <b>Run/List..</b> then the pending calculation will disappear.<br>
                You can request multiple calculations, and they will create a list of<br>
                pending requests, and then you can run them all at the same time.<br>
                I purposely put in some random time for each calculation, to simulate<br>
                a long-running process.  I did not have time to add a 'busy' icon<br>
                in the Run/List page.. so you may just see a delay before anything<br>
                appears.
                </p>
                <p>Tested on Chrome 51.0.., IE 11.0.., and Firefox 37.0..
            </div>


<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="newreq" class="tab-pane fade">
                <h3>Request Calculation</h3>
<!--  -->
                <div id="requestFrameDiv" class="embed-responsive embed-responsive-16by9">
                </div>
<!--  -->
            </div>

<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="pending" class="tab-pane fade">
                <h3>Pending Requests</h3>
<!--  -->
                <div id="pendingFrameDiv" class="embed-responsive embed-responsive-16by9">
                </div>
<!--  -->
            </div>

<!------------------------------------------------------------------------------------>
<!------------------------------------------------------------------------------------>
            <div id="results" class="tab-pane fade">
                <h3>Calculated Results</h3>
<!--  -->
                <div id="resultsFrameDiv" class="embed-responsive embed-responsive-16by9">
                </div>
<!--  -->
            </div>


        </div>

    </div>

</body>
</html>


如果你现在尝试,你会注意到“家庭”和“使用”是有效的,但是另外三个有不同的结果:

请注意,我们看到一些404未发现的错误,但我们也看到一些有效的超文本标记语言。404出现在iframes内部。

为什么一个标签有效,而其他标签无效?

以下是控制台输出:

2016年9月9日上午1:16:27

警告:在名为“DispatcherServlet”的调度器中找不到URI为[/webapp-p2/results]的HTTP请求的映射

2016年9月9日上午1:17:21

警告:在名为“调度者资源集”的调度者资源集中找不到URI为[/webapp-p2/newreq]的HTTP请求的映射

我们将“待定请求”映射到哪里了打开RequestResponseController类。

你会看到一个方法,你会看到:

@ RequestMapping(value =/pending),方法=RequestMethod。获取)

“/pending”与您在Javascript内部索引中看到的内容相匹配。

<script>
function loadCurReqFrame() {
    $("#pendingFrameDiv").html("<iframe src=\'${pageContext.request.contextPath}/pending\'></iframe>");
}
</script>

让我们添加到请求响应控制器:

    @RequestMapping(value="/newreq",method=RequestMethod.GET)
    public ModelAndView newreq() {

        System.err.println("\n\n\nNew Request\n\n\n");

        return new ModelAndView("/newreq","message","New Request Page: message from Controller");

    }

    @RequestMapping(value="/results",method=RequestMethod.GET)
    public ModelAndView results() {

        System.err.println("\n\n\nCalculated Results\n\n\n");

        return new ModelAndView("/results","message","Calculated ResultsPage: message from Controller");

    }


当你现在尝试的时候,所有的标签都应该是一样的。

获取最新代码

你可以go here获取最新版本的代码。

后续步骤

我们已经走了很长的路。我们即将完成这一轮形状计算器的网络应用。在控制器中,我们将添加使用计算器所需的代码,仅此而已。反对...

我们需要能够将未决请求和计算结果的列表返回给JSP,我们还需要创建一个新的请求。我们需要一个表格。

所以,请继续关注下一篇文章!