前言
经过打工人的不懈努力,终于敲出了多层封装的安卓前后端分离项目的雏形。
前期准备
开发环境:
(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创建
生成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)
创建一个结果类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后缀
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中添加网络权限
文件图片如下:
添加内容如下(附加了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"表示使用明文通信-->
另外,不加这个可能会在发起请求时报错:需要使用明文通信。具体原因未查明。
前端也搭建完成。
运行方式
先运行后端springboot的启动类,后运行安卓端,可通过修改MainActivity中被注释的操作内容来尝试实际效果。都是“登录”按钮触发的哦!
类似于这样的:
本次内容有些长,能看到这的都点赞、留言、收藏支持一下吧!
源码都在上面了,如有问题在留言吧!