赞
踩
需要对Ont设备终端进行管理。
现在存在的问题:管理系统过于麻烦(命令行操作),不直观(无图形化页面),普通管理人员难以上手进行管理,只能交由特点人员维护(效率低下)。
开发一个图形化操作界面,基于网页或小程序,页面直观,方便维护Ont设备。
采用主流的前后端分离模式,基于SpringBoot开发框架
项目特殊问题:
1.需要从平台获取Ont信息(链接其他服务器)
2.数据同步要求
Ont 的增删查改
数据库:MySQL
1.SpringBoot
2.MybatisPlus
3.Validation
4.JWT
5.Lombok
客户端发起请求:用户通过浏览器或其他客户端发送请求,请求访问某个URL。
前端控制器接收请求:Spring MVC框架中的前端控制器接收到请求,并根据配置的请求映射规则将请求转发给相应的控制器。使用Spring安全框架过滤请求。
控制器处理请求:控制器类(controller包中)接收到请求后,根据业务逻辑调用相应的服务类。
服务类处理业务逻辑:服务类(service包中)是处理业务逻辑的核心部分。它可以调用一个或多个数据访问对象(DAO)来获取数据,并进行必要的处理。
数据访问对象操作数据库:数据访问对象(通常位于dao包中)封装了与数据库的交互操作,使用MyBatis框架执行SQL语句,将数据从数据库中读取或写入。
控制器返回响应数据:控制器接收到服务类处理完毕后的结果,并根据业务需求进行数据处理和封装,然后将响应数据返回给前端控制器。
前端呈现响应结果:最终响应结果由前端控制器发送给客户端,客户端通过浏览器渲染并显示在用户界面上。
1.获取未注册的Ont
流程:接收请求,请求Ont信息服务器
- public PageVo getOntByIds(GetOntListDTO dto) throws IOException {
-
- String charset = "UTF-8";
- //创建集合
- Map<String, String> params = new HashMap<>();
- //参数判断,有则放入Map集合
- if (dto.getFrameid() != null) {
- params.put("frameid", dto.getFrameid().toString());
- }
- if (dto.getSlotid() != null) {
- params.put("slotid", dto.getSlotid().toString());
- }
- if (dto.getPortid() != null) {
- params.put("portid", dto.getPortid().toString());
- }
- if (dto.getOntid() != null) {
- params.put("ontid", dto.getOntid().toString());
- }
- params.put("pageNum",dto.getPageNum().toString());
- params.put("pageSize",dto.getPageSize().toString());
- StringBuilder query = new StringBuilder();
- int i = 0;
-
- //生成Get的参数区域
- for (Map.Entry<String, String> entry : params.entrySet()) {
- query.append(URLEncoder.encode(entry.getKey(), charset));
- query.append("=");
- query.append(URLEncoder.encode(entry.getValue(), charset));
- if (i < params.size() - 1) {
- query.append("&");
- }
- i++;
- }
- //拼接URL
- String url = GET_ONT_LIST_API +"?"+ query;
- // System.out.println(url);
- //发起请求
- return HttpUtil.getAll(url, OntApi.class);
- }
难点:
参数处理:代码中通过判断dto
对象中的各个参数是否存在,将其放入params
集合中。这样做的目的是根据参数的有无动态地构建请求URL。
URL拼接*:根据生成的参数集合params
,通过遍历拼接成一个完整的URL,包含了API地址和参数部分。需要注意对参数进行URL编码,确保参数的正确传递。
2.与后台同步:
流程:前端发起注册/注销等功能时,告知后台(发起请求)
注册为例:
- public ResponseResult register(RegisterOntDto ont) {
-
- List<OntRegister> list = ontRegisterMapper.selectDelFlagBySn(ont.getSn());
- for (OntRegister flag : list) {
- if (flag != null && flag.getDelFlag() == 1){
- return ResponseResult.errorResult(405,"注册失败,Ont已经被注册");
- }
- }
-
- OntRegister ontRegister = BeanCopyUtils.copyBean(ont, OntRegister.class);
- ontRegister.setCreateTime(LocalDateTime.now());
- //获取注册用户
- ontRegister.setUserid(commonService.getUserInfo().getId());
- //设置具体信息
- //从api获取未注册的ont by SN
- GetOntVo o = httpGetApiService.getOnt(ont.getSn());
- ontRegister.setPort(o.getPortid());
- ontRegister.setFrameid(o.getFrameid());
- ontRegister.setSlotid(o.getSlotid());
- ontRegister.setOntid(o.getOntid());
-
- //将注册Ont写入表中
- ontRegisterMapper.insert(ontRegister);
- //发送请求到信息中心
- RegisterApiOntDTO registerApiOntDTO = BeanCopyUtils.copyBean(ontRegister, RegisterApiOntDTO.class);
- Boolean r = httpGetApiService.registerOnt(registerApiOntDTO);
- if (r == false){
- return ResponseResult.errorResult(405,"注册失败");
- }
- //发送请求到信息中心
- log.info(ontRegister.toString());
- return ResponseResult.okResult("ok");
- }
3.地点的模糊搜索:
- public ResponseResult getPlaceByFuzzyPlace(String place) {
- //判断传入的参数是否为空 是 => 空数组:[]
- if ("empty".equals(place)) {
- ResponseResult result = ResponseResult.okResult();
- result.ok(new ArrayList<>());
- return result;
- }
- //HashSet 去除重复地址
- HashSet placeList = ontRegisterMapper.getPlaceByFuzzyPlace(place);
- return ResponseResult.okResult(placeList);
- }
Mapper
- <select id="getPlaceByFuzzyPlace" resultType="String">
- select address
- from ont_register
- where address like concat('%', #{place}, '%')
- </select>
系统架构设计清晰:项目中采用了明确的系统架构设计,如MVC(Model-View-Controller)模式或其他合适的架构模式,提高了代码结构的清晰性和模块的解耦程度,使系统易于扩展和维护。
业务逻辑与控制器分离:控制器中的业务逻辑被合理地抽取到服务层(Service)或领域层(Domain)中,使控制器专注于请求处理和参数校验,符合单一职责原则,提高了代码的可读性和可维护性。
异常处理完善:项目中建立了统一的异常处理机制,捕获并处理各类异常,并返回友好的错误信息给用户,同时记录异常日志以便排查问题,提高了用户体验和系统的稳定性。
充分的测试覆盖:项目具有全面的测试覆盖,包括单元测试、集成测试和端到端测试等,确保了代码的正确性和稳定性,提高了项目的质量和可靠性。
统一的日志记录:项目中引入了日志框架,统一记录关键操作、异常情况和性能指标,有助于追踪和排查问题,提供了运行时的监控和分析能力,方便系统运维和故障排查。
代码风格和规范统一性:项目制定了统一的代码风格和规范,保持了代码的一致性,提高了代码的可读性和可维护性,便于团队协作和代码维护。
安全性考虑充分:项目中充分考虑了安全性问题,实施了输入验证、数据加密、权限控制等安全措施,保护系统的数据和功能免受攻击和滥用,提高了系统的安全性。
文档和注释完善:项目中有充足的文档和注释,清晰地解释了项目的设计、功能和使用方法,有助于团队协作、新成员上手和项目的可维护性,提高了项目的开发效率和质量。
一些不足之处:
性能优化:项目中可能缺乏对性能优化的深入考虑,没有进行充分的性能测试和分析,导致系统在高并发或大数据量的情况下性能下降,响应时间较长。
代码复用:可能存在代码重复的情况,未充分利用抽象和封装来提高代码的可重用性,导致代码冗余和维护困难。
缓存策略:项目可能缺乏合适的缓存策略,没有充分利用缓存来提高系统性能和响应速度,导致系统在频繁访问相同数据时效率较低。
安全漏洞:尽管项目中有考虑安全性问题,但可能存在一些潜在的安全漏洞,如未对用户输入进行充分验证、未对敏感数据进行适当的加密等,可能导致安全风险和数据泄露的风险。
代码审查:项目中可能未进行足够的代码审查,导致潜在的错误和不规范的代码进入到生产环境中,增加了系统稳定性和维护的风险。
可扩展性:项目可能缺乏足够的可扩展性设计,当需求变更或业务规模扩大时,可能需要大量的修改和重构,增加了开发和维护的复杂性。
以下是对于之前提到的一些缺点的解决措施的简短说明:
完善的统一的错误处理机制:实施全局异常处理,捕获和处理项目中的异常情况,统一返回格式化的错误信息,并记录日志以便排查和修复问题。
进行性能优化:通过性能测试和性能分析,识别性能瓶颈并进行相应的优化,例如使用缓存、减少数据库查询次数、优化算法等,以提高系统的响应速度和扩展能力。
提升代码复用性:抽象和封装可重复使用的代码片段,将其作为公共组件或工具类提供给其他模块使用,减少代码冗余和维护成本。
实施合适的缓存策略:根据业务需求和数据访问模式,选择合适的缓存方案,例如使用内存缓存、分布式缓存等,以提高数据的读取效率和系统的性能。
加强安全性措施:实施严格的用户输入验证,包括数据格式、长度、特殊字符等的检查,同时对敏感数据进行加密存储和传输,以减少安全漏洞和数据泄露的风险。
完善文档和注释:编写清晰的代码注释,解释代码逻辑和设计意图,同时编写详细的文档,包括项目结构、接口说明、配置说明等,以便于团队成员理解和维护代码。
进行代码审查:建立代码审查机制,定期对项目中的代码进行审查,确保代码质量和规范,发现潜在的问题和改进空间,提高系统的稳定性和可维护性。
考虑可扩展性:在系统设计和开发过程中,充分考虑系统的可扩展性,采用松耦合的架构设计和模块化开发,以便在未来需求变更或业务扩展时更容易进行扩展和修改。
在完成该项目的开发过程中,我们面临了一些挑战和问题,但通过团队的努力和合作,我们成功地克服了这些困难,并取得了令人满意的结果。以下是对整个项目开发过程的总结和反思:
首先,我们对项目的需求进行了充分的分析和理解,确保在开发过程中我们与客户保持密切的沟通和协作。这为项目的顺利进行奠定了坚实的基础,并帮助我们准确地把握和满足客户的期望。
其次,我们在技术选择和架构设计上做出了明智的决策。通过评估各种技术选项和考虑项目的需求,我们选择了合适的技术栈和架构。
在开发过程中,我们注重代码质量和可维护性。我们遵循了良好的编码规范,并定期进行代码审查和重构,以确保代码的清晰度和可读性。这有助于减少潜在的错误和问题,并提高团队成员之间的协作效率。
同时,我们注重测试和质量保证。我们采用了多层次的测试策略,包括单元测试、集成测试和自动化测试,以确保项目的稳定性和功能的正确性。我们也积极采纳用户的反馈和意见,并及时修复和改进项目中的问题。
在团队合作方面,我们保持了良好的沟通和协作。通过定期的会议和沟通渠道,我们能够及时共享信息、解决问题,并保持团队的凝聚力和效率。我们也鼓励团队成员提出创新想法和改进措施,以推动项目的进步和发展。
总而言之,这个项目的开发过程不仅仅是技术上的实践,更是团队合作和项目管理的良好体现。我们通过克服挑战和解决问题,获得了宝贵的经验和教训。这次开发经历使我们更加成熟和专业,并为未来的项目开发奠定了基础。
在未来的项目中,我们将继续秉持着这些经验和教训,不断改进和提升自身的能力和技术水平。我们将继续关注用户需求,注重代码质量和可维护性,以及加强团队的沟通和协作。通过不断学习和进步,我们相信我们能够更好地应对挑战,取得更大的成就。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。