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);
    }
}
目录
相关文章
|
1天前
|
API iOS开发 开发者
Snapchat API 访问:Objective-C 实现示例
Snapchat API 访问:Objective-C 实现示例
|
2天前
|
API 网络架构 开发者
探索后端开发:RESTful API设计的艺术
【9月更文挑战第18天】在数字化时代的浪潮中,后端开发如同搭建一座座坚固的桥梁,连接用户与数据的无限可能。本文将深入浅出地探讨RESTful API设计的精髓,从理论基础到实践应用,带领读者领略API设计的艺术。我们将以代码示例为灯塔,照亮理解之路,但
|
10天前
|
前端开发 API 数据处理
探索后端开发中的API设计哲学
【9月更文挑战第10天】在数字化时代的浪潮下,后端开发作为连接数据与前端界面的桥梁,其重要性不言而喻。本文将深入探讨如何通过精心设计的API来提升后端服务的可维护性、扩展性和用户体验。我们将从API设计的基本原则出发,逐步展开对RESTful API和GraphQL两种流行风格的比较分析,并结合具体场景讨论最佳实践。文章旨在为开发者提供一套实用的API设计指南,助力打造高效、稳定且易于协作的软件架构。
25 6
|
9天前
|
API 网络架构 微服务
探索 GraphQL:现代 API 开发的新范式
GraphQL 是一种高效的 API 查询语言,允许客户端精确请求所需数据,避免了传统 RESTful API 中的数据冗余问题。它由 Facebook 开发并开源,现广泛应用于现代 Web 和移动应用。本文将介绍 GraphQL 的核心概念、优势及其在不同场景下的应用,并指导你如何构建和优化 GraphQL API。
|
11天前
|
JavaScript 测试技术 API
探索后端开发:构建高效API的艺术
【9月更文挑战第8天】本文旨在揭示后端开发中一个经常被忽视的领域——API设计。通过深入浅出的方式,我们将探讨如何构建一个既高效又易于维护的API。文章将涵盖设计原则、最佳实践以及一些常见的陷阱和解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和实用的技巧,帮助你在后端开发的道路上更进一步。
|
8天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
8天前
|
Java 数据库连接 Maven
Spring基础1——Spring(配置开发版),IOC和DI
spring介绍、入门案例、控制反转IOC、IOC容器、Bean、依赖注入DI
Spring基础1——Spring(配置开发版),IOC和DI
|
12天前
|
前端开发 API 开发者
深入浅出:后端开发中的API设计艺术
在数字化时代的浪潮中,后端开发如同搭建一座座数据桥梁,连接着用户与服务的无限可能。而API设计,则是这座桥梁的精髓所在。本文将带领读者领略API设计的艺术,从基础原则到进阶实践,探索如何打造高效、稳定且易于使用的后端接口。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往高质量后端开发的大门。
|
11天前
|
存储 安全 API
探索后端开发:构建高效API的艺术
【9月更文挑战第9天】在数字时代的浪潮中,后端开发如同一位默默无闻的艺术家,精心雕琢着每一个数据交互的细节。本文将带你走进后端的世界,从基础概念到实战技巧,一起学习如何打造高效、稳定且易于扩展的API。我们将通过深入浅出的方式,探讨后端开发的哲学与实践,让你在编码之旅中,找到属于自己的节奏和和谐。让我们一起跟随代码的脚步,解锁后端开发的无限可能。
|
15天前
|
XML JSON 缓存
探索后端开发中的RESTful API设计原则
【9月更文挑战第5天】在数字化时代的浪潮中,后端开发扮演着支撑整个互联网世界运行的基石角色。而作为连接前端与后端桥梁的RESTful API,其设计质量直接影响到应用的性能和用户体验。本文将深入探讨RESTful API的设计原则,通过浅显易懂的语言和实际代码示例,引导读者理解如何构建高效、易于维护的API。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和思考。