Spring API 开发简单示例及技巧

简介: 目录.png以用户登录为栗子,示例API请求时处理技巧,和API返回数据时如何处理。一、API返回时:返回的json数据使用spring mvc默认配置就可以返回json了,不过需要jackson的jar包APIResponse是一...
img_2b717f100b46ac3a5174e2368955e1fd.png
目录.png

以用户登录为栗子,示例API请求时处理技巧,和API返回数据时如何处理。


一、API返回时:返回的json数据

使用spring mvc默认配置就可以返回json了,不过需要jacksonjar
APIResponse是一个实体类,配合@ResponseBody就会自动转成Json

@RequestMapping("user")
@Controller
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping(value = "/login", method = RequestMethod.POST, headers = "api-version=1")
    public @ResponseBody
    APIResponse login(HttpServletRequest request) {
        return userService.login(new APIRequest(request));
    }

    @RequestMapping(value = "/query", method = RequestMethod.GET, headers = "api-version=1")
    public @ResponseBody
    APIResponse query() {
        return userService.allUsers();
    }
}


二、API请求时:提取和解析参数

springMVC后台控制层提取和解析请求参数的方式主要有两种

  • request.getParameter("name")
  • 通过注解@RequestParam直接获取;
1.注解方式:@ResponseBody
// 必传且参数名为`userName`
@RequestParam String userName

// 必传且指定参数为 user_name
@RequestParam(value="user_name") String userName

// 标识是否为必传,required=false 会给参数赋值为null
@RequestParam(value="aa", required=true)

完整的如下:

@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("user_name") String userName) {
  APIResponse api = new APIResponse();
  api.setUserName(userName);
  ...
   
}

value用来指定要传入值的id名称
String userName, ModelMap model 是接受 value 传给的值


2.HttpServletRequest 方式

如果参较多的时候,注解方式可能显得比较臃肿,这时候也可以使用HttpServletRequest提取参数,request.getParameter("username")也比较简单。
这里着重Controller中接收的HttpServletRequest做进一步封装。

APIRequestHttpServletRequest进一步封装,提供常用的属性包括请求的URL、请求参数等。如果提供的属性不能满足需求,还提供了原 HttpServletRequest 对象属性 request。

创建 API 请求的实体类

package com.lugq.web.tools.api;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * API请求实体类
 */
public class APIRequest {

    /**
     * Raw Request, 单元测试时为null
     */
    private HttpServletRequest request;

    /**
     * 请求头
     */
    private Map<String, Object> header;

    /**
     * 请求参数
     */
    private Map<String, Object> params;

    /**
     * 客户端发出请求时的完整URL
     */
    private String url;

    /**
     * 请求行中的资源名部分
     */
    private String uri;

    /**
     * 请求行中的参数部分
     */
    private String queryString;

    /**
     * 请求方法
     */
    private String method;

    /**
     * 发出请求的客户机的IP地址
     */
    private String remoteAddr;

    /**
     * 发出请求的客户机的完整主机名
     */
    private String remoteHost;

    /**
     * 发出请求的客户机的网络端口号
     */
    private int remotePort;

    /**
     * WEB服务器的IP地址
     */
    private String localAddr;

    /**
     * WEB服务器的主机名
     */
    private String localName;

    /**
     * WEB服务器的网络端口号
     */
    private int localPort;

    /**
     * 编码格式
     */
    private String characterEncoding;

    /**
     * 上下文
     */
    private String contextPath;

    public APIRequest() {
        super();
    }

    public APIRequest(HttpServletRequest request) {

        this.request = request;

        header = new HashMap<String, Object>();
        Enumeration e = request.getHeaderNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            Object value = request.getHeader(name);
            header.put(name, value);
        }

        params = getParamesMap(request.getParameterMap());
        url = request.getRequestURL().toString();
        uri = request.getRequestURI();
        remoteAddr = request.getRemoteAddr();
        remoteHost = request.getRemoteHost();
        remotePort = request.getRemotePort();
        contextPath = request.getContextPath();
        localAddr = request.getLocalAddr();
        characterEncoding = request.getCharacterEncoding();
        localName = request.getLocalName();
        localPort = request.getLocalPort();
        method = request.getMethod();
        queryString = request.getQueryString();
    }

    private Map<String, Object> getParamesMap(Map properties) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name;
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                for (String v : values) {
                    value = v + ",";
                }
                value = value.substring(0, value.length() - 1);
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    public Object getParameter(String s) {
        return params.get(s);
    }

    public void setAttribute(String s, Object o) {
        if (params == null) params = new HashMap<String, Object>();
        params.put(s, o.toString());
    }

    // 省略 get set method. 自行补充
    ......
}

在控制层controller中实现栗子:

@RequestMapping("user")
@Controller
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping(value = "/login", method = RequestMethod.POST, headers = "api-version=1")
    public @ResponseBody
    APIResponse login(HttpServletRequest request) {
        // 将HttpServletRequest实例赋值到APIRequest对其进一步封装
        return userService.login(new APIRequest(request));
    }

}

Service 层的逻辑处理如下

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper mapper;

    public APIResponse login(APIRequest request) {
        // 获取请求参数
        String username = (String) request.getParameter("username");
        String password = (String) request.getParameter("password");
        // 处理业务逻辑
        User user = mapper.selectUserByUsername(username);
        APIStatus status = API_SUCCESS;
        if (user == null) {
            status = API_USER_NOT_EXIST;
        } else {
            if (!MD5Util.md5(password).equals(user.getPassword()))
                status = API_USER_PASSWORD_ERROR;
        }
        // 返回APIResponse对象,配合@ResponseBody转为Json
        return APIUtil.getResponse(status, user);
    }

    public APIResponse allUsers() {
        List<User> users = mapper.selectAllUser();
        return APIUtil.getResponse(API_SUCCESS, users);
    }
}
目录
相关文章
|
11天前
|
缓存 监控 API
构建高效可扩展的RESTful API:后端开发的实践指南
【4月更文挑战第26天】在现代Web开发中,构建一个高效、可扩展且易于维护的RESTful API是后端工程师必须面对的挑战。本文将深入探讨如何利用最佳实践和流行技术,设计出符合REST架构原则的服务端接口。我们将重点讨论API版本控制、资源路由、数据库优化、缓存策略以及安全性考虑等方面,旨在为开发者提供一套综合性解决方案,帮助其提升API的性能与可靠性。
|
18天前
|
安全 Java API
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)
35 0
第7章 Spring Security 的 REST API 与微服务安全(2024 最新版)(上)
|
8天前
|
JSON API 数据处理
【Swift开发专栏】Swift中的RESTful API集成实战
【4月更文挑战第30天】本文探讨了在Swift中集成RESTful API的方法,涉及RESTful API的基础概念,如HTTP方法和设计原则,以及Swift的网络请求技术,如`URLSession`、`Alamofire`和`SwiftyJSON`。此外,还强调了数据处理、错误管理和异步操作的重要性。通过合理利用这些工具和策略,开发者能实现高效、稳定的API集成,提升应用性能和用户体验。
|
1天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
35 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
7天前
|
缓存 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
【4月更文挑战第30天】Flutter允许开发者通过`CustomPaint`和`CustomPainter`进行自定义绘制,以实现丰富视觉效果。`CustomPaint` widget将`CustomPainter`应用到画布,而`CustomPainter`需实现`paint`和`shouldRepaint`方法。`paint`用于绘制图形,如示例中创建的`MyCirclePainter`绘制蓝色圆圈。Canvas API提供绘制形状、路径、文本和图片等功能。注意性能优化,避免不必要的重绘和利用缓存提升效率。自定义绘制让Flutter UI更具灵活性和个性化,但也需要图形学知识和性能意识。
【Flutter前端技术开发专栏】Flutter中的自定义绘制与Canvas API
|
7天前
|
存储 关系型数据库 Go
【Go语言专栏】基于Go语言的RESTful API开发
【4月更文挑战第30天】本文介绍了使用Go语言开发RESTful API的方法,涵盖了路由、请求处理、数据存储和测试关键点。RESTful API基于HTTP协议,无状态且使用标准方法表示操作。在Go中,通过第三方库如`gorilla/mux`进行路由映射,使用`net/http`处理请求,与数据库交互可选ORM库`gorm`,测试则依赖于Go内置的`testing`框架。Go的简洁性和并发性使得它成为构建高效API的理想选择。
|
8天前
|
机器学习/深度学习 算法 安全
深度学习在图像识别中的应用与挑战构建高效可扩展的RESTful API:后端开发的实战指南
【4月更文挑战第30天】 随着计算机视觉技术的飞速发展,深度学习在图像识别领域取得了显著的成果。本文将探讨深度学习技术在图像识别中的应用及其所面临的挑战。首先,我们将介绍深度学习的基本原理和关键技术,然后分析其在图像识别中的优势和应用案例。最后,我们将讨论当前深度学习在图像识别领域所面临的主要挑战和未来的发展趋势。
|
8天前
|
XML JSON API
【PHP开发专栏】PHP RESTful API设计与开发
【4月更文挑战第29天】本文探讨了在Web开发中流行的前后端分离模式,重点介绍了RESTful API的设计与实现。REST是一种基于HTTP协议的架构风格,核心概念包括资源、表述和状态转换。RESTful API设计遵循无状态、统一接口等原则,使用GET、POST、PUT、DELETE等HTTP方法执行操作,并通过状态码和JSON/XML传输数据。在PHP中实现RESTful API,可通过定义路由、创建控制器、处理请求和响应,同时注意安全性措施,如使用HTTPS。文中还提供了一个用户管理API的实战示例,以帮助读者更好地理解和应用RESTful API。
|
9天前
|
IDE Java 开发工具
Spring Boot DevTools:加速开发的热部署工具
【4月更文挑战第28天】在Spring Boot的开发过程中,快速反馈和效率至关重要。Spring Boot DevTools是一个为开发者设计的模块,支持热部署(hot swapping),能够实现应用的快速重启和自动重载,极大地提高了开发效率。本篇博客将介绍Spring Boot DevTools的核心概念,并通过具体的实战示例展示如何在开发过程中利用这一工具。
21 0
|
13天前
|
安全 Java API
Spring工厂API与原理
Spring工厂API与原理
33 10