登录页面作为我们code学习中非常经典的案例,而华为Harmony官网上没有一个比较简单的http网络请求案例,我们来分析一下如何实现。
功能分析:
- 在Harmony软件开发中使用ArkTs发送http请求到Javaweb服务器(以json格式)。
- javaweb服务器也返回json格式的数据回到Harmony。
- Harmony对收到的信息进行解析。
- 根据返回信息判断登录状态。
Harmony
页面上需要什么?
- 文字信息(介绍登录的系统)
- 输入框*2(账号、密码)
- 登录按钮(触发登录方法)
特别的:
因为这里使用了Promise中的.then方法,举个例子大概解释一下:
Hello(world).then((Hi: boolean)=>{})
就是使用把Hello方法中的结果赋值给Hi,然后可以在{}代码块中继续使用Hello方法retuen的值,及Hi。
可以参考
为什么要使用Promise?
Promise是一种表示异步操作的对象,在 TypeScript 中(Arkts完全支持ts),可以使用泛型来指定 Promise 的返回值类型。
该对象在异步操作完成后通过 resolve 方法传递数据,或者在出现错误时通过 reject 方法抛出错误。通过使用 then 方法可以在操作完成后获取结果,并使用 catch 方法捕获错误。Promise 的链式调用方式使得代码更加简洁和易于阅读。
参考
在这里我使用.then方法处理了登录失败将error赋值为报错信息,成功的话error为空。Arkts中被@State修饰的变量发生改变会导致页面发生重新加载,error每次赋值都会使页面重新加载,从而实现报错信息的展示。
展示页面的page代码如下
import { ErrorConstant } from '../common/constant/ErrorConstant';
import { LoginViewModel } from '../veiwmodel/LoginViewModel'
@Entry
@Component
struct Login {
private name: string = "";
private passwd: string = "";
@State message: string = '登录';
@State error: string = '';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
TextInput()
.input()
.type(InputType.Normal)
.onChange((value: string)=>{
this.name = value
})
TextInput()
.input()
.type(InputType.Password)
.onChange((value: string)=>{
this.passwd = value
})
Button('登录')
.margin(20)
.onClick(()=>{
//登录的逻辑
LoginViewModel.getLoginState(this.name, this.passwd).then((isLogin: boolean)=>{
if (isLogin) {
this.error = "";
} else {
this.error = `${ ErrorConstant.LOGIN_ERROR }`;
}
}).catch(()=>{
this.error = `${ ErrorConstant.LOGIN_ERROR }`;
})
})
Text(this.error)
.fontColor(Color.Red)
}
.width('100%')
}
.height('100%')
}
}
@Extend(TextInput) function input() {
.width(200)
.height(50)
.fontSize(20)
.margin({top: 25})
}
处理登录逻辑的LoginViewModel
特别的:这里url路径应该是本机IP加上javaweb项目中处理Harmony请求的Servlet的路径
例如:每次使用Tomcat部署运行web项目的地址http://localhost:8080/login/LoginServlet
改成
http://你的ip/login/LoginServlet
import { httpRequestPost,userCheck } from '../common/utils/HttpUtil'
import { CommonConstant as Const } from '../common/constant/CommonConstant';
import router from '@ohos.router';
export class LoginViewModel {
static getLoginState(name:string, passwd:string): Promise<boolean> {
return new Promise((resolve: Function)=>{
let url:string = `${Const.SERVER}/${Const.GET_LOGIN_URL}`;// 不要使用本地路径
httpRequestPost(url,name,passwd).then((data: userCheck)=>{
if (data.state == "true") {
let msg:string = "登录成功!"
name = "Hello " + data.name;
router.pushUrl({
url: 'pages/Index', // 跳转的页面
params: {
msg: msg,
name: name
}
})
resolve(true);
} else {
console.info("else error")
resolve(false);
}
}).catch((err: Error)=>{
console.info("error!!!" + err);
resolve(false);
})
})
}
}
建立http请求工具
这里主要发送http请求给web服务器,并处理返回的结果(打包进userCheck类中)
import http from '@ohos.net.http';
export function httpRequestPost(url: string, name: string, passwd: string): Promise<userCheck>{
let httpRequest = http.createHttp();
console.info(name + passwd)
let promise = httpRequest.request(
url,
{
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/json'
},
extraData: {
"name" : name,
"passwd" : passwd
}
} )
let userData: userCheck = new userCheck();
return promise.then((data: http.HttpResponse) => {
console.info("code!:" + data.responseCode)
if (data.responseCode === http.ResponseCode.OK) {
console.info('Result:' + data.result);
let dataJson: userCheck = JSON.parse(`${data.result}`)
userData.name = dataJson.name;
userData.state = dataJson.state;
console.info("state" + dataJson.state)
console.info("state" + dataJson.name)
return userData;
} else {
return userData;
}
}).catch((err) => {
console.info('error!:' + JSON.stringify(err));
return userData;
});
}
export class userCheck{
state: string | Resource
name: string
constructor() {
this.state = 'false';
this.name = '';
}
}
Arkts大致如上。
web处理http请求
userService.isPasswd方法中处理了用户名和密码在数据库的对比验证。
使用JSONObject类处理json数据。
package com.example.login.cotroller;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import com.example.login.service.IUserService;
import com.example.login.service.impl.UserServiceImpl;
import com.example.login.utils.JsonUtils;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import org.json.JSONException;
import org.json.JSONObject;
@WebServlet(name = "LoginHarmonyServlet", value = "/LoginHarmonyServlet")
public class LoginHarmonyServlet extends HttpServlet {
private IUserService userService = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
doPost(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
try {
JSONObject jsonRequest = JsonUtils.JsonToString(request.getReader());//处理json成字符串再处理成JsonObject
String name = jsonRequest.getString("name");
String passwd = jsonRequest.getString("passwd");
boolean isLogin = userService.isPasswd(name,passwd) ;
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("state",isLogin+"");
jsonMap.put("name",name);
JSONObject jsonResponse = new JSONObject(jsonMap);
// System.out.println(jsonResponse.toString());
response.getWriter().write(jsonResponse.toString());
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}