移动端进阶之选: 移动端开发者也能轻松搭建的服务器
前言:
笔者最近收到了挺多客户端的留言, 客户端在等待后台接口的时候遥遥无期, 其实客户端只需要几步就能简单搭建一个后台, 用于调试接口的, 本期就简单搭建一个后台, 用于客户端调试接口. 相关代码已放于 https://github.com/iDwyane/SimpleServer
1. 基础框架搭建:
使用开发工具 IDEA, 新建一个 spring-boot 项目:
IDEA 下载地址为: http://www.jetbrains.com/idea/download/#section=windows 下载 Ultimate 版本 JDK 下载地址为: https://www.oracle.com/technetwork/java/javase/downloads/index.html 下载对应的 JDK 版本即可
image
image
image
image
image
点击 finish 后, 一个 sping-boot 的基础项目已经创建好了.
image
2. 项目启动:
TestApplication 直接 run 就能启动项目了的
image
application.properties 这个是项目的一些配置, 举例一下默认是 8080 端口, 我们如果想改下端口的话, 就可以在配置增加
server.port: 8089
这样子启动的时候端口就更改了的
image
项目的请求地址为: http:// 本机 IP:8089
3. 一个简单的接口开发:
如图创建对应的目录以及创建对应的实体类:
image
在项目启动类 TestApplication 设置 HttpMessageConverters 的 JSON 格式输出为 fastjson:
- package com.example.test;
- import com.alibaba.fastjson.serializer.SerializerFeature;
- import com.alibaba.fastjson.support.config.FastJsonConfig;
- import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
- import org.springframework.context.annotation.Bean;
- import org.springframework.http.MediaType;
- import java.util.ArrayList;
- import java.util.List;
- @SpringBootApplication
- public class TestApplication {
- /**
- * JSON 格式输出使用 fastjson
- * @return
- */
- @Bean
- public HttpMessageConverters fastJsonHttpMessageConverters() {
- FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
- FastJsonConfig fastJsonConfig = new FastJsonConfig();
- fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.WriteNullStringAsEmpty);
- // 时间格式化
- fastJsonConfig.setDateFormat("yyyyMMddHHmmss");
- fastConverter.setFastJsonConfig(fastJsonConfig);
- // 由于新版本 fastjson 设置了 MediaType 为'/', 所以需要手动加入所需的 MediaType
- List<MediaType> supportedMediaTypes = new ArrayList<>();
- // 增加 JSON 的 MediaType
- supportedMediaTypes.add(MediaType.APPLICATION_JSON);
- supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
- // 下面的都是扩展的
- supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
- supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
- supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
- supportedMediaTypes.add(MediaType.APPLICATION_PDF);
- supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
- supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
- supportedMediaTypes.add(MediaType.APPLICATION_XML);
- supportedMediaTypes.add(MediaType.IMAGE_GIF);
- supportedMediaTypes.add(MediaType.IMAGE_JPEG);
- supportedMediaTypes.add(MediaType.IMAGE_PNG);
- supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
- supportedMediaTypes.add(MediaType.TEXT_HTML);
- supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
- supportedMediaTypes.add(MediaType.TEXT_PLAIN);
- supportedMediaTypes.add(MediaType.TEXT_XML);
- fastConverter.setSupportedMediaTypes(supportedMediaTypes);
- fastConverter.setFastJsonConfig(fastJsonConfig);
- // 将 fastjson 添加到视图消息转换器列表内
- return new HttpMessageConverters(fastConverter);
- }
- public static void main(String[] args) {
- SpringApplication.run(TestApplication.class, args);
- }
- }
pom.xml 里面的 dependencies 增加如下配置:
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.47</version>
- </dependency>
创建响应的基础 DTO(entity 目录):
在 entity 文件目录单击右键
image
创建名为 ResponseDTO 的实体类并且实现序列化 (Serializable 可以使你将一个对象的状态写入一个 Byte 流里 (序列化), 并且可以从其它地方把该 Byte 流里的数据读出来 (反序列化))
- package com.example.test.entity;
- import com.example.test.enums.ResponseEnum;
- import java.io.Serializable;
- /**
- * @author Dwyane.
- * @date 2018-11-12
- */
- public class ResponseDTO<T> implements Serializable {
- private static final long serialVersionUID = -4109110629830724000L;
- /**
- * 响应 code
- */
- private String responseCode;
- /**
- * 响应描述
- */
- private String responseDesc;
- /**
- * 响应的内容
- */
- private T data;
- private ResponseDTO() {
- }
- public ResponseDTO(ResponseEnum responseEnum) {
- this(responseEnum, null);
- }
- public ResponseDTO(String responseCode, String responseDesc) {
- this.responseCode = responseCode;
- this.responseDesc = responseDesc;
- }
- public ResponseDTO(T data, ResponseEnum responseEnum) {
- this(responseEnum);
- this.data = data;
- }
- public ResponseDTO(T data, String responseCode, String responseDesc) {
- this.responseCode = responseCode;
- this.responseDesc = responseDesc;
- this.data = data;
- }
- public ResponseDTO(ResponseEnum responseEnum, String extend) {
- if (responseEnum != null) {
- this.responseCode = responseEnum.getResponseCode();
- this.responseDesc = responseEnum.getResponseDesc() + (extend == null ? "":"("+ extend +")");
- }
- }
- public static <T> ResponseDTO<T> buildSuccess(T data) {
- return new ResponseDTO<>(data, ResponseEnum.SUCCESS);
- }
- public static <T> ResponseDTO<T> buildSuccess() {
- return new ResponseDTO<>(ResponseEnum.SUCCESS);
- }
- public static <T> ResponseDTO<T> buildFail() {
- return new ResponseDTO<>(ResponseEnum.FAIL);
- }
- public static <T> ResponseDTO<T> buildError() {
- return new ResponseDTO<>(ResponseEnum.ERROR);
- }
- public static <T> ResponseDTO<T> buildEnum(T data, ResponseEnum responseEnum) {
- return new ResponseDTO<>(data, responseEnum);
- }
- public static <T> ResponseDTO<T> buildEnum(ResponseEnum responseEnum) {
- return new ResponseDTO<>(responseEnum);
- }
- public String getResponseCode() {
- return this.responseCode;
- }
- public void setResponseCode(String responseCode) {
- this.responseCode = responseCode;
- }
- public String getResponseDesc() {
- return this.responseDesc;
- }
- public void setResponseDesc(String responseDesc) {
- this.responseDesc = responseDesc;
- }
- public T getData() {
- return this.data;
- }
- public void setData(T date) {
- this.data = date;
- }
- }
创建响应的基础枚举 (enums 目录):
在 enums 文件目录单击右键创建 class 时选择 Enum 的枚举类
image
- package com.example.test.enums;
- /**
- * @author Dwyane.
- * @date 2018-11-12
- */
- public enum ResponseEnum {
- SUCCESS("0000","成功"),
- ERROR("9999","服务器异常"),
- FAIL("9998","失败"),
- ;
- /**
- * 返回代码
- */
- public String responseCode;
- /**
- * 返回描述
- */
- public String responseDesc;
- ResponseEnum(String responseCode, String responseDesc) {
- this.responseCode = responseCode;
- this.responseDesc = responseDesc;
- }
- /**
- * 获取 返回代码
- *
- * @return 返回代码
- */
- public String getResponseCode() {
- return this.responseCode;
- }
- /**
- * 获取 返回描述
- *
- * @return 返回描述
- */
- public String getResponseDesc() {
- return this.responseDesc;
- }
- }
创建请求的实体类和响应的实体类 (entity 目录下的 member 目录):
- package com.example.test.entity.member;
- import javax.validation.constraints.NotNull;
- /**
- * @author Dwyane.
- * @date 2018-11-9
- */
- public class LoginRequestDTO {
- @NotNull
- private String mobile;
- @NotNull
- private String pwd;
- public String getMobile() {
- return mobile;
- }
- public void setMobile(String mobile) {
- this.mobile = mobile;
- }
- public String getPwd() {
- return pwd;
- }
- public void setPwd(String pwd) {
- this.pwd = pwd;
- }
- }
- package com.example.test.entity.member;
- /**
- * @author Dwyane.
- * @date 2018-11-9
- */
- public class LoginResponseDTO {
- private String mobile;
- private String name;
- public String getMobile() {
- return mobile;
- }
- public void setMobile(String mobile) {
- this.mobile = mobile;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
创建一个 controller(controller 目录):
- package com.example.test.controller;
- import com.example.test.entity.ResponseDTO;
- import com.example.test.entity.member.LoginRequestDTO;
- import com.example.test.entity.member.LoginResponseDTO;
- import com.example.test.enums.ResponseEnum;
- import org.springframework.Web.bind.annotation.PostMapping;
- import org.springframework.Web.bind.annotation.RequestBody;
- import org.springframework.Web.bind.annotation.RequestMapping;
- import org.springframework.Web.bind.annotation.RestController;
- import javax.validation.Valid;
- /**
- * @author Dwyane.
- * @date 2018-11-12
- */
- @RestController
- @RequestMapping("/member")
- public class MemberController {
- @PostMapping("/login")
- public ResponseDTO<LoginResponseDTO> login(@Valid @RequestBody LoginRequestDTO requestDTO) throws Exception{
- //todo 校验账号密码
- // 校验好了, 返回用户信息给到客户端
- LoginResponseDTO response = new LoginResponseDTO();
- response.setMobile(requestDTO.getMobile());
- response.setName("test");
- return new ResponseDTO<>(response, ResponseEnum.SUCCESS);
- }
- }
4.test 接口调试:
在 test 目录下创建一个简单的调试类:
- package com.example.test;
- import com.example.test.entity.member.LoginRequestDTO;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.boot.test.Web.client.TestRestTemplate;
- import org.springframework.http.HttpEntity;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpMethod;
- import org.springframework.http.ResponseEntity;
- import org.springframework.test.context.junit4.SpringRunner;
- @RunWith(SpringRunner.class)
- @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
- public class TestApplicationTests {
- @Autowired
- protected TestRestTemplate restTemplate;
- /**
- * 登录单元测试
- *
- * @throws Exception
- */
- @Test
- public void login() throws Exception {
- LoginRequestDTO requestDTO = new LoginRequestDTO();
- requestDTO.setMobile("12345678910");
- requestDTO.setPwd("123");
- HttpEntity<LoginRequestDTO> formEntity = new HttpEntity<>(requestDTO, new HttpHeaders());
- ResponseEntity<String> exchange = restTemplate.exchange("/member/login",
- HttpMethod.POST, formEntity, String.class);
- System.err.println(exchange.getBody());
- }
- }
直接单击右键测试类 run 即可:
{"responseDesc":"成功","data":{"mobile":"12345678910","name":"test"},"responseCode":"0000"}
这样一个简单的接口调用项目已经完成了.
iOS 开发者也可以用以下 swift 代码请求接口 (安卓请求也简单, 在此不予列出)
- // 输入自己电脑连接的 ip , 我的是以下 ip , 其中 8089 是端口号
- var urlStr = "http://192.168.1.113:8089/member/login"
- var url:NSURL! = NSURL(string: urlStr)
- let request:NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
- // 设置为 POST 请求
- request.httpMethod = "POST"
- request.setValue("text/html", forHTTPHeaderField: "Content-Type")
- // 设置参数
- var params = "{'mobile':122,'pwd':112}"
- let data = params.data(using: .utf8)
- request.httpBody = data
- // 默认 session 配置
- let config = URLSessionConfiguration.default
- let session = URLSession(configuration: config)
- // 发起请求
- let dataTask = session.dataTask(with: request as URLRequest) { (data, response, error) in
- // let str:String! = String(data: data!, encoding: NSUTF8StringEncoding)
- // print("str:/(str)")
- // 转 JSON
- let jsonData:NSDictionary = try! JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
- print(jsonData)
- }
- // 请求开始
- dataTask.resume()
得出如下结果:
- {
- data = {
- mobile = 122;
- name = test;
- };
- responseCode = 0000;
- responseDesc = "\U6210\U529f";
- }
至此, 一个完整的, 简单的后台搭建完成, 客户端的朋友们, 是不是觉得很简单? 如有疑问, 欢迎留言, 笔者第一时间回复, 谢谢关注!
来源: http://www.jianshu.com/p/9064935ab206