java - 如何在 Android 应用程序中使用 Retrofit 2 使用 Spring-Boot REST API
问题描述
我在 Spring Boot 上为我的 Android 应用程序创建了 REST API,当我尝试使用 API 时,它在 Postman 中运行良好,但在我的应用程序中运行良好,请通过查看我的代码帮助我,我将非常感谢社区成员。
春天用户控制器.java
@RestController
@RequestMapping(value = USER_URL)
public class UserController {
private final UserService userService;
//email service
@Autowired
private EmailServiceImpl emailServiceImpl;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping(value = LOGIN, consumes = MediaType.ALL_VALUE)
public ResponseEntity<Object> authenticateUser(@RequestParam(EMAIL) String email,
@RequestParam(PASSWORD) String password) {
if (userService.authenticateUser(email, password).size() > 0) {
//generating auth token
String token;
try {
token = MD5.getMD5Hex(email + DateTime.getCurrentTime(Constants.DATETIME.formatyyyyMMddHHmmss));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return ResponseHandler.negativeResponse(
HttpStatus.INTERNAL_SERVER_ERROR,
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(),
"error generating auth token");
}
//adding authToken to users Entity
userService.updateUserAuthToken(email, token);
//sending response
return ResponseHandler.positiveResponse(
HttpStatus.OK,
HttpStatus.OK.getReasonPhrase(),
SUCCESS,
userService.authenticateUser(email, password).iterator().next(),
USER);
} else
return ResponseHandler.negativeResponse(
HttpStatus.NOT_FOUND,
HttpStatus.NOT_FOUND.getReasonPhrase(),
EMAIL_PASS_NOT_MATCH);
}
春天 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.spring-app</groupId>
<artifactId>spring-app</artifactId>
<version>0.2.5</version>
<packaging>jar</packaging>
<name>spring-app</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>groupid</groupId>
<artifactId>artifiactId</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-XDignore.symbol.file</arg>
<arg>-parameters</arg>
</compilerArgs>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
ANDROID 模型 User.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class User {
@SerializedName("id")
@Expose
private int id;
@SerializedName("full_name")
@Expose
private String fullName;
@SerializedName("email")
@Expose
private String email;
@SerializedName("phone")
@Expose
private String phone;
@SerializedName("role")
@Expose
private String role;
@SerializedName("created_at")
@Expose
private String createdAt;
@SerializedName("auth_token")
@Expose
private String authToken;
@SerializedName("password")
@Expose
private String password;
@SerializedName("image")
@Expose
private String image;
public User(Integer id, String fullName, String email, String phone, String role, String createdAt, String authToken, String password, String image) {
this.id = id;
this.fullName = fullName;
this.email = email;
this.phone = phone;
this.role = role;
this.createdAt = createdAt;
this.authToken = authToken;
this.password = password;
this.image = image;
}
public User(int id, String fullName, String email, String phone, String role, String createdAt, String authToken, String image) {
this.id = id;
this.fullName = fullName;
this.email = email;
this.phone = phone;
this.role = role;
this.createdAt = createdAt;
this.authToken = authToken;
this.image = image;
}
public User() {
}
public int getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getAuthToken() {
return authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", fullName='" + fullName + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
", role='" + role + '\'' +
", createdAt='" + createdAt + '\'' +
", authToken='" + authToken + '\'' +
", password='" + password + '\'' +
", image='" + image + '\'' +
'}';
}
}
ANDROID 模型 GenericResponse.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class GenericResponse {
@SerializedName("error")
@Expose
private String error;
@SerializedName("message")
@Expose
private String message;
@SerializedName("user")
@Expose
private User user;
@SerializedName("timestamp")
@Expose
private String timestamp;
@SerializedName("status")
@Expose
private int status;
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public int getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
ANDROID RestApiInterface.java
public interface RestApiInterface {
//login
@Multipart
@POST(USER_URL + LOGIN)
Call<GenericResponse> signInRequest(@Part("email") RequestBody email,
@Part("password") RequestBody password);
}
ANDROID RestApiManager.java
public class RestApiManager {
public static Retrofit retrofit = null;
//
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
private static OkHttpClient getClientt() {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header(AUTH_KEY_ATTRIBUTE, AUTH_KEY_VALUE)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
})
.build();
return client;
}
}
ANDROID 方法 SendSignInRequestToServer()
/*Network Calls for sign in*/
public void sendSignInRequestToServer(String email, String password) {
RestApiInterface restService = RestApiManager.getClient().create(RestApiInterface.class);
RequestBody email_ = RequestBody.create(MediaType.parse("text/plain"), email);
RequestBody password_ = RequestBody.create(MediaType.parse("text/plain"), password);
Call<GenericResponse> connection = restService.signInRequest(email_, password_);
connection.enqueue(new Callback<GenericResponse>() {
@Override
public void onResponse(Call<GenericResponse> call, retrofit2.Response<GenericResponse> response) {
progressDialog.dismiss();
if (response.body() != null) {
if (response.body().getStatus() == 200) {
((AuthenticationActivity) getActivity()).goToHomeActivity();
} else {
new CustomToast().Show_Toast(getActivity(), mainView, response.body().getMessage());
ll_signIn.startAnimation(shakeAnimation);
}
}
}
@Override
public void onFailure(Call<GenericResponse> call, Throwable t) {
if (t instanceof IOException) {
Toast.makeText(getActivity(), "this is an actual network failure :( inform the user and possibly retry", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getActivity(), "conversion issue! big problems :(", Toast.LENGTH_SHORT).show();
// todo log to some central bug tracking service
}
}
});
}
邮递员回应
{
"error": "OK",
"message": "success",
"user": {
"role": "admin",
"image": "",
"email": "sultan@gmail.com",
"phone": "11223344",
"created_at": "23:40:49",
"full_name": "sultan",
"auth_token": "c7cec6c452f645af1e3a7368aee1b364",
"id": 4
},
"timestamp": "2020-06-04T03:28:59.710+0000",
"status": 200
}
应用程序端的错误 它总是点击失败我不知道我做错了什么请帮助我谢谢
解决方案
我发现在 android x 上您需要为此定义网络安全配置,您需要在 res->xml->network-security-config.xml 此处创建一个 XML 文件并在清单中提及
android:networkSecurityConfig="@xml/network-security-config"
网络安全配置.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">EXAMPLE.COM/API etc</domain>
</domain-config>
</network-security-config>
推荐阅读
- r - 在没有某些列的情况下创建的对象会修改其他对象
- minitest - Guard - Minitest、Rubocop 和 Infinity Loops
- python - 从 git 提交、删除和获取后文件更改的 MD5 哈希
- c - memset 中 `void*` 返回的目的是什么?
- python - 为什么我的 setuptools 在 Python 3.9 中不起作用?
- angular - Angular 10 - 如何在没有 StompJS 的情况下实现 WebSocket
- android - DJI 将 SDK 集成到应用程序中冻结并且不执行任何操作
- docker - 无法使用 Rider 调试使用 docker 容器和 docker-compose 构建的 .net 核心应用程序。容器退出代码 139
- android - 我的代码在模拟器上运行,但在真实设备上遇到错误
- linux - 查找具有特定权限的文件