天天看點

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

前言

經過打勞工的不懈努力,終于敲出了多層封裝的安卓前後端分離項目的雛形。

前期準備

開發環境:

(1)jdk1.8

(2)Android stdio 4.1 (包含自帶的Gradle)

(3)IntelliJ IDEA 2020.2.3 x64 (包含配置好的的Maven)

項目架構及依賴

安卓用了OKHttp

後端用了springboot+mybatis-plus

安卓前端的gradle依賴

dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'com.squareup.okhttp3:okhttp:4.2.2'
    implementation 'com.google.code.gson:gson:2.7'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
    
           

springboot項目的maven依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>


    </dependencies>
           

後端搭建

1.通過mybatis-plus模闆生成

根據資料庫中的表user建立

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

生成mvc代碼:Generate.java(要放在包的最外層,與初始的springboot啟動類平級的位置,例如:放在com.example下)

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;
import java.util.List;

public class Generate {
    public static void main(String[] args) {
        
        //建立generator對象
        AutoGenerator autoGenerator = new AutoGenerator();
        //資料源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("123456");
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/dbName");
        autoGenerator.setDataSource(dataSourceConfig);
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
        globalConfig.setAuthor("admin");
        globalConfig.setOpen(false);
        globalConfig.setServiceName("%sService");
        autoGenerator.setGlobalConfig(globalConfig);
        //包資訊
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.example");//包名
        packageConfig.setEntity("entity");
        packageConfig.setMapper("mapper");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setController("controller");
        autoGenerator.setPackageInfo(packageConfig);
        //政策配置
        StrategyConfig strategyConfig = new StrategyConfig();
        String tablesName="user";
        strategyConfig.setInclude(tablesName);
        
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setEntityLombokModel(true);
        autoGenerator.setStrategy(strategyConfig);
        //運作
        autoGenerator.execute();
    }
}
           

生成結果:(沒有util)

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

建立一個結果類Result,用來裝結果集(第三個參數裝json字元串)

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = false)
public class Result {
	private int code;
	private String msg;
	private String result;
	public void setSuccess(String msg, String result){
		this.code=200;
		this.msg="success-"+msg;
		this.result=result;
	}
	public void setInfo(String msg, String result){
		this.code=400;
		this.msg="warning-"+msg;
		this.result=result;
	}
}

           

配置檔案application改成yml字尾

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

application.yml内容為:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_name
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:com/example/mapper/xml/*.xml
server:
  port: 8081
           

控制層:

import com.campus.book.entity.Result;
import com.campus.book.entity.User;
import com.campus.book.service.UserService;
import com.campus.book.util.JsonBean;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import java.io.Serializable;

@RestController
@RequestMapping("//user")
public class UserController {
	@Autowired
	private UserService userService;

	Gson gson= new GsonBuilder().serializeNulls().create();
	Result result=new Result();

	@PostMapping("/insert")
	public Result insert(String json){
		User user=null;
		try{
			user=gson.fromJson(json,User.class);
		}catch (Exception e){
			e.printStackTrace();
		}
		if(userService.getById(user.getId())!=null){//id重複!
			result.setInfo("該賬号已注冊!",null);
		}else{
			userService.save(user);
			result.setSuccess("注冊成功!",gson.toJson(user));
		}
		return result;
	}

	@DeleteMapping("/delete/{id}")
	public Result delete(@PathVariable("id") Serializable id) {
		result.setSuccess("删除成功!", null);
		boolean is=this.userService.removeById(id);
		if(is){

		}else{
			result.setInfo("删除失敗!",null);
		}
		return result;
	}

	@PutMapping("/update")
	public Result update(String json) {
		result.setInfo("更改失敗!",json);
		User user=null;
		try{
			user=gson.fromJson(json,User.class);
			if(this.userService.updateById(user)){
				result.setSuccess("更改成功!",gson.toJson(userService.getById(user.getId())));
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return result;
	}

	@GetMapping("/list")
	public Result list() {
		result.setSuccess("查詢成功!", gson.toJson(this.userService.list()));
		return result;
	}

	@GetMapping("/line/{id}")
	public Result getUser(@PathVariable("id") Serializable id){
		User user=userService.getById(id);
		if(user!=null){//存在
			result.setSuccess("查詢成功!",gson.toJson(user));
		}else{//不存在
			result.setSuccess("沒有找到相關資料!",null);
		}
		return result;
	}

	@PostMapping("/login")
	public Result login(String json){
		User user=null;
		User user1=null;
		try{
			user=gson.fromJson(json,User.class);
		}catch (Exception e){
			e.printStackTrace();
		}
		user1=userService.getById(user.getId());
		if(user1!=null){//存在該賬戶
			if(user1.getPassword().equals(user.getPassword())){//密碼正确
				result.setSuccess("登入成功!",gson.toJson(user1));
			}else{//密碼錯誤
				result.setInfo("使用者名或密碼錯誤!",null);
			}
		}else{//不存在該賬戶
			result.setInfo("該賬号不存在!",null);
		}
		return result;
	}

}
           

springboot 的啟動類

添加如下注解(定位mapper的位置)

@SpringBootApplication
@MapperScan("com.example.mapper")
           

好了,後端初步搭建完成。

下面就是安卓前端,

安卓前端(直接上代碼,有些冗長,跳着看吧)

首先是okHttp的工具類(沒有檔案上傳下載下傳)

用到了一個接口

import java.io.IOException;

import okhttp3.Response;

public interface OkHttpCallback {
    void onFailure(IOException e);
    void onSuccess(Response response);
}
           
import android.util.Log;
import com.campus.book.util.http.OkHttpCallback;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * @since 2021-04-28
 * 異步請求會放到線程池中執行
 * 同步請求會阻塞目前線程
 * 一般使用異步請求居多
 */
public class OKHttpUtil {
    private static Request request = null;
    private static int TimeOut = 120;
    //單例擷取ohttp3對象
    private static OkHttpClient client = null;
    /**
     * OkHttpClient的構造方法,通過線程鎖的方式構造
     * @return OkHttpClient對象
     */
    private static synchronized OkHttpClient getInstance() {
        if (client == null) {
            client = new OkHttpClient.Builder()
                    .readTimeout(TimeOut, TimeUnit.SECONDS)
                    .connectTimeout(TimeOut, TimeUnit.SECONDS)
                    .writeTimeout(TimeOut, TimeUnit.SECONDS)
                    .build();
        }
        return client;
    }

    /**
     * callback接口
     * 異步請求時使用
     */
    static class MyCallBack implements Callback {
        private OkHttpCallback okHttpCallBack;

        public MyCallBack(OkHttpCallback okHttpCallBack) {
            this.okHttpCallBack = okHttpCallBack;
        }

        @Override
        public void onFailure(Call call, IOException e) {
            okHttpCallBack.onFailure(e);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            okHttpCallBack.onSuccess(response);
        }
    }
    /**
     * 獲得同步get請求對象Response
     * @param url
     * @return Response
     */
    private static Response doSyncGet(String url) {
        //建立OkHttpClient對象
        client = getInstance();
        request = new Request.Builder()
                .url(url)//請求連結
                .build();//建立Request對象
        try {
            //擷取Response對象
            Response response = client.newCall(request).execute();
            return response;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 獲得異步get請求對象
     * @param url      請求位址
     * @param callback 實作callback接口
     */
    private static void doAsyncGet(String url,OkHttpCallback callback) {
        MyCallBack myCallback = new MyCallBack(callback);
        client = getInstance();
        request = new Request.Builder()
                .url(url)
                .get()
                .build();
        client.newCall(request).enqueue(myCallback);
    }
    /**
     * 同步get請求
     * 例如:請求的最終位址為:http://127.0.0.1:8081/user/getUser/123
     * @param url 基本請求位址   例子: http://127.0.0.1:8081
     * @param args 請求的參數    args[]=new String[]{"user","getUser","123"}
     * @return String
     */
    public static String getSyncRequest(String url,String... args) {
        List<String> result=new ArrayList<>();//傳回值
        String address=url;
        for(int i=0;i<args.length;i++){
            address=address+"/"+args[i];
        }
        final String finalAddress = address;
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response finalResponse = doSyncGet(finalAddress);
                String res = null;
                try {
                    Log.d("同步get請求請求位址:",finalAddress);
                    if (finalResponse.isSuccessful()) {//請求成功
                        ResponseBody body = finalResponse.body();//拿到響應體
                        res = body.string();
                        result.add(res);
                        Log.d("HttpUtil", "同步get請求成功!");
                        Log.d("請求對象:", res);
                    } else {
                        Log.d("HttpUtil", "同步get請求失敗!");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        /**因為函數傳回是立刻執行的,而result要在請求完成之後才能獲得
         * 是以需要等待result獲得傳回值之後再執行return*/
        while(result.size()==0){
            try {
                TimeUnit.MILLISECONDS.sleep(10);//等待xx毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get(0);
    }


    /**
     * 異步get請求
     * 例如:請求的最終位址為:http://127.0.0.1:8081/user/getUser/123
     * @param url 基本請求位址   例子: http://127.0.0.1:8081
     * @param args 請求的參數    args[]=new String[]{"user","getUser","123"}
     * @return String
     */
    public static String getAsyncRequest(String url,String... args){
        List<String> result=new ArrayList<>();
        String address=url;
        for(int i=0;i<args.length;i++){
            address=address+"/"+args[i];
        }
        final String finalAddress = address;
        doAsyncGet(finalAddress, new OkHttpCallback() {
            @Override
            public void onFailure(IOException e) {
                Log.d("異步get請求位址:",finalAddress);
                Log.d("HttpUtil", "異步get請求失敗!");
            }
            @Override
            public void onSuccess(Response response) {
                Log.d("異步get請求位址:",finalAddress);
                String res = null;
                try {
                    res = response.body().string();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                result.add(res);
                Log.d("HttpUtil", "異步get請求成功!");
                Log.d("請求對象:", res);
            }
        });
        /**因為函數傳回是立刻執行的,而result要在請求完成之後才能獲得
         * 是以需要等待result獲得傳回值之後再執行return*/
        while(result.size()==0){
            try {
                TimeUnit.MILLISECONDS.sleep(10);//等待xx毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get(0);
    }

    /**
     * 同步post請求
     * 例如:請求的最終位址為:http://127.0.0.1:8081/user/getUser/123
     * @param url 基本請求位址   例子: http://127.0.0.1:8081
     * @param json 送出的json字元串
     * @param args 請求的參數    args[]=new String[]{"user","getUser","123"}
     * @return
     */
    public static String postSyncRequest(String url,String json,String... args){
        List<String> result=new ArrayList<>();
        String address=url;
        for(int i=0;i<args.length;i++){
            address=address+"/"+args[i];
        }
        final String finalAddress = address;
        new Thread(new Runnable() {
            @Override
            public void run() {
                client=getInstance();
                Log.d("同步post請求位址:",finalAddress);
                FormBody.Builder formBody = new FormBody.Builder();
                formBody.add("json",json);
                request=new Request.Builder()
                        .url(finalAddress)
                        .post(formBody.build())
                        .addHeader("device-platform", "android")
                        .build();
                try{
                    Response response=client.newCall(request).execute();
                    String res=response.body().string();
                    result.add(res);
                    Log.d("HttpUtil", "同步post請求成功!");
                    Log.d("請求對象:", res);
                }catch (Exception e){
                    Log.d("HttpUtil", "同步post請求失敗!");
                    e.printStackTrace();
                }
            }
        }).start();
        /**因為函數傳回是立刻執行的,而result要在請求完成之後才能獲得
         * 是以需要等待result獲得傳回值之後再執行return*/
        while(result.size()==0){
            try {
                TimeUnit.MILLISECONDS.sleep(10);//等待xx毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get(0);
    }
    /**
     * 異步post請求
     * 例如:請求的最終位址為:http://127.0.0.1:8081/user/getUser/123
     * @param url 基本請求位址   例子: http://127.0.0.1:8081
     * @param json 送出的json字元串
     * @param args 請求的參數    args[]=new String[]{"user","getUser","123"}
     * @return
     */
    public static String postAsyncRequest(String url,String json,String... args){
        List<String> result=new ArrayList<>();
        String address=url;
        for(int i=0;i<args.length;i++){
            address=address+"/"+args[i];
        }
        final String finalAddress = address;
        Log.d("異步post請求位址:",finalAddress);
        client=getInstance();
        FormBody.Builder formBody = new FormBody.Builder();//建立表單請求體
        formBody.add("json",json);
        request = new Request.Builder()
                .url(finalAddress)
                .post(formBody.build())
                .addHeader("device-platform", "android")
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("HttpUtil","異步post請求失敗!");
                    }
                }).start();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String res = null;
                        try {
                            res = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        result.add(res);
                        Log.d("HttpUtil","異步post請求成功!");
                        Log.d("請求對象",res);
                    }
                }).start();
            }
        });
        /**因為函數傳回是立刻執行的,而result要在請求完成之後才能獲得
         * 是以需要等待result獲得傳回值之後再執行return*/
        while(result.size()==0){
            try {
                TimeUnit.MILLISECONDS.sleep(10);//等待xx毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get(0);
    }
    /**
     * 異步delete請求
     * 例如:請求的最終位址為:http://127.0.0.1:8081/user/getUser/123
     * @param url 基本請求位址   例子: http://127.0.0.1:8081
     * @param json 送出的json字元串
     * @param args 請求的參數    args[]=new String[]{"user","getUser","123"}
     * @return
     */
    public static String deleteAsyncRequest(String url,String json,String... args){
        List<String> result=new ArrayList<>();
        String address=url;
        for(int i=0;i<args.length;i++){
            address=address+"/"+args[i];
        }
        final String finalAddress = address;
        Log.d("異步delete請求位址:",finalAddress);
        client=getInstance();
        FormBody.Builder formBody = new FormBody.Builder();//建立表單請求體
        formBody.add("json",json);
        request = new Request.Builder()
                .url(finalAddress)
                .delete(formBody.build())
                .addHeader("device-platform", "android")
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("HttpUtil","異步delete請求失敗!");
                    }
                }).start();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String res = null;
                        try {
                            res = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        result.add(res);
                        Log.d("HttpUtil","異步delete請求成功!");
                        Log.d("請求對象",res);
                    }
                }).start();
            }
        });
        /**因為函數傳回是立刻執行的,而result要在請求完成之後才能獲得
         * 是以需要等待result獲得傳回值之後再執行return*/
        while(result.size()==0){
            try {
                TimeUnit.MILLISECONDS.sleep(10);//等待xx毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get(0);
    }
    /**
     * 異步put請求
     * 例如:請求的最終位址為:http://127.0.0.1:8081/user/getUser/123
     * @param url 基本請求位址   例子: http://127.0.0.1:8081
     * @param json 送出的json字元串
     * @param args 請求的參數    args[]=new String[]{"user","getUser","123"}
     * @return
     */
    public static String putAsyncRequest(String url,String json,String... args){
        List<String> result=new ArrayList<>();
        String address=url;
        for(int i=0;i<args.length;i++){
            address=address+"/"+args[i];
        }
        final String finalAddress = address;
        Log.d("異步put請求位址:",finalAddress);
        client=getInstance();
        FormBody.Builder formBody = new FormBody.Builder();//建立表單請求體
        formBody.add("json",json);
        request = new Request.Builder()
                .url(finalAddress)
                .put(formBody.build())
                .addHeader("device-platform", "android")
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d("HttpUtil","異步put請求失敗!");
                    }
                }).start();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String res = null;
                        try {
                            res = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        result.add(res);
                        Log.d("HttpUtil","異步put請求成功!");
                        Log.d("請求對象",res);
                    }
                }).start();
            }
        });
        /**因為函數傳回是立刻執行的,而result要在請求完成之後才能獲得
         * 是以需要等待result獲得傳回值之後再執行return*/
        while(result.size()==0){
            try {
                TimeUnit.MILLISECONDS.sleep(10);//等待xx毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get(0);
    }
}
           

封裝的httpUrl

public class HttpUrl {
//通過cmd指令行輸入 ipconfig  IpV4位址即為本地的ip位址
    final private static String baseUrl="http://192.168.xx.1:8081";

    public static String getBaseUrl() {
        return baseUrl;
    }

}
           

封裝的位址參數

import java.io.Serializable;

public class HttpAddress {
   private static String[] args;
    final private static String userAddress="user";
    public static String user(){
        return userAddress;
    }
    /**
     *
     * @param address 首位址 例如:“user”
     * @param method 位址中的方法  例如: “insert”
     * @return
     */
    public static String[] get(String address,String method){
        switch (method){
            case "login":args=getLoginAddress();
                break;
            case "insert":args=getInsertAddress(address);
                break;
            case "update":args=getUpdateAddress(address);
                break;
            case "list":args=getListAddress(address);
                break;
        }
        return args;
    }
    /**
     *采用方法重載,分别處理兩種情況,帶id和不帶id
     * @param address 首位址 例如:“user”
     * @param method 位址中的方法  例如: “delete”
     * @param id id則為相應參數  delete後的id參數
     * @return
     */
    public static String[] get(String address,String method,Serializable id){
        switch (method){
            case "delete":args=getDeleteAddress(address,id);
                break;
            case "line":args=getLineAddress(address,id);
                break;
        }
        return args;
    }
    private static String[] getLoginAddress(){
        args=new String[]{userAddress,"login"};
        return args;
    }
    private static String[] getInsertAddress(String address){
        args=new String[]{address,"insert"};
        return args;
    }
    private static String[] getDeleteAddress(String address, Serializable id){
        args=new String[]{address,"delete", String.valueOf(id)};
        return args;
    }
    private static String[] getUpdateAddress(String address){
        args=new String[]{address,"update"};
        return args;
    }
    private static String[] getLineAddress(String address, Serializable id){
        args=new String[]{address,"line", String.valueOf(id)};
        return args;
    }
    private static String[] getListAddress(String address){
        args=new String[]{address,"list"};
        return args;
    }
}

           

在安卓端模拟出一個資料庫增删改查的工具類(實際上是通過發起請求實作的)

import com.campus.book.entity.Result;
import com.campus.book.util.gson.JsonBean;
import com.campus.book.util.gson.JsonUtil;
import com.campus.book.util.http.HttpUrl;
import com.campus.book.util.http.OKHttpUtil;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;

/**
 * 增删改查
 * 增:post請求
 * 删:delete請求
 * 改:put請求
 * 查:get請求
 */
public class DatabaseUtil {
    final private static String baseUrl= HttpUrl.getBaseUrl();
    //final private static Gson gson= JsonBean.getGson();
    final private static Gson gson=new GsonBuilder().serializeNulls().create()
    private static String jsonForm=null;
    private static String jsonResult=null;
    private static Result result=null;
    /**
     * 通過異步post請求
     * 資料庫插入操作----增        --例子
     * @param bean bean對象       user
     * @param args 請求位址參數   {"user","insert"}
     * @return
     */
    public static Result insert(Object bean,String... args){
        try{
            jsonForm=gson.toJson(bean);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        jsonResult= OKHttpUtil.postAsyncRequest(baseUrl,jsonForm,args);
        if(jsonResult==null){//請求失敗
            result.setInfo("發送請求錯誤!",null);
        }else{//請求成功
            result=gson.fromJson(jsonResult,Result.class);
            if(result.getCode()==200){//插入失敗

            }else if(result.getCode()==400){//插入成功

            }
        }
        return result;
    }

    /**
     * 通過異步delete請求
     * 資料庫插入操作----通過 id 删除
     * @param args 請求位址參數 args[]={"user","delete",id}
     * @return
     */
    public static Result deleteById(String... args){
        jsonForm= "";
        jsonResult= OKHttpUtil.deleteAsyncRequest(baseUrl,jsonForm,args);
        if(jsonResult==null){//請求失敗
            result.setInfo("發送請求錯誤!",null);;
        }else{//請求成功
            result=gson.fromJson(jsonResult,Result.class);
            if(result.getCode()==200){//删除失敗

            }else if(result.getCode()==400){//删除成功

            }
        }
        return result;
    }
    /**
     * 通過異步put請求
     * 資料庫更新操作----通過 id 改    ---例子
     * @param bean                     user
     * @param args                    {"user","update"}
     * @return
     */
    public static Result updateById(Object bean,String... args){
        try{
            jsonForm=gson.toJson(bean);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        jsonResult= OKHttpUtil.putAsyncRequest(baseUrl,jsonForm,args);
        if(jsonResult==null){//請求失敗
            result.setInfo("發送請求錯誤!",null);;
        }else{//請求成功
            result=gson.fromJson(jsonResult,Result.class);
            if(result.getCode()==200){//插入失敗

            }else if(result.getCode()==400){//插入成功

            }
        }
        return result;
    }

    /**
     * 資料庫操作--查詢,查詢單個對象
     * @param args 請求位址參數 {"user","line",id}
     * @return
     */
    public static Result selectLineById(String... args){
        jsonResult= OKHttpUtil.getAsyncRequest(baseUrl,args);
        if(jsonResult==null){//請求失敗
            result.setMsg("發送請求錯誤!");
        }else{//請求成功
            result=gson.fromJson(jsonResult,Result.class);
            if(result.getCode()==200){//查詢失敗

            }else if(result.getCode()==400){//查詢成功

            }
        }
        return result;
    }

    /**
     * 資料庫操作--查詢,查詢對象集合
     * @param args 請求位址參數 {"user","list"}
     * @return
     */
    public static Result selectList(String... args){
        jsonResult= OKHttpUtil.getAsyncRequest(baseUrl,args);
        if(jsonResult==null){//請求失敗
            result.setMsg("發送請求錯誤!");
        }else{//請求成功
            result=gson.fromJson(jsonResult,Result.class);
            if(result.getCode()==200){//查詢失敗

            }else if(result.getCode()==400){//查詢成功

            }
        }
        return result;
    }
    /**
     * 通過Result擷取bean對象
     * @param result
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T getEntity(Result result,Class<?> cls){
        T entity=null;
        try {
            entity= (T) gson.fromJson(result.getResult(),cls);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return entity;
    }

    /**
     * 通過Result擷取對象集合
     * @param result
     * @return
     */
    public static List getList(Result result){
        List list=new ArrayList<>();
        try{
            list= (List) gson.fromJson(result.getResult(),  List.class);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

}

           

同樣,安卓端也有一個結果集類

public class Result {
    private int code;
    private String msg;
    private String result;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", result='" + result + '\'' +
                '}';
    }

    public void setSuccess(String msg, String result){
        this.code=200;
        this.msg="success-"+msg;
        this.result=result;
    }
    public void setInfo(String msg, String result){
        this.code=400;
        this.msg="warning-"+msg;
        this.result=result;
    }
}
           

下面是使用執行個體:activity

MainActvity.java

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.campus.book.entity.Result;
import com.campus.book.entity.User;
import com.campus.book.util.DatabaseUtil;

import com.campus.book.util.http.HttpAddress;


import java.util.List;

public class MainActivity extends AppCompatActivity {
    private TextView tv=null;
    EditText userId = null;
    EditText pwd = null ;
    Button login=null;
    private Button registry=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_layout);

        setTitle("登入");
        login = (Button)findViewById(R.id.login);
        registry = (Button)findViewById(R.id.registry);
        userId=(EditText) findViewById(R.id.userId);
        pwd=findViewById(R.id.pwd);
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String id = userId.getText().toString();
                String password=pwd.getText().toString();
                User user1=new User(id,password);

                                /**插入單條資料
                Result result=DatabaseUtil.insert(user1,
                        HttpAddress.get(HttpAddress.user(),"insert"));
                System.out.println(result.toString());
                // */

                /**删除單個資料
                Result result=DatabaseUtil.deleteById(HttpAddress.
                        get(HttpAddress.user(),"delete",id));
                System.out.println(result.toString());
                // */

                /**更新單個資料
                Result result=DatabaseUtil.updateById(user1,
                        HttpAddress.get(HttpAddress.user(),"update"));
                System.out.println(result.toString());
                 //*/

                /**查單行資料
                Result result=DatabaseUtil.selectLineById(
                        HttpAddress.get(HttpAddress.user(),"line",id));
                User user=DatabaseUtil.getEntity(result,User.class);
                System.out.println(user.toString());
                // */

                /**查清單資料
                Result result =DatabaseUtil.selectList(
                        HttpAddress.get(HttpAddress.user(),"list"));
                List<User> users=DatabaseUtil.getList(result);
                System.out.println(users.toString());
                // */
            }
        });

        registry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
    }

}
           

布局檔案:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tv"
    android:text="内容:"/>
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/mainBg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/login" />
<[email protected]/login改成相應的背景圖,放在drawable檔案夾下-->
        <TableLayout
            android:layout_width="350dp"
            android:layout_height="match_parent"
            android:stretchColumns="*"
            android:layout_marginBottom="150sp"
            android:layout_gravity="center" >

            <TableRow android:layout_height="match_parent">
                <EditText
                    android:id="@+id/userId"
                    android:layout_column="0"
                    android:layout_span="2"
                    android:hint="請輸入手機号"
                    android:textColorHint="#FFFFFF"
                    android:textColor="#FFFFFF"
                    android:textCursorDrawable="@drawable/cursor_color"
                    android:textSize="15sp" />
            </TableRow>

            <TableRow android:layout_height="match_parent" >
                <EditText
                    android:id="@+id/pwd"
                    android:inputType="textPassword"
                    android:layout_column="0"
                    android:layout_span="2"
                    android:hint="請輸入密碼"
                    android:textColorHint="#FFFFFF"
                    android:textColor="#FFFFFF"
                    android:textCursorDrawable="@drawable/cursor_color"
                    android:textSize="15sp" />
            </TableRow>

            <TableRow android:layout_height="match_parent">
                <Button
                    android:id="@+id/login"
                    android:layout_height="wrap_content"
                    android:textColor="#FFFFFF"
                    android:background="#000000"
                    android:layout_margin="8dp"
                    android:textSize="15sp"
                    android:text="登入" />
                <Button
                    android:id="@+id/registry"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#FFFFFF"
                    android:background="#000000"
                    android:layout_margin="8dp"
                    android:textSize="15sp"
                    android:text="注冊" />
            </TableRow>

        </TableLayout>

    </FrameLayout>

</LinearLayout>

           

cursor_color.xml也放在drawable檔案夾下

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <size android:width="2dp" />
    <solid android:color="@android:color/black" />
</shape>

           

忘記說了,要在Android中使用okHttp,要在AndroidMainfest.xml中添加網絡權限

檔案圖檔如下:

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

添加内容如下(附加了sd卡的權限,視情況需要使用的可以一起加上去):

<!-- 聯網權限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--接入wifi狀态-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- SD卡權限 -->
    <!--讀-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!--寫-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!--在sdcard中建立/删除檔案的權限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" tools:ignore="ProtectedPermissions" />
    <!--android:usesCleartextTraffic="true"表示使用明文通信-->
           

另外,不加這個可能會在發起請求時報錯:需要使用明文通信。具體原因未查明。

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

前端也搭建完成。

運作方式

先運作後端springboot的啟動類,後運作安卓端,可通過修改MainActivity中被注釋的操作内容來嘗試實際效果。都是“登入”按鈕觸發的哦!

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

類似于這樣的:

Android的前後端互動架構搭建(okhhtp+springboot+mysql完整版)

本次内容有些長,能看到這的都點贊、留言、收藏支援一下吧!

源碼都在上面了,如有問題在留言吧!