springMVC+maven+mybatis+mysql入门

(六)利用ajax和后台交互

这一小节,我们主要实现页面和后台简单的数据交互,初步掌握这个交互流程

页面主要采用ajax技术往后台发数据,后台就使用上一节我们写好的工程代码(五)最简单的springMVC后台程序
关于jquery,ajax这些基础理论,这里就不多讲了,简单使用的话,没什么难度,有需求的请自行百度。

首先,为了这一节的讲解,我们需要新建一些文件和目录。
1.引入jquery*
这个简单,只需要到jquery官网去把jquery.js文件下回来,引入代码即可。这里我们在 src/main/webapp 下创建一个resources文件夹,在这个文件夹下边,创建一个jquery文件夹,把从官网下回来的jquery.js拷贝到这里面,我这里用的是 jqery-3.3.1.js
2.创建一个hello目录,在里面创建一个hello.js和hello.css两个文件,暂时保持空文件,后面再来添加内容。
3.在WEB-INF下面创建一个pages文件夹,然后在这个文件夹里,创建一个hello.jsp。
创建完成后,目录结构如下:


目录结构.png

这里我们为了演示,做了一个比较完整的结构,hello.jsp是我们需要访问的页面,hello.js提供脚本支持,hello.css提供样式支持,常规工程也基本就是这样了,可能就是目录结构的差异

好了,现在我们在填写内容,具体细节暂时不讨论,jsp相关的知识点请自行百度学习。
首先,hello.jsp的代码如下

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>HelloJsp</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <script type="text/javascript" src="<%=basePath%>resources/jquery/jquery-3.3.1.js"></script>
    <script type="text/javascript" src="<%=basePath%>resources/hello/hello.js">
    
    </script>
    <script type="text/javascript">
    var basePath = "<%=basePath%>";
    </script>
    <link rel="stylesheet" type="text/css" href="<%=basePath%>resources/hello/hello.css">
    
  </head>
  
  <body>
    This is my first jsp page. <br>
    
    <br/>
    my hello
    <br/>
    <div class="mydiv">
        <input id="myInput"></input>      
        <button class="mybutton" id="getButton">Get</button>
    </div>
  </body>
</html>

这个页面部分代码是自动生成的时候留下的,先不管它,就这样写满足我们的需求即可
其中的

    <script type="text/javascript" src="<%=basePath%>resources/jquery/jquery-3.3.1.js"></script>
    <script type="text/javascript" src="<%=basePath%>resources/hello/hello.js">

引入了jquery和js
然后,我们在页面上画了一个输入框和一个按钮

<div class="mydiv">
        <input id="myInput"></input>      
        <button class="mybutton" id="getButton">Get</button>
    </div>

后面的学习和测试,都是围绕这个输入框和按钮来进行。

然后,hello.js这样写

$("document").ready(function(){ 
    $("#getButton").click(function(){
        let id = $("#myInput").val();
        $.ajax({
            url:basePath+"/firstGet/"+id,
            type:'GET',
            dataType:'text',
            contentType:'application/json',
            success:function(result){
                $("#myInput").val(result);
            }
        })      
    }); 
});

简单的,典型的,基于jquery的一个js代码。
点击button,向后端服务器发送一个get请求,然后将后端的返回值,填写到输入框。
至于ajax的相关问题,请大家自行百度学习,这里写的是很简单的。

好了,然后我们在hello.css中加入内容

.mydiv{
    display:flex;
    flex-direction:column;
    width:400px;
    height:600px;
}
.mybutton{
    width:100px;
}

不擅长写样式,简单的写一下,达到演示的目的即可。

好,我们的页面文件已经准备好了,现在修改一下后端代码。

在上面ajax中,我们发出去的请求是

url:basePath+"/firstGet/"+id,

在controller中要处理的uri就是 /firstGet/{id} 其中的{id}指的就是我们从input获取到的id,这个是目前流行的restful风格的写法,按照以前的写法已经改是/firstGet/id?id=xxx这样,我们顺应潮流,按照流行的方式来,当然,正是项目肯定不能取 firstGet 这样的名字,这里为了演示,不用太严谨。
controller需要处理这个,DemoController 代码修改后如下:

package com.springstart.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class DemoController {

    @RequestMapping(value="/hello",method=RequestMethod.GET)
    public String myFirstController(){
        System.out.println("some one call MyFirstController");
        return "hello";
    }
    
    @ResponseBody
    @RequestMapping(value="/firstGet/{id}",method=RequestMethod.GET)
    public String myFirstGet(@PathVariable("id") String id){
        System.out.println("from page id:"+id);
        return "Right "+id;
    }   
}

在新的方法上,多了一个注解 @ResponseBody 这个是注解的作用是把返回值写入 HTTP response body 中,便于ajax接收,这也是使用ajax发送请求接收数据的常规方式。
好了,代码完成了,加载到tomcat中,跑起来试试。
在浏览器中,输入
http://localhost:8080/springstart/hello
将会把hello.jsp这个页面展示给我们

hello.png

感觉不对呢,我们写的css明明是 flex-column,没有生效呢
在输入框中输入一个数字,然后点 Get,没有反应
这个时候,需要进行页面调试了,在Chrome或者Firefox中按F12(IE不怎么用不知道),调出调试页面,在console一栏可以看到报错了
error.png

没找到jquery,css,js文件
这个就是涉及一个问题,我们在web.xml中对DispatcherServlet设置的拦截规则是/,表示拦截一切请求,那么对静态资源的请求,也会被拦截,这样就找不到对应的controller来处理,从而报了404找不到的错误。
对于这个问题,比较简洁的解决办法有两个
1.在resources/config/mymvc.xml中添加一个配置

<mvc:default-servlet-handler />

这句话的内在意思比较复杂,完全可以写一篇文章来说明,需要深入了解的自行百度,就这样配置后,就可以访问到静态资源了。
2.在resources/config/mymvc.xml中添加一个配置

<mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources>

这个配置直接定位到resources,resources下面的文件都被注册为资源,这样servlet就会处理了。这个配置方式定位精确,resources之外的静态资源,依然不能访问。

上面两个方法都有效,以实际需求为准。
加上这个配置之后,重新启动tomcat,依然访问
http://localhost:8080/springstart/hello
结果。。。访问不了了。。。
因为增加了上面的配置后,默认加载的来处理注解@RequestMapping的handler就没有了,这样就无法处理这个注解,也就无法将http请求URI对应到我们的controller上面去
需要增加一个注解

<mvc:annotation-driven />

启用对 @RequestMapping的处理,这样就可以了,而这个配置,一般在spring mvc项目中,都是需要的。

目前到这里,mymvc.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc.xsd
                        http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <context:component-scan base-package="com.springstart.*"></context:component-scan>
    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    
    <!-- <mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources>  -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

这样,启动tomcat,就可以访问到hello.jsp了


hello.png

设定的flex样式,也生效了,按f12,没有报错。
在输入框输入字符串,点击 Get,输入框会回显Right加上输入的字符串。
最基本的一个交互功能完成。

前面我们写的ajax里面有一个

type:'GET',

表示我们这个请求是一个get请求
在controller中,我们对应的处理方法有注解method=RequestMethod.GET,就是处理GET的请求。
关于请求的类型,大致常规的有 GET POST PUT DELETE,还有一些其他的,常规的开发过程很难用到,暂时不谈。
一般说来
GET 表明根据请求链接,从服务器获取一定的信息
DELETE 表明删除一定信息
POSTPUT不好区分,都是给服务端发送信息过去,服务端的处理方式有一些差异。
POST 每次给过来的信息都会存起来,POST两次,就存两条记录
PUT 每次给过来的信息以更新方式存起来,不管执行多少次,只影响一条记录。

这里就要引入一个概念 幂等,在http请求这一块, 幂等表达的就是同一个请求,不管执行多少次,对服务器的影响都是相同的,或者指一次和多次请求某一个资源应该具有同样的结果。
举例来说
GET ,get一个name=Jack的人的id,只要没有人修改数据库,不管我们执行多少次,返回的id都是一样的,这是 幂等
DELETE,delete name=Jack,执行1次或多次,数据库里这条记录都会被删除,这是 幂等
PUT ,put表示更新,将name=Jack的年龄变更为20岁,不管执行多少次,数据库里这个人的年龄都会变成20,这是 幂等
POST,执行1次后数据库多一条记录,执行2次后,数据库多两条记录,这个不是幂等

好了,这些都是理论和常规用法。你当然也可以用get达到post的效果,这就非主流啦。
另外,页面开发这一块还涉及到浏览器版本问题,有些旧版本的浏览器不支持除GETPOST以外的方法,这一点在实际项目中可能需要考虑。

我们这里增加一个POST方法的演示,跟get方法很类似,只是数据不放在请求链接里。
首先在jsp页面增加一个post按钮

<div class="mydiv">
        <input id="myInput"></input>      
        <button class="mybutton" id="getButton">Get</button>
        <button class="mybutton" id="POSTButton">POST</button>
    </div>

在js中,增加对post按钮的处理

$("#POSTButton").click(function(){
        let id = $("#myInput").val();
        $.ajax({
            url:basePath+"/firstPost",
            data:id,
            type:'POST',
            dataType:'text',
            contentType:'application/json',
            success:function(result){
                $("#myInput").val(result);
            }
        })      
    }); 

在controller中增加一个处理这个post请求的方法

@ResponseBody
@RequestMapping(value="/firstPost",method=RequestMethod.POST)
public String myFirstPost(@RequestBody String msg){
    System.out.println("from page msg:"+msg);
    return "Good "+msg;
}

这里我们在参数体重增加了一个 @RequestBody注解,要获取POST过来的数据,同时类型是 application/json,就可以用这个注解来获取,我们把传过来的字符串写到msg里,很方便。

好了,基本的交互我们完成了,下一章会对post和get进行一个详细的讲解。
本章代码上传至 sprintStart github springStart_basic_2,请自行下载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容