Android用户登录与数据存储:从权限请求到内外部存储的完整实践【完整实践步骤、外部存储、内部存储】

步骤 1: 登录页面布局

MainActivity 中实现用户登录功能,首先创建一个布局文件 activity_main.xml 包含用户名和密码的输入字段以及登录按钮。

<!-- activity_main.xml -->
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><EditTextandroid:id="@+id/editTextUsername"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="用户名" /><EditTextandroid:id="@+id/editTextPassword"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="密码"android:inputType="textPassword" /><Buttonandroid:id="@+id/buttonLogin"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="登录" /></LinearLayout>

实现效果
在这里插入图片描述

步骤 2:商品列表页面布局

在Android Studio中,右键点击项目的app目录,选择“New” > “Activity” > “Empty Activity”。
在这里插入图片描述

布局文件 activity_product_list.xml 用于显示商品列表。

<!-- activity_product_list.xml -->
<ListViewxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/listViewProducts"android:layout_width="match_parent"android:layout_height="match_parent" />

实现效果
在这里插入图片描述

然后,在 ProductListActivity.java 中加载商品数据并显示在 ListView 中。

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;public class ProductListActivity extends AppCompatActivity {private ListView listViewProducts;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_product_list);listViewProducts = findViewById(R.id.listViewProducts);// 在这里获取商品数据,可以从网络或本地获取// 假设你有一个商品列表的字符串数组String[] products = {"商品1", "商品2", "商品3", "商品4"};// 使用ArrayAdapter将商品数据绑定到ListViewArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, products);listViewProducts.setAdapter(adapter);}
}

步骤 3:实现登录功能

然后在 MainActivity.java 中处理登录逻辑,验证用户名和密码是否正确。在成功登录后,跳转到商品列表页面。

package com.leo.login_filestore;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {private EditText editTextUsername;private EditText editTextPassword;private Button buttonLogin;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editTextUsername = findViewById(R.id.editTextUsername);editTextPassword = findViewById(R.id.editTextPassword);buttonLogin = findViewById(R.id.buttonLogin);buttonLogin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 在这里验证用户名和密码是否正确String username = editTextUsername.getText().toString();String password = editTextPassword.getText().toString();if (isValidCredentials(username, password)) {// 登录成功,跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));} else {// 登录失败,显示错误消息Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();}}});}private boolean isValidCredentials(String username, String password) {// 在这里实现验证逻辑,比较输入的用户名和密码是否正确// 这里可以将用户名和密码写在代码中或从其他数据源获取// 用户名和密码硬编码在代码中,用于演示String validUsername = "user";String validPassword = "password";// 比较输入的用户名和密码与有效的用户名和密码是否匹配return username.equals(validUsername) && password.equals(validPassword);}}

实现效果
user

步骤 4:请求外部存储权限

要请求外部存储权限,你需要在 AndroidManifest.xml 中添加权限声明。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="WrongManifestParent" />

在这里插入图片描述

步骤 5:编写SaveUtil类用于保存数据到外部存储上的文件

创建一个 SaveUtil.java 类来处理数据保存到外部存储的逻辑。

使用 Environment.getExternalStorageDirectory() 来获取外部存储的根目录,然后创建一个文件并将数据写入其中。这将使你的代码更加灵活,因为它动态获取了外部存储的路径,而不是硬编码路径。请确保在使用外部存储时处理好权限问题。

package com.leo.login_filestore;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;import android.os.Environment;public class SaveUtil {public static boolean saveDataToExternalStorage(String filename, String data) {// 在这里实现数据保存到外部存储的逻辑// 注意要处理异常情况try {// 获取外部存储根目录File root = Environment.getExternalStorageDirectory();// 创建要保存的文件File file = new File(root, filename);// 创建文件输出流FileOutputStream fos = new FileOutputStream(file);// 写入数据fos.write(data.getBytes());// 关闭文件输出流fos.close();return true;} catch (IOException e) {e.printStackTrace();return false;}}
}

步骤 6: 在MainActivity中调用SaveUtil类实现保存用户名和密码

在登录成功后,调用 SaveUtil 类保存用户名和密码到外部存储。这里我们使用模拟数据,实际情况下应该更加安全地保存密码。

存储的默认目录:/storage/emulated/0/你的文件

// 登录成功后
if (isValidCredentials(username, password)) {// 保存用户名和密码到外部存储boolean saved = SaveUtil.saveDataToExternalStorage("credentials.txt", username + "," + password);if (saved) {// 跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));} else {// 处理保存失败的情况}
}

步骤 7:在 MainActivity 中请求权限保存代码

还需要在 MainActivity 中请求权限。通常,这会在应用的运行时动态请求。
完整代码

package com.leo.login_filestore;import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;import android.Manifest;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {private static final int PERMISSION_REQUEST_CODE = 1;private EditText editTextUsername;private EditText editTextPassword;private  String username;private  String password;private Button buttonLogin;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editTextUsername = findViewById(R.id.editTextUsername);editTextPassword = findViewById(R.id.editTextPassword);buttonLogin = findViewById(R.id.buttonLogin);// 请求外部存储权限requestStoragePermission();buttonLogin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 在这里验证用户名和密码是否正确username = editTextUsername.getText().toString();password = editTextPassword.getText().toString();if (isValidCredentials(username, password)) {// 登录成功,跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));saveDataToExternalStorage();} else {// 登录失败,显示错误消息Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();}}});}private void requestStoragePermission() {if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {// 请求权限ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},PERMISSION_REQUEST_CODE);}}private void saveDataToExternalStorage() {System.out.println(username + "," + password);// 可以使用FileOutputStream等方式boolean saved = SaveUtil.saveDataToExternalStorage("credentials.txt", username + "," + password);}private boolean isValidCredentials(String username, String password) {// 在这里实现验证逻辑,比较输入的用户名和密码是否正确// 这里可以将用户名和密码写在代码中或从其他数据源获取// 用户名和密码硬编码在代码中,用于演示String validUsername = "user";String validPassword = "password";// 比较输入的用户名和密码与有效的用户名和密码是否匹配return username.equals(validUsername) && password.equals(validPassword);}}

实现效果
请添加图片描述
存储到虚拟机文件中的内容——/storage/emulated/0/credentials.txt
在这里插入图片描述

步骤 8:尝试自动登录

当前我们已经实现了保存用户名和密码到外部存储的逻辑。接下来,需要修改 MainActivity,在启动应用时尝试读取 credentials.txt 文件中的用户名和密码,并实现自动登录。

private static final String CREDENTIALS_FILE = "credentials.txt";@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// ...// 尝试自动登录tryAutoLogin();
}private void tryAutoLogin() {String savedCredentials = readDataFromExternalStorage(CREDENTIALS_FILE);if (savedCredentials != null) {String[] parts = savedCredentials.split(",");if (parts.length == 2) {String savedUsername = parts[0];String savedPassword = parts[1];// 检查保存的用户名和密码是否与有效凭据匹配if (isValidCredentials(savedUsername, savedPassword)) {// 自动登录成功,跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));}}}
}private String readDataFromExternalStorage(String filename) {try {File root = Environment.getExternalStorageDirectory();File file = new File(root, filename);if (file.exists()) {FileInputStream fis = new FileInputStream(file);InputStreamReader isr = new InputStreamReader(fis);BufferedReader bufferedReader = new BufferedReader(isr);StringBuilder sb = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {sb.append(line);}bufferedReader.close();return sb.toString();}} catch (IOException e) {e.printStackTrace();}return null;
}

上述代码在 onCreate 中调用了 tryAutoLogin 方法,该方法会尝试从 credentials.txt 文件中读取保存的用户名和密码,然后检查它们是否与有效凭据匹配。如果匹配成功,它将执行自动登录并跳转到商品列表页面。

请确保在 AndroidManifest.xml 中添加适当的权限声明以及在 Android 11 及更高版本上正确处理存储权限。

实现自动登录效果
请添加图片描述

步骤 9: 使用内部存储文件和SharedPreferences实现自动登录功能

我们使用SharedPreferences来保存和检索用户名和密码。tryAutoLogin 方法尝试从SharedPreferences中获取保存的凭据,并自动登录用户,如果凭据存在并有效的话。

确保在 ProductListActivity 中实现商品列表的显示,这部分代码应该保持不变。

代码如下:

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private EditText editTextUsername;private EditText editTextPassword;private Button buttonLogin;private SharedPreferences sharedPreferences;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editTextUsername = findViewById(R.id.editTextUsername);editTextPassword = findViewById(R.id.editTextPassword);buttonLogin = findViewById(R.id.buttonLogin);sharedPreferences = getSharedPreferences("MyAppPrefs", MODE_PRIVATE);tryAutoLogin();buttonLogin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String username = editTextUsername.getText().toString();String password = editTextPassword.getText().toString();if (isValidCredentials(username, password)) {// 登录成功,保存用户名和密码到SharedPreferencessaveCredentials(username, password);// 跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));} else {// 登录失败,显示错误消息Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();}}});}private void tryAutoLogin() {String savedUsername = sharedPreferences.getString("username", "");String savedPassword = sharedPreferences.getString("password", "");if (!savedUsername.isEmpty() && !savedPassword.isEmpty()) {// 自动登录成功,跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));}}private void saveCredentials(String username, String password) {SharedPreferences.Editor editor = sharedPreferences.edit();editor.putString("username", username);editor.putString("password", password);editor.apply();}private boolean isValidCredentials(String username, String password) {// 在这里实现验证逻辑,比较输入的用户名和密码是否正确// 这里可以将用户名和密码写在代码中或从其他数据源获取// 示例:用户名和密码硬编码在代码中,用于演示String validUsername = "user";String validPassword = "password";// 比较输入的用户名和密码与有效的用户名和密码是否匹配return username.equals(validUsername) && password.equals(validPassword);}
}

MainActivity完整代码

package com.leo.login_filestore;
/** 使用内部存储文件和SharedPreferences实现自动登录功能 **/
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private EditText editTextUsername;private EditText editTextPassword;private Button buttonLogin;private SharedPreferences sharedPreferences;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editTextUsername = findViewById(R.id.editTextUsername);editTextPassword = findViewById(R.id.editTextPassword);buttonLogin = findViewById(R.id.buttonLogin);sharedPreferences = getSharedPreferences("MyAppPrefs", MODE_PRIVATE);tryAutoLogin();buttonLogin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String username = editTextUsername.getText().toString();String password = editTextPassword.getText().toString();if (isValidCredentials(username, password)) {// 登录成功,保存用户名和密码到SharedPreferencessaveCredentials(username, password);// 跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));} else {// 登录失败,显示错误消息Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();}}});}private void tryAutoLogin() {String savedUsername = sharedPreferences.getString("username", "");String savedPassword = sharedPreferences.getString("password", "");if (!savedUsername.isEmpty() && !savedPassword.isEmpty()) {// 自动登录成功,跳转到商品列表页面startActivity(new Intent(MainActivity.this, ProductListActivity.class));}}private void saveCredentials(String username, String password) {SharedPreferences.Editor editor = sharedPreferences.edit();editor.putString("username", username);editor.putString("password", password);editor.apply();}private boolean isValidCredentials(String username, String password) {// 在这里实现验证逻辑,比较输入的用户名和密码是否正确// 这里可以将用户名和密码写在代码中或从其他数据源获取// 示例:用户名和密码硬编码在代码中,用于演示String validUsername = "user";String validPassword = "password";// 比较输入的用户名和密码与有效的用户名和密码是否匹配return username.equals(validUsername) && password.equals(validPassword);}
}/** # 外部存储实现自动登录 **/
//
//import android.content.Intent;
//import android.content.pm.PackageManager;
//import android.os.Bundle;
//import android.os.Environment;
//import android.view.View;
//import android.widget.Button;
//import android.widget.EditText;
//
//import android.Manifest;
//
//import androidx.annotation.NonNull;
//import androidx.appcompat.app.AppCompatActivity;
//import androidx.core.app.ActivityCompat;
//import androidx.core.content.ContextCompat;
//import android.widget.Toast;
//
//import java.io.BufferedReader;
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.IOException;
//import java.io.InputStreamReader;
//
//public class MainActivity extends AppCompatActivity {
//    private static final int PERMISSION_REQUEST_CODE = 1;
//    private static final String CREDENTIALS_FILE = "credentials.txt";
//
//
//    private EditText editTextUsername;
//    private EditText editTextPassword;
//
//    private  String username;
//    private  String password;
//
//    private Button buttonLogin;
//
//    @Override
//    protected void onCreate(Bundle savedInstanceState) {
//        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
//
//        editTextUsername = findViewById(R.id.editTextUsername);
//        editTextPassword = findViewById(R.id.editTextPassword);
//        buttonLogin = findViewById(R.id.buttonLogin);
//        // 请求外部存储权限
//        requestStoragePermission();
//
//        tryAutoLogin();
//
//        buttonLogin.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//
//                // 在这里验证用户名和密码是否正确
//                username = editTextUsername.getText().toString();
//                password = editTextPassword.getText().toString();
//
//                if (isValidCredentials(username, password)) {
//                    // 登录成功,跳转到商品列表页面
//                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
//                    saveDataToExternalStorage();
//                } else {
//                    // 登录失败,显示错误消息
//                    Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();
//                }
//            }
//        });
//    }
//    private void requestStoragePermission() {
//
//        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
//                != PackageManager.PERMISSION_GRANTED) {
//            // 请求权限
//            ActivityCompat.requestPermissions(this,
//                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
//                    PERMISSION_REQUEST_CODE);
//        }
//    }
//
//    private void saveDataToExternalStorage() {
//        System.out.println(username + "," + password);
//        // 可以使用FileOutputStream等方式
//        boolean saved = SaveUtil.saveDataToExternalStorage("credentials.txt", username + "," + password);
//
//    }
//
//    private boolean isValidCredentials(String username, String password) {
//        // 在这里实现验证逻辑,比较输入的用户名和密码是否正确
//        // 这里可以将用户名和密码写在代码中或从其他数据源获取
//
//        // 用户名和密码硬编码在代码中,用于演示
//        String validUsername = "user";
//        String validPassword = "password";
//
//        // 比较输入的用户名和密码与有效的用户名和密码是否匹配
//        return username.equals(validUsername) && password.equals(validPassword);
//    }
//
//    private void tryAutoLogin() {
//        String savedCredentials = readDataFromExternalStorage(CREDENTIALS_FILE);
//        if (savedCredentials != null) {
//            String[] parts = savedCredentials.split(",");
//            if (parts.length == 2) {
//                String savedUsername = parts[0];
//                String savedPassword = parts[1];
//
//                // 检查保存的用户名和密码是否与有效凭据匹配
//                if (isValidCredentials(savedUsername, savedPassword)) {
//                    // 自动登录成功,跳转到商品列表页面
//                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
//                }
//            }
//        }
//    }
//
//    private String readDataFromExternalStorage(String filename) {
//        try {
//            File root = Environment.getExternalStorageDirectory();
//            File file = new File(root, filename);
//
//            if (file.exists()) {
//                FileInputStream fis = new FileInputStream(file);
//                InputStreamReader isr = new InputStreamReader(fis);
//                BufferedReader bufferedReader = new BufferedReader(isr);
//
//                StringBuilder sb = new StringBuilder();
//                String line;
//                while ((line = bufferedReader.readLine()) != null) {
//                    sb.append(line);
//                }
//
//                bufferedReader.close();
//                return sb.toString();
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return null;
//    }
//
//}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/98132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单元测试该怎么写

单元测试对于开发人员来说很熟悉&#xff0c;各种语言都提供了单元测试的框架&#xff0c;用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具&#xff0c;使开发人员能够编写和运行测试用例&#xff0c;比较预期行为和实际行为之间的差异&#xff0c;并准确地识…

【已验证】微信小程序介绍及创建过程23.10.08

1、环境准备 开发微信⼩程序之前&#xff0c;必须要准备好相应的环境 1.1.注册账号 建议使用全新的邮箱&#xff0c;没有注册过其他小程序或者公众号的。访问注册⻚⾯&#xff0c;耐⼼完成注册即可。 1.2.获取APPID 由于登录&#xff0c;然后获取APPID 2.开发工具 下载地…

ElementUI结合Vue完成主页的CUD(增删改)表单验证

目录 一、CUD ( 1 ) CU讲述 ( 2 ) 编写 1. CU 2. 删除 二、验证 前端整合代码 : 一、CUD 以下的代码基于我博客中的代码进行续写 : 使用ElementUI结合Vue导航菜单和后台数据分页查询 ( 1 ) CU讲述 在CRUD操作中&#xff0c;CU代表创建&#xff08;Create&#xff09…

设备搭建(waf、蜜罐、ids和ips)

文章目录 防火墙waf网闸蜜罐idsips 防火墙 DMZ区域叫非军事化区减&#xff0c;DMZ有web服务或者MySQL服务&#xff0c;从互联网到dmz的流量一般不拦截&#xff08;因为需要互联网用户访问web服务&#xff09;&#xff0c;如果dmz沦陷&#xff0c;攻击者想要继续横向移动到内网…

Vue中实现自定义编辑邮件发送到指定邮箱(纯前端实现)

formspree里面注册账号 注册完成后进入后台新建项目并且新建表单 这一步完成之后你将得到一个地址 最后就是在项目中请求这个地址 关键代码如下&#xff1a; submitForm() {this.fullscreenLoading true;this.$axios({method: "post",url: "https://xxxxxxx…

什么是数据库锁(Lock)?有哪些类型的锁

数据库锁&#xff08;Lock&#xff09;&#xff1a;保护数据完整性与并发性的关键 数据库锁&#xff08;Lock&#xff09;是在数据库管理系统中用于管理并发访问数据的重要机制。它们确保了多个用户或事务可以同时访问数据库&#xff0c;同时保护数据的完整性。在本文中&#…

7.wifi开发【智能家居:终】,实践总结:智能开关,智能采集温湿,智能灯。项目运行步骤与运行细节,技术归纳与提炼,项目扩展

一。项目运行步骤与运行细节 1.项目运行步骤&#xff08;一定有其他的运行方式&#xff0c;我这里只提供一种我现在使用的编译方式&#xff09; &#xff08;1&#xff09;项目运行使用软件与技术&#xff1a; 1.Virtual linux 使用这个虚拟机进行程序的编译 2.Makefile与shl…

【Navicat】win 10 / win 11:Navicat 15 安装完整教程(navicat 连接 mysql 出现 2059 报错问题解决)

目录 一、Navicat 连接 mysql 出现 2059 报错问题解决 二、Navicat 15 的下载 三、Navicat 15 的安装 四、Navicat 15 的使用 一、Navicat 连接 mysql 出现 2059 报错问题解决 之前使用的是完整版本 navicat 12&#xff0c;但是随着 MySQL 的升级&#xff0c;再连接 MySQL…

【SpringCloud】认识微服务

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 认识微服务 一、 服务架构演变1.1 单体架构…

库存管理与策略模式

库存管理是个难题&#xff0c;涉及到采购、销售、仓储、门店、网站订单各个环节&#xff0c;实物库存和系统库存很难保证完全一致&#xff0c;记得系统刚上线第一天&#xff0c;因为实物库存与导入系统的库存有差异&#xff0c;系统又做了限制系统库存必须大于0才允许销售普通订…

Spring的beanName生成器AnnotationBeanNameGenerator

博主介绍&#xff1a;✌全网粉丝4W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

软件设计原则 1小时系列 (C++版)

文章目录 前言基本概念 Design Principles⭐单一职责原则(SRP) Single Responsibility PrincipleCode ⭐里氏替换原则(LSP) Liskov Substitution PrincipleCode ⭐开闭原则(OCP) Open Closed PrincipleCode ⭐依赖倒置原则(DIP) Dependency Inversion PrincipleCode ⭐接口隔离…

【Oracle】Oracle系列十九--Oracle的体系结构

文章目录 往期回顾前言1. 物理结构2. 内存结构2.1 SGA2.2 后台进程 3. 逻辑结构 往期回顾 【Oracle】Oracle系列之一–Oracle数据类型 【Oracle】Oracle系列之二–Oracle数据字典 【Oracle】Oracle系列之三–Oracle字符集 【Oracle】Oracle系列之四–用户管理 【Oracle】Or…

基于springboot实现人职匹配推荐管理系统演示【项目源码+论文说明】分享

基于springboot实现人职匹配推荐管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于人职匹配推荐系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了…

ADuM1250 ADuM1251 模块 I2C IIC总线2500V电磁隔离 接口保护

功能说明&#xff1a; 1&#xff0c;2500V电磁隔离&#xff0c;2通道双向I2C&#xff1b; 2&#xff0c;支持电压在3到5.5V&#xff0c;最大时钟频率可达1000KHz&#xff1b; 3&#xff0c;将该隔离模块接入总线&#xff0c;可以保护主MCU引脚&#xff0c;降低I2C总线上的干…

【Java 进阶篇】HTML表格标签详解

HTML&#xff08;Hypertext Markup Language&#xff09;表格标签是在网页中用于创建表格的重要工具。表格是一种在网页上以行和列的方式组织和显示数据的有效方式。在本文中&#xff0c;我们将详细介绍HTML表格标签&#xff0c;包括如何创建表格、定义表头、单元格合并等内容。…

应用案例 | dataFEED OPC Suite为化工行业中的质量控制和成本节约提供数据集成方案

一 背景 在当今化工行业中&#xff0c;质量控制对于特种塑料供应商至关重要。一家国际性的特种塑料供应商在全球拥有五个生产基地&#xff0c;每个基地都运行着2-6台塑料挤出机。为了确保塑料质量&#xff0c;他们需要每两小时分析一次挤出样品——导致这项工作占用了较大的生…

WebGoat 靶场 JWT tokens 四 五 七关通关教程

文章目录 webGoat靶场第 四 关 修改投票数第五关第七关 你购买书&#xff0c;让Tom用户付钱 webGoat靶场 越权漏洞 将webgoat-server-8.1.0.jar复制到kali虚拟机中 sudo java -jar webgoat-server-8.1.0.jar --server.port8888解释&#xff1a; java&#xff1a;这是用于执行…

京东数据分析平台:2023年8月京东奶粉行业品牌销售排行榜

鲸参谋监测的京东平台8月份奶粉市场销售数据已出炉&#xff01; 鲸参谋数据显示&#xff0c;8月份京东平台上奶粉的销售量将近700万件&#xff0c;环比增长约15%&#xff0c;同比则下滑约19%&#xff1b;销售额将近23亿元&#xff0c;环比增长约4%&#xff0c;同比则下滑约3%。…

【React】深入理解React组件状态State

目录 一、何为State二、如何定义State三、如何判断是否为State四、如何正确使用State1、用setState修改State2、State的更新是异步的①、代码示例 3、State更新会被合并①、组件状态例子②、当只需要修改状态title时&#xff0c;只需要将修改后的title传给setState③、React会合…