基于Android的JavaEE课设
创始人
2024-02-21 06:32:08

目录

1 技术栈

2 android前端

2.1 概述

2.1.1 目录结构

2.1.2 代码分层

2.2 技术点

2.2.1 数据绑定

2.2.2 前后端数据交互

2.2.3 九宫格图片

2.2.4 未处理消息提醒

2.2.5 动画效果

2.2.6 实时聊天

2.2.7 文件上传

2.2.8 底部弹窗

2.2.9 其他

3 后端

3.1 概述

3.1.1 目录结构

3.2 技术点

3.2.1 viewmodel

3.2.2 文件上传

3.2.3 websocket

4 服务器相关

4.1 搭建环境遇到的问题

4.1.1 本地访问不了远程mysql数据库

5 前后端交互设计文档

6 后台管理系统

6.1 搭建步骤

6.1.1 初始化本地仓库

6.1.2 从Gitee上拉取项目

6.1.3 配置、运行renren-fast项目

6.1.4 配置、运行renren-fast-vue项目

6.1.5 配置,运行 renren-generator

6.2 过程中遇到的问题

6.3 最终呈现效果


1 技术栈

前端:

  • android

后端:

  • springboot
  • springsecurity
  • mybatis-plus
  • redis
  • websocket

项目部署阿里云服务器

2 android前端

2.1 概述

主要介绍引用的第三方框架、技术点

2.1.1 目录结构

2.1.2 代码分层

不论是目录结构,还是代码,都应注意分层

2.2 技术点

2.2.1 数据绑定

viewBinding

android {buildFeatures {viewBinding true}
}

2.2.2 前后端数据交互

xutils

引入依赖

implementation 'org.xutils:xutils:3.8.5'
// gson
implementation 'com.google.code.gson:gson:2.8.2'

2.2.3 九宫格图片

AssNineGridView

2.2.4 未处理消息提醒

badgeview

2.2.5 动画效果

lottie

2.2.6 实时聊天

服务器 + websocket

2.2.7 文件上传

单文件、多文件

2.2.8 底部弹窗

2.2.9 其他

走马灯

    

输入提示属性

android:hint="请输入用户名"

文本改变监听器

    searchEditText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void afterTextChanged(Editable editable) {// 文本改变后执行的动作}});

webView

spinner

3 后端

3.1 概述

3.1.1 目录结构

3.2 技术点

3.2.1 viewmodel

使用场景:比如用户有多个字段,但是当我们注册,登录时,并不需要这么多字段

好处:节省数据交互时空间的消耗,有提升效率的作用。

 

 实际上,我们需要的字段是比较少的,比如:

 在UserController层:

不过在最后,我们存入数据库的肯定还是原来的User,而不是UserRegisterVM, 所以,我们要对这两者之间作个转换:

User user = modelMapper.map(model, User.class);

以下是对modelMapper的封装,可以当做API调用。

public class BaseApiController {/*** The constant DEFAULT_PAGE_SIZE.*/protected final static String DEFAULT_PAGE_SIZE = "10";/*** The constant modelMapper.*/protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();
}

需要使用modelMapper的时候,要继承BaseApiController 这里对应的是一个单例modelMapper

public class ModelMapperSingle {/*** The constant modelMapper.*/protected final static ModelMapper modelMapper = new ModelMapper();private final static ModelMapperSingle modelMapperSingle = new ModelMapperSingle();static {modelMapper.getConfiguration().setFullTypeMatchingRequired(true);modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);}/*** Instance model mapper.** @return the model mapper*/public static ModelMapper Instance() {return modelMapperSingle.modelMapper;}
}

3.2.2 文件上传

/*
* @description: 将文件保存在本地
* @author: xingxg
* @date: 2022/11/8 17:32
* @param: file , 与前端的名字相对应
* @return: 返回文件保存的路径
**/@PostMapping("/upload")
public CommonResult> fileLoad(MultipartFile[] file, HttpServletRequest request) throws IOException {String saveLocation = "e:/images/";//String saveLocation = "/images/";String fileSaveName = "";List imageUri = new ArrayList<>();for (MultipartFile multipartFile : file) {fileSaveName = UUID.randomUUID().toString() + multipartFile.getOriginalFilename();multipartFile.transferTo(new File(saveLocation, fileSaveName));String result = request.getScheme() + "://" +request.getServerName() + ":" +request.getServerPort() + "/" +fileSaveName;imageUri.add(result);}return CommonResult.ok(imageUri);
}

3.2.3 websocket

此前的状态是,两个人进行聊天,A发一句,B需要重新进入聊天界面才能看到A新发的消息,这是不合理的,针对该问题进行改进。

预期效果,不用重新进入页面,只要由新消息传进来,就可以展示新的数据。

解决方法1:

前端周期性地去请求后端数据,达到实时聊天的效果。

这种方式非常消耗资源,明显是不合理的。

解决方法2:

A向B发消息, A将消息推送到服务器上,由服务器主动推动消息给B

 android

引入依赖

implementation "org.java-websocket:Java-WebSocket:1.3.7"

android核心代码

public void addUserToService() {URI serverURI = URI.create("ws://192.168.130.1:9000/chat/" + Global.username);webSocketClient = new WebSocketClient(serverURI) {@Overridepublic void onOpen(ServerHandshake handshakedata) {Log.i("WebSocketClient", "onOpen");}@Overridepublic void onMessage(String message) {loadMessage(); // 有新消息传给本用户的话,重新请求后端,加载数据。}@Overridepublic void onClose(int code, String reason, boolean remote) {Log.i("WebSocketClient", "onClose");}@Overridepublic void onError(Exception ex) {Log.i("WebSocketClient", "onError");}};try {webSocketClient.connectBlocking();} catch (InterruptedException e) {e.printStackTrace();}
}

后端核心代码

package com.huiliyi.backend.utils;import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Slf4j
@ServerEndpoint(value = "/chat/{username}")
@Component
@Data
public class ChatEndpoint {//用来存储每个用户客户端对象的ChatEndpoint对象public static Map onlineUsers = new ConcurrentHashMap<>();//声明session对象,通过对象可以发送消息给指定的用户private Session session;private String username;//连接建立@OnOpenpublic void onOpen(@PathParam("username") String username,Session session, EndpointConfig config){this.session = session;this.username = username;//存储登陆的对象onlineUsers.put(username,this);log.info("onOpen:{}", username);}//收到消息@OnMessagepublic void onMessage(String toName,Session session){//将数据转换成对象try {//发送数据log.info("onMessage:{}",toName);onlineUsers.get(toName).session.getBasicRemote().sendText("来消息了");} catch (Exception e) {e.printStackTrace();}}//关闭@OnClosepublic void onClose(Session session) {//从容器中删除指定的用户log.info("onClose:{}", username);onlineUsers.remove(username);}
}
public static Map onlineUsers = new ConcurrentHashMap<>();

系统中用户名昵称是全局唯一的,所以可以将用户名作为主键,使得每个用户对应一个ChatEndpoint

4 服务器相关

采用宝塔面板进行傻瓜式操作。

注意在阿里云的云服务器实例开放所需要的所有端口

4.1 搭建环境遇到的问题

4.1.1 本地访问不了远程mysql数据库

在linux本地可以登录mysql, 但是本地机连不上远程的?

  原因是远程主机没有开放3306端口

开放3306端口号后,还是出现问题:

这是因为远程的 主机限制了只能localhost连接数据库

所以,在远程主机上修改这个限制,就可以解决这个问题了

1、在安装Mysql数据库的主机上登录root用户:

mysql -u root -p

2、执行命令:

use mysql;
select host from user where user='root';

可以得到结果:

表名此时mysql数据库只允许localhost连接,所以此前才会拒绝本地的主机连接远程服务器。

3、将Host设置为通配符%

update user set host = '%' where user ='root';

4、Host修改完成后记得执行flush privileges使配置立即生效

flush privileges;

5 前后端交互设计文档

使用Apipost

在课程设计的过程中,项目采用前后端分离技术。

有的人负责编写后端,有的人负责编写前端。这可以使得整个项目的结构更加清晰明了,但是前端如何去与后端交互是一个问题。

因为前后端是不同的人写的,所以需要提前规范好API文档

而ApiPost不仅可以对API接口进行调试,还可以自动生成相对应的文档,是一个非常实用的开发的工具。

 生成的文档,就比较清晰,比自己写一个API接口文档要规范的多

6 后台管理系统

renren.io

人人开源是Gitee上的一个开源项目,可以快速搭建后台管理系统

6.1 搭建步骤

6.1.1 初始化本地仓库

1、 创建一个总目录,用来承载多个项目

2、初始化为git仓库

进入test_project

 

6.1.2 从Gitee上拉取项目

 

同理,再拉取2个项目

最终的目录层次为:

6.1.3 配置、运行renren-fast项目

 

 

 

运行项目, 访问Swagger文档路径,如果可以正常访问,则表明一切正常。

 

6.1.4 配置、运行renren-fast-vue项目

打开renren-fast-vue项目, 这里本人使用的是WebStorm编译器

依赖安装完成, 打开终端,运行项目

这里的命令行是:

 npm run dev

 

登录成功后:

此时,这个项目还算是一个空壳,没有管理到真正自身的项目

这是就需要另一个项目, renren-generator 实现代码生成!

代码生成需要提供关于数据库的表


6.1.5 配置,运行 renren-generator

 

修改generator.properties

注释出现乱码问题,修改字符集编码

 

在renren_fast数据库中插入你真正项目中所使用的表, 可以在已有的数据库中选择转储sql文件,然后在renren_fast中执行这个sql文件即可。

然后,就可以在代码生成器中查到你刚刚插入的数据库表。

运行项目,访问localhost

 

代码就自动生成了。

解压文件,可以看到有如下内容:

这些sql文件,直接拖到navicat里执行就可以了。

作用是用来生成管理的子菜单

 

将后端代码复制到renren-fast项目下的 module

最后,就可以实现对模块的管理。

6.2 过程中遇到的问题

人人开源后端中,自带了一个User,而我们自身模块有一个名字一模一样的User

冲突1:

  • Spring容器中UserService组件不唯一

解决:

冲突2:

  • UserDao也是自动注入的。虽然说对应的mapper文件可以映射过去,但是名字重复了,还是会有点问题.

解决方法:

冲突3:

  • ShiroConfig 已经存在对UserEntity的映射。意思就是说,类名不能重复。

解决方法:修改类名

6.3 最终呈现效果

可以看到,用户的ID后几位都为0,这是由于前段接收Long类型时,出现精度丢失,以下为解决方式:

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...