SpringMvc 從 Body 中獲取數據的接口開發方式


目前網站開發基本上都是采用前后端分離,所以對於 SpringMvc 來說,大部分情況下可能主要是開發接口,接收靜態 html 頁面發送來的請求數據,將處理后的數據返回給調用者。在前面的博客中,已經介紹過了許多接收請求數據的方式,其實已經夠用了。但是接收請求數據的方式還有很多,而且技術也在不斷的發展演變,因此有必要學習更多的接口開發方式。

本篇博客主要介紹從請求 body 中接收數據的接口開發方式,后續會介紹 restful 風格接口的開發方式,掌握了這些接口開發方式后,基本上就可以應對企業中的各種開發場景了。本篇博客的 Demo 做的很簡單,在博客的最后會提供 Demo 源代碼下載。


一、搭建工程

新建一個 maven 項目,導入相關 jar 包,我所導入的 jar 包都是最新的,內容如下:

有關具體的 jar 包地址,可以在 https://mvnrepository.com 上進行查詢。

<dependencies>
    <!--導入 servlet 相關的 jar 包-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>

    <!--導入 Spring 核心 jar 包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.18</version>
    </dependency>
    <!--導入 SpringMvc 的 jar 包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.18</version>
    </dependency>

    <!--導入 jackson 相關的 jar 包-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.13.1</version>
    </dependency>
</dependencies>

配置好引用的 jar 包后,打開右側的 Maven 窗口,刷新一下,這樣 Maven 會自動下載所需的 jar 包文件。

搭建好的項目工程整體目錄比較簡單,具體如下圖所示:

image

項目工程結構簡單介紹:

com.jobs.config 包下存儲的是 SpringMvc 的配置文件和 Servlet 的初始化文件
com.jobs.controller 包下存儲的是用於提供 api 接口的類
com.jobs.domain 包下存儲的是 JavaBean 實體類

web 目錄下放置的是網站文件,只有一個靜態頁面和一些 js 文件


二、SpringMvc 配置相關

com.jobs.config 下的 SpringMvcConfig 類是 SpringMvc 的配置類,具體內容如下:

package com.jobs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

@Configuration
@ComponentScan("com.jobs")
//啟用 mvc 功能,配置了該注解之后,SpringMvc 攔截器放行相關資源的設置,才會生效
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {

    //配置 SpringMvc 連接器放行常用資源的格式(圖片,js,css)
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    //配置響應數據格式所對應的數據處理轉換器
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        //如果響應的是 application/json ,則使用 jackson 轉換器進行自動處理
        MappingJackson2HttpMessageConverter jsonConverter =
                        new MappingJackson2HttpMessageConverter();
        jsonConverter.setDefaultCharset(Charset.forName("UTF-8"));
        List<MediaType> typelist1 = new ArrayList<>();
        typelist1.add(MediaType.APPLICATION_JSON);
        jsonConverter.setSupportedMediaTypes(typelist1);
        converters.add(jsonConverter);

        //如果響應的是 text/html 和 text/plain ,則使用字符串文本轉換器自動處理
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
        stringConverter.setDefaultCharset(Charset.forName("UTF-8"));
        List<MediaType> typelist2 = new ArrayList<>();
        typelist2.add(MediaType.TEXT_HTML);
        typelist2.add(MediaType.TEXT_PLAIN);
        stringConverter.setSupportedMediaTypes(typelist2);
        converters.add(stringConverter);
    }

    //注解配置 SpringMvc 返回配置的字符串所表示的頁面,從哪些去找
    //可以注釋掉下面的方法,這樣需要在 SpringMvc 方法返回時,指定全局路徑的頁面地址
    //這里配置的是:根據 SpringMvc 方法返回的字符串,到 /WEB-INF/pages/ 下找對應名稱的 jsp 頁面
    @Bean
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        //如果頁面需要使用JSTL標簽庫的話
        //viewResolver.setViewClass(JstlView.class);
        return viewResolver;
    }
}

ServletInitConfig 類初始化 Servlet 容器,裝載 SpringMvc 的配置,具體如下:

package com.jobs.config;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.EnumSet;

public class ServletInitConfig extends AbstractDispatcherServletInitializer {

    //初始化 Servlet 容器,加載 SpringMvc 配置類
    //創建 web 專用的 Spring 容器對象:WebApplicationContext
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext cwa = new AnnotationConfigWebApplicationContext();
        cwa.register(SpringMvcConfig.class);
        return cwa;
    }

    //注解配置 SpringMvc 的 DispatcherServlet 攔截地址,攔截所有請求
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    //在servlet容器啟動時進行配置
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //這行代碼不能省略
        super.onStartup(servletContext);

        //設置【獲取到的請求】的統一字符編碼過濾器,
        //無論是【請求、轉發、包含】統一使用 UTF-8 編碼
        CharacterEncodingFilter cef = new CharacterEncodingFilter();
        cef.setEncoding("UTF-8");
        //注意:這里的過濾器名稱必須是 characterEncodingFilter
        FilterRegistration.Dynamic registration =
                       servletContext.addFilter("characterEncodingFilter", cef);
        registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST,
                       DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "/*");
    }
}

上面這些 SpringMvc 純注解搭建的細節,沒有任何變化,我直接從之前編寫的博客中抄了一下,估計看過我之前博客的小伙伴們,已經看吐了。其實 SpringMvc 純注解搭建,本來就很簡單,但是為了保持博客文章的完整性,我還是得保留這些內容。


三、接口開發介紹

還是首選介紹一下 domian 下的 Employee 實體類,具體內容如下:

package com.jobs.domain;

import java.io.Serializable;
import java.util.List;

public class Employee implements Serializable {

    //姓名
    private String name;
    //年齡
    private Integer age;

    public Employee() {
    }

    public Employee(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    //這里省略了相關字段的 get 和 set 方法...

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

然后列出從請求的 body 中獲取數據的接口開發方式,內容如下:

package com.jobs.controller;

import com.jobs.domain.Employee;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//由於接口開發,都是返回數據,不返回頁面,所以直接使用 @RestController 注解
@RequestMapping("/api")
@RestController
public class ApiController {

    //這里主要演示普通的接口開發,主要通過 ajax 請求調用這里的接口

    //請求 body 中發過來文本類型的數據
    @RequestMapping(value = "/test1", produces = "text/plain")
    public String testApi1(@RequestBody String text) {
        System.out.println("接收了發來的文本數據:" + text);
        return "成功接收到數據:" + text;
    }

    //請求的 body 中發來的是 Json 數據,
    //並且 Json 數據中的字段名稱與 Java 實體類中的字段名稱一致
    //此時可以采用 Java 實體類接收 Json 數據,SpringMvc 會自動賦值處理
    @RequestMapping(value = "/test2", produces = "application/json")
    public Employee testApi2(@RequestBody Employee emp) {
        System.out.println("接收了發來的單個 Json 對象數據,自動封裝成對象:");
        System.out.println(emp);

        System.out.println("我們對 emp 進行修改,然后返回給調用者,修改后的結果為:");
        emp.setName(emp.getName() + "111");
        emp.setAge(emp.getAge() + 10);
        System.out.println(emp);

        return emp;
    }

    //請求的 body 中發來的是 Json 數組數據,
    //數組中每個 Json 對象的字段名稱與 Java 實體類中的字段名稱一致
    //此時可以采用 Java 實體類集合接收,SpringMvc 會自動賦值處理並轉換為集合
    @RequestMapping(value = "/test3", produces = "application/json")
    public List testApi3(@RequestBody List<Employee> emplist) {
        System.out.println("接收了發來的單個 Json 數組對象數據,自動封裝成對象集合:");
        System.out.println(emplist);

        System.out.println("我們在 emplist 中增加一個 Employee 對象,然后返回給調用者:");
        emplist.add(new Employee("喬豆豆", 38));
        System.out.println(emplist);

        return emplist;
    }

    //使用 @CrossOrigin 開啟跨域訪問
    //如果 @CrossOrigin 標注在方法上,方表示該方法支持跨域訪問
    //如果 @CrossOrigin 標注在 Controller 類上,表示該類中的所有方法均支持跨域訪問
    @CrossOrigin
    @RequestMapping(value = "/testCross", produces = "text/plain")
    public String testApi4(@RequestBody String msg) {
        System.out.println("跨域訪問成功..." + msg);
        return "恭喜你跨域訪問成功,獲取到的數據為:" + msg;
    }
}

本篇博客決定使用靜態 html 頁面,采用 JQuery 請求這些接口進行測試,首先列出靜態頁面的內容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>演示普通接口的請求和響應</title>
</head>
<body>
<h1>SpringMvc 采用 Ajax 調用普通 Api 接口</h1>
<a href="javascript:void(0);" id="test1">SpringMvc發送普通文本數據</a><br/>
<a href="javascript:void(0);" id="test2">SpringMvc發送單個對象的Json數據</a><br/>
<a href="javascript:void(0);" id="test3">SpringMvc發送多個對象的Json數據(Json數組)</a><br/>
<br/>

<fieldset>
    <legend>SpringMvc跨域訪問</legend>
    條件准備:<br/>
    1.請在本機的 hosts 文件中配置 www.jobs.com 對應的 ip 地址為 127.0.0.1<br/>
    2.在 SpringMvc 的后端接口上,增加 @CrossOrigin 注解<br/>
    <a href="javascript:return false;" id="testCross">SpringMvc測試跨域訪問</a><br/>
</fieldset>

<script src="./js/jquery-3.6.0.min.js"></script>
<script src="./js/apitest.js"></script>
</body>
</html>

在該靜態頁面中,引用了 js 目錄中編寫的 apitest.js 文件,具體內容如下:

$(function () {
    $('#test1').click(function () {
        $.ajax({
            type: "post",
            url: "/api/test1",
            data: "努力學習,天天向上",
            dataType: "text",
            contentType: "text/plain",
            success: function (data) {
                alert(data);
            }
        });
    });

    $('#test2').click(function () {
        $.ajax({
            type: "post",
            url: "/api/test2",
            data: '{"name":"喬豆豆","age":28}',
            dataType: "json",
            contentType: "application/json",
            success: function (data) {
                alert("修改后的結果:" + data.name + "," + data.age);
            }
        });
    });

    $('#test3').click(function () {
        $.ajax({
            type: "post",
            url: "/api/test3",
            data: '[{"name":"任肥肥","age":40},{"name":"侯胖胖","age":42}]',
            dataType: "json",
            contentType: "application/json",
            success: function (data) {

                //采用數組存儲字符串,最后以中文逗號拼接在一起
                let arr = new Array();
                for (let i = 0; i < data.length; i++) {
                    arr.push(data[i].name + '---' + data[i].age);
                }

                let result = arr.join(',');
                alert(result);
            }
        });
    });

    $('#testCross').click(function () {
        $.ajax({
            type: "post",
            url: "http://www.jobs.com:8080/api/testCross",
            data: "祝大家事業有成",
            dataType: "text",
            contentType: "text/plain",
            success: function (data) {
                alert(data);
            }
        });
    });
})

然后運行網站,在首頁 index.html 靜態頁面中,即可進行接口的測試。



Ok,有關從 body 中獲取請求數據的接口開發方式,已經介紹完畢。這種開發接收的方式比較常用。

本篇博客的 Demo 源代碼下載地址為:https://files.cnblogs.com/files/blogs/699532/SpringMvc_DataApi.zip




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM