尝试用kotlin做一个app(五)
JSP后台管理系统
开发工具是IntelliJ IDEA+tomcat+mysql5.6.19+mysql-connector-java-5.1.48.jar+easyui+kindeditor
之前也有记录一些Servlet基础(java,idea)
这篇我只把一些重要的记录一下
easyui很简单,而且中文文档介绍得很详细,对照文档做就好了
kindeditor问题比较多,这里记录一下
准备工作
mysql数据库test中建立t_hp_new表

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">
- <input type="file" id="thumb" name="thumb"/>
点击提交,发现浏览器上传这样一段数据(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"
备注:
MIME媒体类型,是描述报文实体主体内容的一些保准化名称(如,text/html,image/jpeg)
request.getContentType函数
java.lang.String getContentType()
Returns the MIME type of the body of the request, or null if the type is not known. For HTTP servlets, same as the value of the CGI variable CONTENT_TYPE.
Returns:
a String containing the name of the MIME type of the request, or null if the type is not known
这里返回的是multipart/form-data; boundary=----WebKitFormBoundarye0S1O6ob5tGT8sqx
接下来就有点傻了,我们要在字符串里,截取文件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/1Qu-OYX_ppqEBYmWvRk11aw
提取码:u1ht
补充:
·中文乱码解决
String orginStr = new String(orginData,"utf-8");
但是这样强制编码,图片就会出错!!!!!!!!!!!!
所以要设置getBytes("utf-8")。这样弄了之后如果是图片上传不完整,那就在判断读取的行s是普通form域之后,把s转成utf-8吧
·editor里面的内容也是多行,所以要加个判断
- if(name.equals("editor")){
- for(;;) {
- value += s;
- reader.mark(1);
- s=reader.readLine();
- if(s.equals(boundary)) {
- reader.reset();
- break;
- }
- }
- }else value = s;
·
尝试用kotlin做一个app(五)的更多相关文章
- 尝试用kotlin做一个app(写在前面)
学kotlin的目的好像就是做一个app,不一定有什么想做的项目,只是单纯想掌握这一门技术,确切地说只是单纯想学会做app.对于概念的东西,我也没兴趣深究,用得到的学一下,用不到的,就算了.我也不知道 ...
- 尝试用kotlin做一个app(二)
导航条 我想实现的效果是这样的 类似于ViewPager的效果,子类导航页面可以滑动,当滑动某个子类导航页面,导航线会平滑地向父类导航移动 ·添加布局 <!--导航分类:编程语言/技术文档/源码 ...
- 尝试用kotlin做一个app(三)
新闻列表 添加新闻列表可以使用RecyclerView.但是有个问题,RecyclerView只会在内部滚动,不会带动整个屏幕滚动.所以在原根布局外层添加androidx.core.widget.Ne ...
- 尝试用kotlin做一个app(一)
1.先添加一下anko库 依赖:implementation "org.jetbrains.anko:anko:$anko_version" 版本:ext.anko_version ...
- 尝试用kotlin做一个app(四)
本来是应该为主页加载数据库数据了,但是想着做后台,之前写jsp后台写吐了,所以先拖几天.把之前的代码完善一下,或者添加些新内容. ...... 多个fragment切换卡顿 首先修正一个bug.从主页 ...
- 创业成本?亲身经历告诉你做一个app要多少钱
导语:作为一名苦逼的移动互联网创业者,被外行的朋友们问及最多的问题是“做一个网站需要多少钱?”或者“做一个APP需要多少钱?” 作为一名苦逼的移动互联网创业者,被外行的朋友们问及最多的问题是“做一个网 ...
- 做一个 App 前需要考虑的几件事
做一个 App 前需要考虑的几件事 来源:limboy的博客 随着工具链的完善,语言的升级以及各种优质教程的涌现,做一个 App 的成本也越来越低了.尽管如此,有些事情最好前期就做起来,避免当 ...
- 做一个App前需要考虑的几件事
本文转载于文章原文链接,版本归原作者所有! 随着工具链的完善,语言的升级以及各种优质教程的涌现,做一个 App 的成本也越来越低了.尽管如此,有些事情最好前期就做起来,避免当 App 有了一定规模后, ...
- 涨姿势:创业做一个App需要花多少钱(8个人,6个月,就要100万,附笔记心得)
(原标题:涨姿势:创业做一个App要花多少钱?) 作为互联网从业者,被外行的朋友们问及最多的问题是,“做一个网站需要多少钱?”或者“做一个APP需要多少钱?”. 作为做过完整网站项目和APP的人,今天 ...
随机推荐
- list中会直接绑定HashMap中的数据
import java.util.ArrayList;import java.util.HashMap;import java.util.List; public class HashMapSync ...
- 条形码识别手持终端(PDA)人们每日触碰的科技
时尚达人的你,收快递物流时,毫无疑问在有时会好奇心,派送员腰部取出的那把“扫枪”,轻轻地一扫后,给你打开享有开拆快递物流的开心時刻.老湿机的你,是否会突然发觉,泊车交费时收费员哥哥已不找你许多零钱,只 ...
- 工作中一些常用的linux命令
问题一: 绝对路径用什么符号表示?当前目录.上层目录用什么表示?主目录用什么表示? 切换目录用什么命令? 答案:绝对路径:如/etc/init.d当前目录和上层目录:./ ../主目录:~/切换目录 ...
- 修改了ssh默认端口对git的影响
如果服务端的ssh不是采用的默认端口. 那么客户端git命令就会报错: ssh: connect to host 192.168.2.152 port 22: Connection refused 这 ...
- Visual c++6.0如何创建工程项目
首先,打开电脑里安装的visual C++ 6.0 ,进入其选择的主界面,如果兼容性不对,先调整一下电脑与软件的兼容性. 进入主界面之后,点击左上角的文件,然后点击新建,可以创建新的文件. 打开后弹出 ...
- S3C2440内存控制器详解
S3C2440A Memory Map after Reset S3C2440的内存空间划分为不同的块,当CPU向内存控制器发出地址,内存控制器根据地址范围,发出对应片选信号到片选引脚,实现对不同设备 ...
- hdu 1874 畅通工程续(SPFA模板)
畅通工程续 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 收藏了一篇很有用的博客 “npm的安装教程”
暂时贴上这一篇博客的地址,感谢原作者 https://www.cnblogs.com/goldlong/p/8027997.html 使用之前,我们先来掌握3个东西是用来干什么的. npm: Node ...
- Java的SpringMVC执行流程
SpringMVC找Controller流程 1.扫描整个项目(Spring已经做了)定义一个Map集合. 2.拿到所有加了@Controller注解的类. 3.遍历类里面的所有方法对象. 4.判断方 ...
- vscode spring boot配置文件application.properties不提示解决方式
背景 因实际的编程环境是jdk1.6,vscode安装了spring boot tools开发后,application.properties无法提示.spring boot tools的功能之一就是 ...