尝试用kotlin做一个app(五)

JSP后台管理系统

开发工具是IntelliJ IDEA+tomcat+mysql5.6.19+mysql-connector-java-5.1.48.jar+easyui+kindeditor

之前也有记录一些Servlet基础(java,idea)

这篇我只把一些重要的记录一下

easyui官方文档

kindeditor官方文档

easyui很简单,而且中文文档介绍得很详细,对照文档做就好了

kindeditor问题比较多,这里记录一下

准备工作

mysql数据库test中建立t_hp_new表

create table t_hp_new(id int primary key auto_increment,title varchar(100),author varchar(30),pubdate datetime,origin varchar(50),href varchar(200),thumb mediumtext,content mediumtext);

thumb是缩略图,为blob类型,这里先不考虑这个。建立New类been数据的时候,把thumb定义为String类型

kindeditor的使用

·初始化

在需要使用kindeditor的地方添加

    <link type="text/css" href="kindeditor-4.1.11-zh-CN/kindeditor/themes/default/default.css" rel="stylesheet">
    <script type="text/javascript" src="kindeditor-4.1.11-zh-CN/kindeditor/kindeditor-all.js"></script>
    <script type="text/javascript" src="kindeditor-4.1.11-zh-CN/kindeditor/kindeditor-all-min.js"></script>
    <script type="text/javascript" src="kindeditor-4.1.11-zh-CN/kindeditor/lang/zh-CN.js"></script>

内容编辑区域是一个富文本框

<th> <textarea id="editor" name="editor" style="height:480px;width:900px"></textarea> </th>

初始化

    <script type="text/javascript">
        let editor
        KindEditor.ready(function (K) {
            editor=K.create(‘textarea[id="editor"]‘,{
                items:[‘source‘, ‘undo‘, ‘|‘, ‘redo‘, ‘|‘, ‘cut‘, ‘copy‘, ‘paste‘, ‘|‘, ‘plainpaste‘, ‘|‘, ‘fontname‘, ‘fontsize‘, ‘forecolor‘, ‘hilitecolor‘, ‘bold‘, ‘italic‘, ‘underline‘, ‘strikethrough‘, ‘|‘, ‘justifyleft‘, ‘justifyright‘, ‘justifycenter‘, ‘|‘, ‘image‘, ‘insertfile‘, ‘link‘, ‘code‘],
            })
        })
    </script>

items:可选

添加插入图片功能

添加uploadJson:"kindeditor-4.1.11-zh-CN/kindeditor/jsp/upload_json.jsp"

把jsp/lib下的jar包粘贴到web工程的lib目录下

此时提示上传目录不存在

然后修改upload_json.jsp的savepath

String savePath=request.getSession().getServletContext().getRealPath("/");

在这里顺便把saveUrl也改了,因为后面会用到saveUrl

(这个问题不一定是这样,也可以试着在web目录下新建一个attached目录)

把上图图片插入到编辑框里

默认上传图片后,点显示html源码它是这样的,浏览器错误提示Not allowed to load local resource

<img>标签不允许引用本地磁盘的图片

一种解决办法是把src后的url的图片转换成base64编码

定义编码函数

看情况导入包,如果提示错误The import java.util.Base64.Encoder collides with another import statement就去掉

<%@ page import="java.util.Base64.Encoder" %>
<%@ page import="java.util.Base64.Decoder" %>
//图片编码
<%!
    public String getBaseImg(String imgPath){
        InputStream in=null;
        byte[] data=null;

        try{
            in=new FileInputStream(imgPath);
            data=new byte[in.available()];
            in.read(data);
            in.close();

        }catch (Exception e) {
            e.printStackTrace();
        }
        Base64.Encoder encoder=Base64.getEncoder();
        String encode=encoder.encodeToString(data);
        return encode;
    }

%>

在传递saveUrl之前,对saveUrl进行编码处理

JSONObject obj = new JSONObject();//String saveUrlEncode="data:image/jpeg;base64,"+getBaseImg(saveUrl + newFileName);obj.put("error", 0);obj.put("url", saveUrlEncode);out.println(obj.toJSONString());

记得要加"data:image/jpeg;base64,"这个加在base64编码前,<img>标签才能正常显示

kindeditor编辑框内容上传

在表单提交之前首先要把kindeditor的内容同步到textarea中,使用

editor.sync()

那这样提交一下就厉害了,发送这么一长串请求会遇到问题:

比如java.lang.IllegalArgumentException: Request header is too large 请求头太大

具体可以参考Servlet基础(java,idea)之前提到改成post会乱码,是因为没有添加req.setCharacterEncoding("utf-8");(那这里就可以把get请求改成post了,不用之后的对内容进行url编码)

还有一个easyui也不能正常读取新闻列表了

这是因为之前读取数据库的数据,把数据转换成Json数据(使用json-lib),而json数据里不能存在html的一些标签,特殊符号的。具体的错误提示at net.sf.json.util.JSONTokener.syntaxError

那在New的java been类中,添加一个自定义的tostring1()函数,把content转化为url编码

public String toString1() {
        Long date=0L;
        if(pubdate!=null){
            date=pubdate.getTime();
        }
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String dateString=sdf.format(date);

        String contentUrlEncode= URLEncoder.encode(content);

        return "{" +
                "id=" + id +
                ", title=‘" + title + ‘\‘‘ +
                ", author=‘" + author + ‘\‘‘ +
                ", pubDate=" + dateString +
                ", origin=‘" + origin + ‘\‘‘ +
                ", href=‘" + href + ‘\‘‘ +
                ", content=‘" + contentUrlEncode + ‘\‘‘ +
                ", thumb=‘" + thumb + ‘\‘‘ +
                ‘}‘;
    }

在执行select * from t_hp_new查询的时候,会输出很长的字段值,那这个暂时没办法了

关于缩略图上传(也可以是通用图片上传)

先是form表单要改一下,添加enctype="multipart/form-data"

<form id="fm" method="post" enctype="multipart/form-data">

点击提交,发现浏览器上传这样一段数据(request payload)

------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="title"

a
------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="thumb"; filename="1.png"
Content-Type: image/png

------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="editor"

b
------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="author"

c
------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="origin"

d
------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="href"

e
------WebKitFormBoundary8BC9g9ZlOORkXrkN--

(改成get请求,好像是正常title=%E5%93%88%E5%93%88&thumb=1.jpg&editor=00&author=ee&origin=dd&href=ex;这里还是改回post)

上面那段字符串,分为两种域,一种是图片文件的域

------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="thumb"; filename="1.png"
Content-Type: image/png

一种是普通form的域

d
------WebKitFormBoundary8BC9g9ZlOORkXrkN
Content-Disposition: form-data; name="href"

接下来就有点傻了,我们要在字符串里,截取文件filename,Content-Type和name以及下面的值。那就先随便试一下

这个看起来很复杂,但是思路是挺简单的。这里没必要看别人的代码,自己动手实践一下就好

public class main {
    public static void main(String[] args) {
        String str = "------WebKitFormBoundaryoAZzkCVEWZ0J434f\n" +
                "Content-Disposition: form-data; name=\"title\"\n" +
                "WO\n" +
                "------WebKitFormBoundaryoAZzkCVEWZ0J434f\n" +
                "Content-Disposition: form-data; name=\"thumb\"; filename=\"1.jpg\"\n" +
                "Content-Type: image/png\n" +
                "------WebKitFormBoundaryoAZzkCVEWZ0J434f\n" +
                "Content-Disposition: form-data; name=\"editor\"\n" +
                "HAHA\n" +
                "------WebKitFormBoundaryoAZzkCVEWZ0J434f\n" +
                "Content-Disposition: form-data; name=\"author\"\n" +
                "DD\n" +
                "------WebKitFormBoundaryoAZzkCVEWZ0J434f\n" +
                "Content-Disposition: form-data; name=\"origin\"\n" +
                "EE\n" +
                "------WebKitFormBoundaryoAZzkCVEWZ0J434f\n" +
                "Content-Disposition: form-data; name=\"href\"\n" +
                "SS\n" +
                "------WebKitFormBoundaryoAZzkCVEWZ0J434f--\n";
        String contentType = "multipart/form-data; boundary=----WebKitFormBoundaryoAZzkCVEWZ0J434f";
        int position = contentType.indexOf("boundary=");

        position += ("boundary=").length();
        String boundary = "--" + contentType.substring(position);

        String lastboundary = boundary + "--";
        System.out.println(lastboundary);

        BufferedReader reader = new BufferedReader(new StringReader(str));
        String s = null;
        while (true) {
            try {
                //读取每一行,当读取到最末一行或者返回null的时候结束
                s = reader.readLine();
                if (s == lastboundary || s == null) break;
                if (s.startsWith(boundary)) {
                    s = reader.readLine();//读取下一行
                    if (s != null) {
                       if(s.indexOf("filename=")!=-1){
                           //上传图片域
                           //截取文件名
                           int pos=s.indexOf("filename=");
                           pos+="filename=".length();
                           String filename=s.substring(pos);
                           filename=filename.replace("\"","");
                           //继续获取图片文件类型
                           s=reader.readLine();
                           pos=s.indexOf("Content-Type:");
                           pos+="Content-Type:".length();
                           String type=s.substring(pos).replace(" ","");
                           System.out.println(type);
                           //判断图片类型应该是image/jpeg,image/png,image/gif
                           if(type.equals("image/jpeg")||type.equals("image/png")||type.equals("image/gif")){
                               System.out.println("上传图片格式正确");
                           }else {
                               System.out.println("只支持上传jpg,png,gif文件");
                           }

                       }else {
                           //普通from域
                           int pos=s.indexOf("name=");
                           pos+="name=".length();
                           String name=s.substring(pos);
                           name=name.replace("\"",""); //获得name
                           //再读取下一行获取到值
                           s=reader.readLine();
                           String value=s;
//                           System.out.println("{name:"+name+",value:"+value+"}");

                       }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

那之后的重点是获得图片流数据。当执行

       ServletInputStream in = req.getInputStream();
        int len = req.getContentLength(); //获得请求数据字节长度
        byte[] orginData = new byte[len];//len字节数组
        orginData=in.readAllBytes();
        in.close();
        String orginStr=new String(orginData);
        System.out.println(orginStr);

会输出一段乱码,那么乱码的位置就是图片流数据的位置。先找到字符串orginStr乱码的开始,结束位置,过程大概是这样

这个过程的代码如下

public class AddNewsServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//    req.setCharacterEncoding("utf-8");
//    String title=req.getParameter("title");
//    String author=req.getParameter("author");
//    String content=req.getParameter("editor");
//    String origin=req.getParameter("origin");
//    String href=req.getParameter("href");

        //获得请求流数据,并转换成字符串
        ServletInputStream in = req.getInputStream();
        int len = req.getContentLength(); //获得请求数据字节长度
        byte[] orginData = new byte[len];//len字节数组
        orginData=in.readAllBytes();
        in.close();
        String orginStr=new String(orginData);

        String contentType=req.getContentType();//
        int position = contentType.indexOf("boundary=");

        position += ("boundary=").length();
        String boundary = "--" + contentType.substring(position);
        String lastboundary = boundary + "--";

        BufferedReader reader = new BufferedReader(new StringReader(orginStr));

        String savePath=req.getSession().getServletContext().getRealPath("/")+"thumb/";
        String s = null;
        JSONObject params=new JSONObject();
        while (true) {
            try {
                //读取每一行,当读取到最末一行或者返回null的时候结束
                s = reader.readLine();
                if (s == lastboundary || s == null) break;
                if (s.startsWith(boundary)) {
                    s = reader.readLine();//读取下一行
                    if (s != null) {
                        if(s.indexOf("filename=")!=-1){
                            //上传图片域
                            //截取文件名
                            int pos=s.indexOf("filename=");
                            pos+="filename=".length();
                            String filename=s.substring(pos);
                            filename=filename.replace("\"","");
                            //继续获取图片文件类型
                            s=reader.readLine();
                            pos=s.indexOf("Content-Type:");
                            pos+="Content-Type:".length();
                            String type=s.substring(pos).replace(" ","");
                            System.out.println(type);
                            //判断图片类型应该是image/jpeg,image/png,image/gif
                            if(type.equals("image/jpeg")||type.equals("image/png")||type.equals("image/gif")){
                                System.out.println("上传图片格式正确");
                                //重命名图片名称
                                filename=filename.substring(filename.lastIndexOf("."));
                                SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
                                String ymd=sdf.format(new Date());
                                String newFilename=ymd+filename;

                                //获得图片流开始位置
                                int typeStart=orginStr.indexOf("Content-Type"); //定位到Content-Type开始位置
                                int fileStart=orginStr.indexOf("\n",typeStart)+1;//定位到Content-Type下一行
                                fileStart=orginStr.indexOf("\n",fileStart)+1;//再下一行
                                //获得图片流结束的位置
                                int fileEnd=orginStr.indexOf(boundary,fileStart);//从文件开始处开始查找,直到第一个boundary出现
                                String saveFile=orginStr.substring(fileStart,fileEnd);
//                                System.out.println(saveFile);
//                                System.out.println(orginStr);
                                int contentStart=orginStr.substring(0,fileStart).getBytes().length;
                                int contentEnd=orginStr.substring(0,fileEnd).getBytes().length;

                                FileOutputStream out=new FileOutputStream(savePath+newFilename);
                                out.write(orginData,contentStart,contentEnd);
                                out.close();

                            }else {
                                System.out.println("只支持上传jpg,png,gif文件");
                            }

                        }else {
                            //普通form域
                            int pos=s.indexOf("name=");
                            pos+="name=".length();
                            String name=s.substring(pos);
                            name=name.replace("\"",""); //获得name
                            //再读取下一行获取到值,可能是空行,那就继续读下一行
                            while ((s=reader.readLine()).equals("")){ }
                            String value=s;
                            //添加进json
                            params.put(name,value);

                        }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        System.out.println(params);

        //获得系统的时间
//    Timestamp pubdate=new Timestamp(System.currentTimeMillis());
//    int count=new T_NewImpl().addNewsForHp(title,author,content,origin,href,pubdate);
//    resp.setContentType("text/html;charset=utf-8");
//    JSONObject result=new JSONObject();
//    result.put("count",count);
//
//    resp.getWriter().println(result);
//    resp.getWriter().flush();
//    resp.getWriter().close();

    }
}

那如果是这样,看来数据库的thumb字段还是让它是varchar类型好了,就保存一个图片的地址;或者要保存到数据库的话,就把图片流数据写到数据库里吧,之前尝试过,在这里面常用sql语句(mysql测试)

简直不要太累

源码

链接:https://pan.baidu.com/s/1Crxq7HpciMDkTNQ5zannrA
提取码:ebms

不要直接运行这个程序,AddNewsServlet还没写好。。。

原文地址:https://www.cnblogs.com/vocus/p/12370269.html

时间: 2024-11-01 00:09:22

尝试用kotlin做一个app(五)的相关文章

尝试用kotlin做一个app(十六)

继续优化一下可折叠的toolbar.目前的效果是这样 这里有几个问题: 1.我这里是设置了一下状态栏的颜色,但是要设置状态栏透明.设置状态栏透明之后,其实是actionbar会与状态栏重合,而toolbar并不会.所以要在activity中设置setSupportActionBar(Toolbar),让toolbar act as actionbar 2.toolbar和状态栏重合问题,按照之前的方法应该设置toolbar具有一个与状态栏高度的paddingTop,但是这里有个更简单的方法,即在

尝试用kotlin做一个app(八)

点击新闻列表进入详情页 使用WebView 1.准备工作 现在没有办法把整个网站前端都做出来,就先做一个新闻页面吧.新闻页面也要连接数据库,要使用之前写后台的JDBC类,所以我想可以在原来项目中增加一个“子项目”.那就要调整一下原来项目的结构. 调整后的项目结构是这样的 以下是遇到的问题和解决方法 idea项目重命名 如果出现错误javax.management.InstanceNotFoundException: Catalina:type=Server,查看artifacts下的是否还保留了

尝试用kotlin做一个app(三)

新闻列表 添加新闻列表可以使用RecyclerView.但是有个问题,RecyclerView只会在内部滚动,不会带动整个屏幕滚动.所以在原根布局外层添加androidx.core.widget.NestedScrollView,并且在原先根局部,添加android:descendantFocusability,解决进入页面跳入页面底部的问题. ·添加RecyclerView <androidx.recyclerview.widget.RecyclerView android:id="@+

尝试用kotlin做一个app(十一)

为新闻列表页加载数据库数据,并为条目添加点击事件,点击进入新闻详情页 又转战后台了 java文章,kotlin文章还有其他文章是用一个表,还是分别建不同的表呢,我想还是建一个表吧,为表增加一个分类的字段就行了.文章一共有10个类别,分别是: 新建两个表.一个是文章表,一个是用户表.两个表包含的字段信息如下 数据库表也是有命名规范的,但是我这暂时不用处理很复杂的表,所以命名直白点就好.文章应该有作者,又要通过文章的作者查询到作者的头像,所以应该有一次联合查询. create table artic

尝试用kotlin做一个app(六)

还是关于JSP后台管理系统的,有几个问题要解决一下 使用虚拟路径访问本地图片 之前在kindeditor编辑框插入图片时,是把图片文件转换为base64编码的形式:还有一种方法是使用虚拟地址.另外图片在数据库中存储的时候,应该是存储图片的虚拟地址(当然也可以是图片的二进制流数据). 可以参考 idea设置tomcat虚拟路径的两种方法 配置好了之后,就得把图片的路径上传到数据库中,更新表t_hp_new的thumb字段 后台登录状态验证 这里先不做,因为程序还在调试,每次进入要登录也是很麻烦了.

做一个App究竟要花多少钱?

作为互联网从业者,被外行的朋友们问及最多的问题是: “做一个网站需要多少钱?”或者“做一个APP需要多少钱?”. 作为做过完整网站项目和APP的人,今天从产品经理的角度,一起来算一下中小型APP从无到有需要做哪些工作,以及为达成使命,需要付出多少金钱代价. 以下内容的前提是: 深圳.移动互联网方向.包含研发一个新产品过程中一些常见的工作,并非十全十美. 首先假设在做APP之前我们已经有了一个成熟的团队(这是非常幸运的前提,很多产品研发进度极其缓慢的原因之一就是在过程中不断在招人),团队的结构以架

做一个 App 前需要考虑的几件事

做一个 App 前需要考虑的几件事 来源:limboy的博客 随着工具链的完善,语言的升级以及各种优质教程的涌现,做一个 App 的成本也越来越低了.尽管如此,有些事情最好前期就做起来,避免当 App 有了一定规模后,再感慨当初为什么没有多留点心. 完善的日志系统 以 iOS 为例,有时图方便,就直接用 NSLog 了,甚至线上都一直开着.一方面会影响性能,尤其是输出比较频繁的时候,另一方面也容易泄露敏感信息,所以一般做法是在 Release 模式下禁用 NSLog,比如在 pch 文件中,通过

做一个App前需要考虑的几件事

本文转载于文章原文链接,版本归原作者所有! 随着工具链的完善,语言的升级以及各种优质教程的涌现,做一个 App 的成本也越来越低了.尽管如此,有些事情最好前期就做起来,避免当 App 有了一定规模后,再感慨当初为什么没有多留点心. 此处由标哥的技术博客站长点评: 看完本篇文章之后,也让我想起了不少以前做过的蠢事,做过很多重复的工作.之前在项目中使用过cocoalumberjack,个人感觉是很不错的日志管理框架.当然,不一定要求使用它,也在另一家公司里,原来的人将NSLog重定义了,改写了输出,

如何利用php+android+新浪sae服务器做一个app下载应用

功能简介:提供一个app下载的平台,类似于appstore,上面有很多app可供下载 实现基本思路:利用android,在手机桌面建立一个图标,点击该图标不是打开app应用,而是跳转到一个web页面,这个web页面是部署在新浪sae服务器上面的,apk资源也是存放到新浪sae服                     务器上,本例子使用的web变成语言主要是利用smarty模板php编写的 首先是android页面,就一个简单的url跳转,把跳转到activity换成跳转到web页面,代码如下