Spring MVC 4 - Ajax请求

1.返回json
2.Ajax请求
3.多视图输出
4.MyBatis使用

这是一个Spring MVC 4 实现Ajax 的 post请求用户信息的Demo.
纯注解配置。

1.工程结构

这里写图片描述

2.pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.jeiker.demo</groupId>
  <artifactId>springdemo</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>

  <name>springdemo Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <jdk.version>1.8</jdk.version>
    <spring.version>4.2.2.RELEASE</spring.version>
    <jackson.version>2.8.5</jackson.version>
    <logback.version>1.1.7</logback.version>
    <jcl.slf4j.version>1.7.21</jcl.slf4j.version>
    <jstl.version>1.2</jstl.version>
    <servletapi.version>3.1.0</servletapi.version>
    <junit.version>3.8.1</junit.version>
  </properties>

  <dependencies>
    <!-- 单元测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>

    <!-- spring-webmvc 排除日志依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <!-- json转对象 ,对象转json -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson.version}</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>

    <!-- view层的 jsp标准函数库 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>

    <!-- 日志 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>${jcl.slf4j.version}</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>${logback.version}</version>
    </dependency>

    <!-- 仅在编译时使用, 布署不用,布署时容器会提供 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${servletapi.version}</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

  <build>
    <finalName>springdemo</finalName>

    <plugins>

      <!--编译插件-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>${jdk.version}</source>
          <target>${jdk.version}</target>
        </configuration>
      </plugin>

      <!-- 部署至本机 -->
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.3.9.v20160517</version>
        <configuration>
          <httpConnector>
            <port>8080</port>
          </httpConnector>
          <webAppConfig>
            <contextPath>/</contextPath>
          </webAppConfig>
        </configuration>
      </plugin>

    </plugins>
  </build>

</project>

3.spring配置文件

这里使用了java代码配置的方式:

package com.jeiker.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * @Author : xiao
 * @Date : 16/12/21 下午3:07
 */
@EnableWebMvc
@Configuration
@ComponentScan({"com.jeiker.web"})
public class SpringWebConfig extends WebMvcConfigurerAdapter{

    /**
     * 资源访问处理器:注册资源文件
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    /**
     * 视图解析器:配置JSP文件作为视图
     */
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/jsp/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }
}

4.servlet配置文件

package com.jeiker.servlet3;

import com.jeiker.config.SpringWebConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * 使用java config 代替 xml config
 */
public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { SpringWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

5.MVC相关文件

5.1 Model

AjaxResponseBody.java (ajax响应的模型)

package com.jeiker.web.model;

import com.fasterxml.jackson.annotation.JsonView;
import com.jeiker.web.view.Views;

import java.util.List;

/**
 * 返回参数模型
 */
public class AjaxResponseBody {

    @JsonView(Views.Public.class)
    String msg;
    @JsonView(Views.Public.class)
    String code;
    @JsonView(Views.Public.class)
    List<User> result;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public List<User> getResult() {
        return result;
    }

    public void setResult(List<User> result) {
        this.result = result;
    }

    @Override
    public String toString() {
        return "AjaxResponseBody { msg=" + msg + ", code=" + code + ", result=" + result + " }";
    }
}

SearchCriteria.java (查询用户的入参模型)

package com.jeiker.web.model;

/**
 * 入参模型
 */
public class SearchCriteria {

    String username;
    String email;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

User.java (用户模型实体)

package com.jeiker.web.model;

import com.fasterxml.jackson.annotation.JsonView;
import com.jeiker.web.view.Views;

/**
 * 用户模型,实体模型
 */
public class User {

    @JsonView(Views.Public.class)
    String username;

    String password;

    @JsonView(Views.Public.class)
    String email;

    @JsonView(Views.Public.class)
    String phone;

    @JsonView(Views.Public.class)
    String address;

    public User() {

    }

    public User(String username, String password, String email, String phone, String address) {
        super();

        this.username = username;
        this.password = password;
        this.email = email;
        this.phone = phone;
        this.address = address;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User {username=" + username + ", password=" + password + ", email=" + email + ", phone=" + phone +
                ", address=" + address + "}";
    }
}

5.2 Controller

WelcomeController.java (欢迎界面的Controller)

package com.jeiker.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @Author : xiao
 * @Date : 16/12/21 下午3:49
 */
@Controller
public class WelcomeController {

    /**
     * "/"路径,GET请求映射,返回welcome.jsp
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String printWelcome(ModelMap model) {
        return "welcome";
    }
}

AjaxController.java (Ajax请求的Controller)

package com.jeiker.web.controller;

import com.fasterxml.jackson.annotation.JsonView;
import com.jeiker.web.model.AjaxResponseBody;
import com.jeiker.web.model.SearchCriteria;
import com.jeiker.web.model.User;
import com.jeiker.web.view.Views;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author : xiao
 * @Date : 16/12/21 下午3:49
 */
@RestController
public class AjaxController {

    List<User> userList;

    /**
     * @ResponseBody 不再需要,当前类已经注解为 @RestController
     * @ResponseBody :将对象(AjaxResponseBody)转为json数据,返回给前端
     * @RequestBody :将前端请求的json数据转换为对象(SearchCriteria)
     * @JsonView(Views.Public.class) :可选,限制返回给前端的json数据字段(不返回密码等)
     */
    @JsonView(Views.Public.class)
    @RequestMapping(value = "/search/api/getSearchResult")
    public AjaxResponseBody getSearchResultViaAjax(@RequestBody SearchCriteria search) {
        AjaxResponseBody result = new AjaxResponseBody();

        if (isValidSearchCriteria(search)) {

            List<User> users = findByUserNameOrEmail(search.getUsername(), search.getEmail());

            if (users.size() > 0) {
                result.setCode("200");
                result.setMsg("");
                result.setResult(users);
            } else {
                result.setCode("204");
                result.setMsg("No user!");
            }

        } else {
            result.setCode("400");
            result.setMsg("Search criteria is empty!");
        }

        // AjaxResponseBody 模型将会转化为json数据,并返回给前端.
        return result;
    }

    /**
     * 检查入参是否有效
     */
    private boolean isValidSearchCriteria(SearchCriteria search) {

        boolean valid = true;

        if (search == null) {
            valid = false;
        }
        if ((StringUtils.isEmpty(search.getUsername())) && (StringUtils.isEmpty(search.getEmail()))) {
            valid = false;
        }

        return valid;
    }

    /**
     * 初始化一些用户数据作测试
     */
    @PostConstruct
    private void iniDataForTesting() {

        userList = new ArrayList<User>();

        User user1 = new User("jeiker", "pass123", "jeiker@126.com", "110-1234567", "address 123");
        User user2 = new User("xiao", "pass456", "xiao@163.com", "119-1234567", "address 456");
        User user3 = new User("xiaoxiao", "pass789", "jeikerxiao@qq.com", "120-1234567", "address 789");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
    }

    /**
     *  查询用户的方法
     */
    private List<User> findByUserNameOrEmail(String username, String email) {

        List<User> result = new ArrayList<User>();

        for (User user : userList) {
            if ((!StringUtils.isEmpty(username)) && (!StringUtils.isEmpty(email))) {
                if (username.equals(user.getUsername()) && email.equals(user.getEmail())) {
                    result.add(user);
                    continue;
                } else {
                    continue;
                }

            }
            if (!StringUtils.isEmpty(username)) {
                if (username.equals(user.getUsername())) {
                    result.add(user);
                    continue;
                }
            }
            if (!StringUtils.isEmpty(email)) {
                if (email.equals(user.getEmail())) {
                    result.add(user);
                    continue;
                }
            }
        }
        return result;
    }
}

5.3 View

View.java (视图模型,结合User模型看,注意@JsonView(Views.Public.class))

package com.jeiker.web.view;

/**
 * @Author : xiao
 * @Date : 16/12/21 下午3:36
 */
public class Views {
    public static class Public {}
}

6.前端界面

welcome.jsp

<%@page session="false"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>
<html lang="en">
<head>
<title>Spring MVC 4 + Ajax Hello World</title>

<c:url var="home" value="/" scope="request" />

<spring:url value="/resources/core/css/hello.css" var="coreCss" />
<spring:url value="/resources/core/css/bootstrap.min.css" var="bootstrapCss" />
<link href="${bootstrapCss}" rel="stylesheet" />
<link href="${coreCss}" rel="stylesheet" />

<spring:url value="/resources/core/js/jquery.1.10.2.min.js" var="jqueryJs" />
<script src="${jqueryJs}"></script>

</head>

<nav class="navbar navbar-inverse">
    <div class="container">
        <div class="navbar-header">
            <a class="navbar-brand" href="#">Spring 4 MVC Ajax Hello World</a>
        </div>
    </div>
</nav>

<div class="container" style="min-height: 500px">

    <div class="starter-template">
        <h1>Search Form</h1>
        <br>

        <div id="feedback"></div>

        <form class="form-horizontal" id="search-form">
            <div class="form-group form-group-lg">
                <label class="col-sm-2 control-label">Username</label>
                <div class="col-sm-10">
                    <input type=text class="form-control" id="username">
                </div>
            </div>
            <div class="form-group form-group-lg">
                <label class="col-sm-2 control-label">Email</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="email">
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" id="bth-search"
                        class="btn btn-primary btn-lg">Search</button>
                </div>
            </div>
        </form>

    </div>

</div>

<div class="container">
    <footer>
        <p>
            &copy; <a href="#">jeikerxiao.com</a> 2016
        </p>
    </footer>
</div>

<script>
    jQuery(document).ready(function($) {

        $("#search-form").submit(function(event) {

            // 关闭搜索按钮
            enableSearchButton(false);

            // 当点击搜索按钮时阻止对表单的提交
            event.preventDefault();

            // ajax请求后台
            searchViaAjax();

        });

    });

    // ajax请求后台
    function searchViaAjax() {

        var search = {};
        search["username"] = $("#username").val();
        search["email"] = $("#email").val();

        $.ajax({
            type : "POST",
            contentType : "application/json",
            url : "${home}search/api/getSearchResult",
            data : JSON.stringify(search),
            dataType : 'json',
            timeout : 100000,
            success : function(data) {
                console.log("SUCCESS: ", data);
                display(data);
            },
            error : function(e) {
                console.log("ERROR: ", e);
                display(e);
            },
            done : function(e) {
                console.log("DONE");
                enableSearchButton(true);
            }
        });

    }

    // 控制搜索按钮的点击
    function enableSearchButton(flag) {
        $("#btn-search").prop("disabled", flag);
    }

    // 显示后台返回的json数据
    function display(data) {
        var json = "<h4>Ajax Response</h4>"
                    + "<pre>"
                    + JSON.stringify(data, null, 4)
                    + "</pre>";
        $('#feedback').html(json);
    }
</script>

</body>
</html>

7.运行结果

jetty:run 运行

7.1 运行配置

这里写图片描述

7.2 Post测试

使用Postman工具查看:
这里写图片描述

7.3 前端效果

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值