首页 > 其他分享 >技术分享

技术分享

时间:2023-12-29 18:02:45浏览次数:33  
标签:return title 技术 public article 分享 data id

Java 是一种广泛使用的编程语言,有很多方面的技术专长可以涵盖。以下是一份可能的 Java 技术专长总结:

  1. 核心语言特性:
  • 熟练掌握 Java 语言的基本语法和核心特性。
  • 对面向对象编程(OOP)的概念有深入理解,包括类、对象、继承、封装和多态。
  1. Java 标准库:
  • 熟悉并能有效使用 Java 标准库中的核心类和接口。
  • 对集合框架、I/O 操作、多线程编程等有深入了解。
  1. Java EE(Enterprise Edition):
  • 了解 Java 企业级开发,包括 Servlet、JSP、EJB 等技术。
  • 熟悉 Java EE 容器(如 Tomcat、WildFly)的使用。
  1. Spring 框架:
  • 精通 Spring 框架,包括 Spring Core、Spring MVC 和 Spring Boot。
  • 能够使用依赖注入(DI)和面向切面编程(AOP)进行企业级应用开发。
  1. 持久层框架:
  • 对 Hibernate 或 MyBatis 等持久层框架有经验。
  • 熟悉数据库设计和 SQL 查询优化。
  1. RESTful Web Services:
  • 熟练设计和开发基于 REST 架构的 Web 服务。
  • 使用 JAX-RS 或 Spring MVC 等实现 RESTful 服务。
  1. 前端开发:
  • 了解 JavaScript、HTML 和 CSS。
  • 使用前端框架(如 Angular、React 或 Vue.js)与后端集成。
  1. 消息队列和异步编程:
  • 使用消息队列(如 RabbitMQ 或 Apache Kafka)实现异步通信。
  • 熟悉 Java 的多线程编程和并发控制。
  1. 微服务架构:
  • 了解微服务架构的概念和实践。
  • 使用 Spring Cloud 或类似的框架构建和管理微服务。
  1. 测试:
  • 熟悉单元测试和集成测试。
  • 使用 JUnit 或 TestNG 进行测试驱动开发。
  1. 构建和部署:
  • 使用 Maven 或 Gradle 进行项目构建。
  • 配置和管理持续集成和持续部署(CI/CD)流水线。
  1. 安全性:
  • 理解常见的安全问题,如跨站脚本(XSS)、跨站请求伪造(CSRF)等。
  • 使用框架和最佳实践确保应用程序的安全性。
  1. 监控和日志:
  • 配置和使用监控工具,如 Prometheus、Grafana。
  • 实施有效的日志记录和异常处理。
  1. 容器化和云计算:
  • 使用 Docker 容器化应用程序。
  • 在云平台(如 AWS、Azure、Google Cloud)上部署和管理应用程序。
  1. 性能调优:
  • 了解 JVM 的工作原理,进行性能调优。
  • 使用性能分析工具,如 VisualVM 或 YourKit。

在saveArticle方法的代码中,返回代码是这样的:

if (archive == null) {
            return ResponseEntity.badRequest().build();
        }
        else {
            URI uri = ServletUriComponentsBuilder.fromCurrentRequest()
                    .path("/{id}")
                    .buildAndExpand(archive.getTitle())
                    .toUri();

            return ResponseEntity.created(uri)
                    .body(archive);
        }

也就是正常时候回返回一个json的文章数据。出错的时候会返回badRequest().build()出来的东西。到了客户端后,其实浏览器就直接跑到ajax的error方法中去了。在error中处理出错的信息,都只有网络信息看的到。无法精确表达我们真正的出错信息。

所以,这里第一步就是改造和统一服务器Api的返回信息。

工程Model目录下,建立新的java类文件,全名ResponseMessage.java。全部代码如下:

package DefaultMain.Model;

public class ResponseMessage {
    private int code;
    private String message;
    private Object data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

这个是网络api比较通用的手法,一个code,表示返回码,通常成功会给一个值,其他的值可能就是各种出错信息码。一个message,表示对应的返回信息。一个data,是事实上的数据,客户端需要根据不同的api才知道具体对应的是什么。

在我们的教程中,code这个值是0的时候表示成功,先预留。其他的看情况再说,即使是真的项目,也是慢慢添加,没有人事先知道有多少码要添加。

有了这个基础,后面就是改造文章编辑的后台和前台。不过文章的数据结构是第一个要改造的。因为原先并没有已发布的标识。

改造Article类

仅仅是加入一个boolean类型的变量:published。再加上它对应的getter和setter,最后代码如下:

package DefaultMain.Model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;

import javax.validation.constraints.NotBlank;
import java.util.List;

public class Article {
    @Id
    private String id;

    @NotBlank(message = "title cannot be empty")
    private String title;
    @NotBlank(message = "content cannot be empty")
    private String content;
    @DBRef
    private Catalog catalog;
    @DBRef
    private List<Tag> tagList;

    private boolean published;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Catalog getCatalog() {
        return catalog;
    }

    public void setCatalog(Catalog catalog) {
        this.catalog = catalog;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public List<Tag> getTagList() {
        return tagList;
    }

    public void setTagList(List<Tag> tagList) {
        this.tagList = tagList;
    }

    public boolean isPublished() {
        return published;
    }

    public void setPublished(boolean published) {
        this.published = published;
    }
}

改造ArticleApi类

保存和即将实现的发布仅仅是写入数据的时候,差了一个字段的值。这样似乎只要拷贝原来的saveArticle方法稍微改下就能做出发布的方法。既然是拷贝都出来了,马上就想到这个必须用一个方法复用,所以,写一个方法在该类中:

private ResponseEntity<?> writeArticle(Article article) {
        Article archive;

        for (int i = 0; i < article.getTagList().size(); ++i) {
            String name = article.getTagList().get(i).getName();
            if (tagService.exists(name)) {
                //已经存在的tag,通过得到id绑定
                List<Tag> tags = tagService.findByName(name);
                article.getTagList().get(i).setId(tags.get(0).getId());
            }
            else {
                //还不存在的tag,需要先创建一个,然后再绑定
                Tag t = new Tag();
                t.setId(null);
                t.setName(name);
                t.setCreateTime(Utility.getNowTime());
                t = tagService.create(t);
                article.getTagList().get(i).setId(t.getId());
            }
        }

        if (article.getId().isEmpty()) {
            //MongoRepository的API决定了,只有id是null的时候,才会返回给数据库的id给我们
            article.setId(null);
            archive = articleService.create(article);
        }
        else {
            archive = articleService.update(article);
        }

        ResponseMessage message = new ResponseMessage();
        if (archive == null) {
            message.setCode(-1);
            message.setMessage("create or update article error.");
        }
        else {
            message.setCode(0);
            message.setMessage("success");
            message.setData(archive);
        }

        URI uri = ServletUriComponentsBuilder.fromCurrentRequest().build().toUri();
        return ResponseEntity.created(uri).body(message);
    }

这个方法不带注解,是给类的其他方法用的私有方法。代码细节基本跟原来的saveArticle方法相同,除了返回的时候用上了刚写的统一返回。

有了该方法,就可以把saveArticle方法改成如下:

@PostMapping("/api/savearticle")
    public ResponseEntity<?> saveArticle(@Valid @RequestBody Article article) {
        article.setPublished(false);
        return writeArticle(article);
    }

然后,我们再在该类里面添加一个api方法用于发布:

@PostMapping("/api/publishrticle")
    public ResponseEntity<?> publishArticle(@Valid @RequestBody Article article) {
        article.setPublished(true);
        return writeArticle(article);
    }

好了。后台代码就修改完成。不过还测试不了,因为前端代码没有发布功能,而且因为我们对返回值的结构改动,原来的功能也会出错,得改!

newarticle.js

因为后台的返回数据结构导致的改动,现在只有saveArticle()方法,而且集中在netPostJson方法的两个回调上,所以我这里只贴出netPostJson的整体:

netPostJson(url, data, function(data) {
            if (data.code === 0) {
                Toast.fire({
                    type: 'success',
                    title: '保存成功'
                });

                if (id == "") {
                    $('#article-id').attr('value', data.data.id);
                }
            }
            else {
                Toast.fire({
                    type: 'error',
                    title: data.message
                });
            }
        }, function(xhr) {
            Toast.fire({
                type: 'error',
                title: "Ajax 发生错误: " + xhr.responseText
            });
        });

相比较原来,现在会先查看返回值中的code,只有0的时候表示是真的成功。否则,则会显示出服务器返回的错误的信息。

最后就是真正的向后台发起发布请求。也是因为只有一个属性不同,其他功能都相同。所以只要改造一下原来的saveArticle方法,给一个参数,指定是“保存”还是“发布”即可。不多细节上的东西不能少:比如后台数据返回后的提示,还有调用的是不同的api。

最后的saveArticle方法是这样:

function saveArticle(onlySave) {
    var title = $('#article-title').val();
    var catalog = $("#catlog-selection").val();
    var content = window.editor.getData();
    var id = $('#article-id').attr('value').trim();
    var tagList = $('#tags-container').find('.token-autocomplete-token');

    if (title == null || title.trim() == '') {
        console.log("题目不能是空的");
        return;
    }

    if (catalog == null || catalog.trim() == '') {
        console.log("分类不能是空的");
        return;
    }

    if (content == null || content.trim == '') {
        console.log("内容不能是空的");
        return;
    }

    if (tagList.length == 0) {
        console.log("标签不能是空的");
        return;
    }

    var tags = [];
    for (var i = 0; i < tagList.length; ++i) {
        var tag = {};
        tag.name = tagList[i].getAttribute('data-text');
        tags.push(tag);
    }

    var data = {'title': title, 'content': content, 'catalog': { 'id': catalog }, 'tagList': tags, 'id': id};
    var url = document.location.origin;
    if (onlySave) {
        url += '/api/savearticle';
    }
    else {
        url += '/api/publisharticle';
    }

    netPostJson(url, data, function(data) {
            if (data.code === 0) {
                Toast.fire({
                    type: 'success',
                    title: '成功'
                });

                if (id == "") {
                    $('#article-id').attr('value', data.data.id);
                }
            }
            else {
                Toast.fire({
                    type: 'error',
                    title: data.message
                });
            }
        }, function(xhr) {
            Toast.fire({
                type: 'error',
                title: "Ajax 发生错误: " + xhr.responseText
            });
        });
}

还差不一步,调用该方法的地方得相应改动!

改动newArticle.ftl

找到“保存”这样的字眼的行,改成:

<button class="btn btn-secondary" onclick="saveArticle(true)">保存</button>

这一行紧邻的下一行,改成:

<button class="btn btn-success" onclick="saveArticle(false)">发布</button>

标签:return,title,技术,public,article,分享,data,id
From: https://blog.51cto.com/u_16483295/9029655

相关文章

  • GB28181监控系统LiteCVR视频监控技术在农业种植园中的应用
    随着科技的进步,LiteCVR视频监控技术已经成为农业现代化不可或缺的一部分。在农业种植园中,这种技术的应用为农业生产带来了诸多便利。首先,LiteCVR视频监控技术为种植园提供了24小时的实时监控。无论是白天还是夜晚,管理人员都可以通过视频监控系统随时了解种植园的情况,掌握作物的生......
  • 大模型时代,如何构建技术壁垒?
    在2023年的尾声回顾这一年,大模型毫无疑问是科技产业最值得关注的话题。在人们畅想掀起新一波AI浪潮的大模型将如何变革各个行业时,却发现大模型最先“颠覆”的是AI产业本身:大模型具备如此强大且不断进化的“泛化”能力,让“小模型”时代发展起来的众多AI公司似乎在一夜之间丧失了自己......
  • ShowMeBug X 元象唯思 | 打造全面技术招聘流程,提升人才甄选效率
    ShowMeBug签约了元象唯思控股深圳有限公司(以下简称元象唯思),凭借完善的技术招聘解决方案,ShowMeBug助力元象唯思构建全流程技术招聘,打造科学的人才筛选机制,帮助企业快速识别优质技术人才。ShowMeBug技术测评平台集成了30多种编程语言与主流开发框架,不仅满足了元象唯思多个技术岗......
  • 数据结构实验代码分享 - 4
    迷宫与栈问题(图的应用)【问题描述】以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。输入:行列迷宫,0表示无障碍,1表示有障碍输出:一条Path或“NOPATH” 注:参考了《数据结......
  • 金蝶云苍穹技术开放日第十期精彩回顾|赋能开发者提升项目质量
    12月28日,以“开发之巅:项目质量提升之道”为主题的第十期技术开放日活动圆满结束。此次线上交流活动吸引了超过1700+开发者热情参与,来自金蝶云苍穹平台生态部的技术架构师——郑烈彬老师和金蝶中国用户体验部的产品经理——曹卫群老师分别带来了关于开发助手工具的深入解析和用户......
  • 技术文档 | 在Jenkins及GitlabCI中集成OpenSCA,轻松实现CI/CD开源风险治理
    插播:OpenSCA-cli现支持通过homebrew以及winget安装:Mac/Linuxbrewinstallopensca-cliWindowswingetinstallopensca-cli总有小伙伴问起如何在CI/CD中集成OpenSCA,文档它这不就来啦~若您解锁了其他OpenSCA的用法,也欢迎向项目组来稿,将经验分享给社区的小伙伴们~Jenkins在Jenk......
  • 金蝶云苍穹技术开放日第十期精彩回顾|赋能开发者·提升项目质量
    12月28日,以“开发之巅:项目质量提升之道”为主题的第十期技术开放日活动圆满结束。此次线上交流活动吸引了超过1700+开发者热情参与,来自金蝶云苍穹平台生态部的技术架构师——郑烈彬老师和金蝶中国用户体验部的产品经理——曹卫群老师分别带来了关于开发助手工具的深入解析和用......
  • 技术文档 | 在Jenkins及GitlabCI中集成OpenSCA,轻松实现CI/CD开源风险治理
    ​插播:OpenSCA-cli现支持通过homebrew以及winget安装:Mac/Linuxbrewinstallopensca-cliWindowswingetinstallopensca-cli总有小伙伴问起如何在CI/CD中集成OpenSCA,文档它这不就来啦~若您解锁了其他OpenSCA的用法,也欢迎向项目组来稿,将经验分享给社区的小伙伴们~Je......
  • 【代码分享】10行代码写一个超级简单的进度条
    我们知道,Python使用rich或tqdm模块可以轻松创建进度条,那么如果我们自己写一个,需要几行代码呢?答案是4行。显示效果完整代码完整代码如下,核心代码也就4行#!/usr/bin/envpython#-*-coding:UTF-8-*-importtimedefprogress_bar(desc:str,index:int,total:int,b......
  • iOSapp开发怎么分享小程序?
    Hello,大家好我是咕噜铁蛋!随着移动互联网的迅猛发展,小程序作为一种新型的应用形态,已经逐渐成为移动开发领域的新宠。对于iOS开发者来说,如何将自己的APP与小程序进行无缝对接,为用户提供更加便捷的服务,成为了一个值得探讨的话题。今天铁蛋讲为大家详细解读iOS开发APP如何分享小程序。......