獻給移動端的伺服器搭建

highhand發表於2021-09-09

圖片描述

移動端進階之選:移動端開發者也能輕鬆搭建的伺服器

前言:

筆者最近收到了挺多客戶端的留言,客戶端在等待後臺介面的時候遙遙無期,其實客戶端只需要幾步就能簡單搭建一個後臺,用於除錯介面的,本期就簡單搭建一個後臺,用於客戶端除錯介面。相關程式碼已放於

1.基礎框架搭建:

使用開發工具IDEA,新建一個spring-boot專案:

下載Ultimate版本
下載對應的JDK版本即可

圖片描述

圖片描述

圖片描述

圖片描述

圖片描述

點選finish後,一個sping-boot的基礎專案已經建立好了。

圖片描述

2.專案啟動:

TestApplication直接run就能啟動專案了的

圖片描述

application.properties這個是專案的一些配置,舉例一下預設是8080埠,我們如果想改下埠的話,就可以在配置增加

server.port: 8089

這樣子啟動的時候埠就更改了的

圖片描述

專案的請求地址為:

3.一個簡單的介面開發:

如圖建立對應的目錄以及建立對應的實體類:

圖片描述

在專案啟動類 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檔案目錄單擊右鍵 圖片描述

建立名為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的列舉類

圖片描述

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 = “U6210U529f”;
}

至此,一個完整的、簡單的後臺搭建完成,客戶端的朋友們,是不是覺得很簡單? 如有疑問,歡迎留言,筆者第一時間回覆,謝謝關注!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/810/viewspace-2817331/,如需轉載,請註明出處,否則將追究法律責任。

相關文章