Java Web后端--入职技能任务单(新增插件信息)八
来源:互联网 发布:pla 算法初始化 编辑:程序博客网 时间:2024/04/25 09:04
一、插件新增功能页面jsp的添加
(1)创建一个jsp页面,命名plugin-add.jsp
(2)plugin-add.jsp内容
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet"><script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script><script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script><div style="padding:10px 10px 10px 10px"><form id="pluginAddForm" class="pluginForm" method="post"> <table cellpadding="5"> <tr> <td>用户名:</td> <td><input class="easyui-textbox" type="text" name="userName" data-options="required:true" style="width: 100px;"></input></td> </tr> <tr> <td>插件名称:</td> <td><input class="easyui-textbox" type="text" name="name" data-options="required:true" style="width: 280px;"></input></td> </tr> <tr> <td>插件类型:</td> <td><input class="easyui-textbox" type="text" name="type" data-options="required:true" style="width: 100px;"></input></td> </tr> <tr> <td>插件图标:</td> <td> <a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上传图片</a> <input type="hidden" name="icon"/> </td> </tr> <tr> <td>运行环境:</td> <td><input class="easyui-textbox" type="text" name="pre" data-options="required:true" style="width: 280px;"></input></td> </tr> <tr> <td>关键字:</td> <td><input class="easyui-textbox" type="text" name="keyword" data-options="required:true" style="width: 100px;"></input></td> </tr> <tr> <td>描述:</td> <td> <textarea style="width:800px;height:300px;visibility:hidden;" name="description"></textarea> </td> </tr> <tr> <td><input type="button" onclick="myfile.click();" value="文件地址" ></input></td> <td><input id="file_address" type="text" name="fileAddress" style="width: 280px;"></input></td> <td><input type="file" id="myfile" onchange="file_address.value=this.value" style="display:none"></input></td> </tr> </table></form><div style="padding:5px"> <a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a> <a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()">重置</a></div></div><script type="text/javascript">var pluginAddEditor ;//页面初始化完成后 调用此方法$(function(){//创建富文本编辑器pluginAddEditor = YuKun.createEditor("#pluginAddForm [name=description]");var data = {fun:function(node){YuKun.changeItemParam(node, "pluginAddForm");}};//初始化类目选择和图片上传器YuKun.init(data);});//提交表单 --> pluginAddForm, json数据格式转换function submitForm(){if(!$('#pluginAddForm').form('validate')){$.messager.alert('提示','表单还未填写完成!');return ;}//将编辑器中的内容同步到隐藏多行文本中pluginAddEditor.sync();$.post("/plugin/save",$("#pluginAddForm").serialize(), function(data){if(data.status == 200){$.messager.alert('提示','新增一条插件信息成功!');}if(data.status == 400){$.messager.alert('提示','你输入的用户名不存在,插入记录失败!');}});function clearForm(){$('#pluginAddForm').form('reset');pluginAddEditor.html('');}}</script>
(3)需要注意的几个地方
A.富文本编辑器的引用添加
B.easyUI风格的表单引用
C.表单的name要与数据表Plugin的字段列名对应,后期表单数据【POST参数】序列化成Plugin对象很重要
1.
2.
D.表单数据ajax-post提交
二、运行项目,查看效果
(1)
(2)
(3)我们看下ide中控制台中的输出信息
找不到/plugin-add的http映射请求,说白了,就是Controller没有处理好URI映射
(4)解决办法
A.
B.
IndexPageController.java
package com.appleyk.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;/** * 后台管理首页展示 * @author Appleyk * @date 2017年11月14日12:10:45 */@Controllerpublic class IndexPageController { @RequestMapping("/") public String ShowIndex(){ return "index"; } //添加一个Handler 用来返回XX相关的页面 @RequestMapping("/{page}") public String ShowPage(@PathVariable String page){ return page; }}
三、统一定义【技能任务单后台管理系统】返回数据格式
(1)
(2)DataResult.java【实现序列化】
package com.appleyk.result;import java.io.Serializable;import java.util.List;import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;/** * 技能任务单后台管理自定义响应数据结构 */public class DataResult implements Serializable {private static final long serialVersionUID = 1L;// 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); // 响应业务状态 private Integer status; // 响应消息 private String msg; // 响应中的数据 private Object data; public static DataResult build(Integer status, String msg, Object data) { return new DataResult(status, msg, data); } public static DataResult ok(Object data) { return new DataResult(data); } public static DataResult ok() { return new DataResult(null); } public DataResult() { } public static DataResult build(Integer status, String msg) { return new DataResult(status, msg, null); } public DataResult(Integer status, String msg, Object data) { this.status = status; this.msg = msg; this.data = data; } public DataResult(Object data) { this.status = 200; this.msg = "OK"; this.data = data; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } /** * 将json结果集转化为DataResult对象 * * @param jsonData json数据 * @param clazz DataResult中的object类型 * @return */ public static DataResult formatToPojo(String jsonData, Class<?> clazz) { try { if (clazz == null) { return MAPPER.readValue(jsonData, DataResult.class); } JsonNode jsonNode = MAPPER.readTree(jsonData); JsonNode data = jsonNode.get("data"); Object obj = null; if (clazz != null) { if (data.isObject()) { obj = MAPPER.readValue(data.traverse(), clazz); } else if (data.isTextual()) { obj = MAPPER.readValue(data.asText(), clazz); } } return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj); } catch (Exception e) { return null; } } /** * 没有object对象的转化 * * @param json * @return */ public static DataResult format(String json) { try { return MAPPER.readValue(json, DataResult.class); } catch (Exception e) { e.printStackTrace(); } return null; } /** * Object是集合转化 * * @param jsonData json数据 * @param clazz 集合中的类型 * @return */ public static DataResult formatToList(String jsonData, Class<?> clazz) { try { JsonNode jsonNode = MAPPER.readTree(jsonData); JsonNode data = jsonNode.get("data"); Object obj = null; if (data.isArray() && data.size() > 0) { obj = MAPPER.readValue(data.traverse(), MAPPER.getTypeFactory().constructCollectionType(List.class, clazz)); } return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj); } catch (Exception e) { return null; } }}
(3)关键数据节点说明
四、先实现,图片上传功能【Java客户端+Nginx+FastDFS】
上传的操作请参考我的博文 --> 点击打开链接
(1)启动装有Nginx+FastDFS环境的Linux系统
A.启动Nginx反向代理服务器
B.启动FastDFS的tracker调度器
C.启动FastDFS的storage存储器
D.停掉防火墙服务【避免本地上传图片至Linux系统,出现对应端口号无法访问的问题,索性直接停掉】
E.暂未上传任何图片
稍后,我们会折返回来,验证一下我们上传图片的功能,怎么验证,就是上图中存储图片的目录下面不在等于空白
(2)FastDFS客户端jar包依赖【已依赖】
(3)SpringMVC配置文件中注入多媒体解析器bean【已注入】
(4)添加FastDFS的tracker调度器节点的地址属性配置文件【IP+Port】
A.
B.
(5)配置FastDFS上传成功后的图片访问的http地址头
(6)定义图片上传请求的的响应消息数据格式
A.
B.
PictureResult实体类
package com.appleyk.result;/* 返回格式(JSON)//成功时{ "error" : 0, "url" : "http://www.example.com/path/to/file.ext "}//失败时{ "error" : 1, "message" : "错误信息"} */public class PictureResult {private int error;private String url;private String message;public int getError() {return error;}public void setError(int error) {this.error = error;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}
(7)创建FastDFS客户端上传工具类以及对象转JSON串工具类
A.
B.
C.
FastDFSClient.java
package com.appleyk.utils;import org.csource.common.NameValuePair;import org.csource.fastdfs.ClientGlobal;import org.csource.fastdfs.StorageClient1;import org.csource.fastdfs.StorageServer;import org.csource.fastdfs.TrackerClient;import org.csource.fastdfs.TrackerServer;public class FastDFSClient { private TrackerClient trackerClient = null; private TrackerServer trackerServer = null; private StorageServer storageServer = null; private StorageClient1 storageClient = null; public FastDFSClient(String conf) throws Exception { if (conf.contains("classpath:")) { conf = conf.replace("classpath:", this.getClass().getResource("/").getPath()); } ClientGlobal.init(conf); trackerClient = new TrackerClient(); trackerServer = trackerClient.getConnection(); storageServer = null; storageClient = new StorageClient1(trackerServer, storageServer); } /** * 上传文件方法 * <p>Title: uploadFile</p> * <p>Description: </p> * @param fileName 文件全路径 * @param extName 文件扩展名,不包含(.) * @param metas 文件扩展信息 * @return * @throws Exception */ public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception { String result = storageClient.upload_file1(fileName, extName, metas); return result; } public String uploadFile(String fileName) throws Exception { return uploadFile(fileName, null, null); } public String uploadFile(String fileName, String extName) throws Exception { return uploadFile(fileName, extName, null); } /** * 上传文件方法 * <p>Title: uploadFile</p> * <p>Description: </p> * @param fileContent 文件的内容,字节数组 * @param extName 文件扩展名 * @param metas 文件扩展信息 * @return * @throws Exception */ public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception { String result = storageClient.upload_file1(fileContent, extName, metas); return result; } public String uploadFile(byte[] fileContent) throws Exception { return uploadFile(fileContent, null, null); } public String uploadFile(byte[] fileContent, String extName) throws Exception { return uploadFile(fileContent, extName, null); }}
D.
E.
JsonUtils.java
package com.appleyk.utils;import java.util.List;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.JavaType;import com.fasterxml.jackson.databind.ObjectMapper;/** * JOSN转化工具 */public class JsonUtils { // 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); /** * 将对象转换成json字符串。 * <p>Title: pojoToJson</p> * <p>Description: </p> * @param data * @return */ public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */ public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成pojo对象list * <p>Title: jsonToList</p> * <p>Description: </p> * @param jsonData * @param beanType * @return */ public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List<T> list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); return null; } }}
(8)编写图片上传的Service 接口+实现
A.
<1>
<2>
PictureService.Java
package com.appleyk.service;import org.springframework.web.multipart.MultipartFile;import com.appleyk.result.PictureResult;public interface PictureService { PictureResult uploadPic(MultipartFile picFile);}
<1>
<2>
PictureServiceImpl.java
package com.appleyk.service.Impl;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import com.appleyk.utils.FastDFSClient;import com.appleyk.result.PictureResult;import com.appleyk.service.PictureService;/** * 图片上传Service接口 实现 * @author Appleyk * @Time 2017年12月4日15:30:20 * */@Servicepublic class PictureServiceImpl implements PictureService { //spring容器一启动,就会加载*.properties文件中的信息 //利用@Value注解,拿到属性文件里面的 指定变量的值@Value("${FASTDFS_IMG_HTTP_HEADER}")private String http_url_header;@Overridepublic PictureResult uploadPic(MultipartFile picFile) {PictureResult picResult = new PictureResult();if(picFile.isEmpty()){ //如果等于空,失败 picResult.setError(1); picResult.setMessage("图片为空"); return picResult;}//如果不等于空的话,获得url//获得文件的原始名称String originalFilename = picFile.getOriginalFilename();//截取文件的后缀名 ==> 也就是FastDFS uploadfile方法的第二个参数,不要"."String extName = originalFilename.substring(originalFilename.lastIndexOf(".")+1);try {FastDFSClient fClient = new FastDFSClient("classpath:properties/client.conf"); //如果没问题 直接 upload//返回上传成功后的图片名(准确来说,还需要拼接成http url地址)String url = fClient.uploadFile(picFile.getBytes(), extName);picResult.setError(0);picResult.setUrl(http_url_header+url);} catch (Exception e) {e.printStackTrace();//抛异常 就是FastDFS的tracker server 的配置文件 有问题(IP:Port)picResult.setError(1);picResult.setMessage("FastDFS的tracker server 的配置文件 有问题,图片上传失败!");return picResult;}return picResult;}}
(9)编写图片上传的Controller
A.
B.
C.
PictureUpLoadController.java
package com.appleyk.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;import com.appleyk.result.PictureResult;import com.appleyk.service.PictureService;import com.appleyk.utils.JsonUtils;@Controllerpublic class PictureUpLoadController { //装载PictureService 实例 @Autowired private PictureService picService ; @RequestMapping("/pic/upload") @ResponseBody //解决浏览器不兼容的问题 直接 返回一个json string public String picUpload(MultipartFile uploadFile){ PictureResult picResult = picService.uploadPic(uploadFile); String json = JsonUtils.objectToJson(picResult); System.out.println(json); return json; }}
(10)运行项目,图片上传测试
A.
B.
C.Linux中,在storage存储文件的目录下面验证一下这两张图是否成功了
D.上传成功后,插入图片
E.点击图片,进行大图的地址浏览查看
图片上传功能配置好后,接下来就是实现Plugin的插入Service层接口的创建+业务实现
五、Plugin插件数据操作对应的Service层编写
A.
B.
PluginService.java
package com.appleyk.service;import com.appleyk.pojo.Plugin;import com.appleyk.result.DataResult;public interface PluginService { //向Plugin表添加一条记录 DataResult savePlugin(Plugin plugin,String userName); }
C.
PluginServiceImpl.java
package com.appleyk.service.Impl;import java.util.Date;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.appleyk.mapper.PluginMapper;import com.appleyk.mapper.UsersMapper;import com.appleyk.pojo.Plugin;import com.appleyk.pojo.Users;import com.appleyk.pojo.UsersExample;import com.appleyk.pojo.UsersExample.Criteria;import com.appleyk.result.DataResult;import com.appleyk.service.PluginService;/** * 根据用户名查询插件信息 * @author 余坤 * @date 2017年11月10日:下午5:31:07 */@Servicepublic class PluginServiceImpl implements PluginService {@Autowired private UsersMapper uMapper = null;@Autowiredprivate PluginMapper pMapper = null;@Overridepublic DataResult savePlugin(Plugin plugin,String userName) {//这里要判断一下,用户名对应的Users表里是否存在记录//因为plugin表和users表关联ID == u_id /** 表单提交数据参数 除了第一个外,其他都可看成是一个Plugin对象userNameappleyk111name dddtype dddimage nullpre dddkeyword ddddescription你们不知道的事,是什么呢fileAddressdddd.txt */UsersExample example = new UsersExample();Criteria criteria = example.createCriteria();criteria.andUsernameEqualTo(userName);List<Users> list = uMapper.selectByExample(example);int uID = 0;if(list!=null && list.size()>0){//这里取出对应用户名的 uIduID = list.get(0).getId();}if(uID!=0){ //如果在Users表中查到对应的记录,则向plugin表插入一条记录,记录由jsp页面的表单数据js--post提交 plugin.setuId(uID); plugin.setCreatetime(new Date()); pMapper.insert(plugin); return DataResult.ok();}else{ DataResult dataResult = new DataResult(); dataResult.setStatus(400);//400:表示在Users表中找不到对应的用户信息 return dataResult;}}}
六、编写Plugin对应的Controller控制器
A.
B.
PluginController.java
package com.appleyk.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import com.appleyk.pojo.Plugin;import com.appleyk.result.DataResult;import com.appleyk.service.PluginService;/** * Plugin插件表 Controller * * @author Appleyk * @blob http://blog.csdn.net/appleyk * @date 2017年12月4日16:22:15 */@Controller@RequestMapping("/plugin") // url地址窄化public class PluginController {@Autowiredprivate PluginService pService;@RequestMapping(value = "/save", method = RequestMethod.POST)@ResponseBodypublic DataResult createItem(Plugin plugin, String userName) {DataResult result = pService.savePlugin(plugin, userName);return result;}}
七、Plugin插件信息插入前端测试
A.先测试用户不存在的情况【上述图中显示了当前系统注册的用户有哪些】
(1)
(2)点击提交,发生了什么呢?
B.测试用户存在的情况
(1)
(2)提交表单后,会发生什么呢?
八、Plugin插件信息插入成功后,后台数据库查询验证
由于,Plugin插件信息的查询列表展示我们本篇还没涉及到,放到以后再加,因此,新增了一条插件信息后,我们只能手动的去数据库进行查询:
本篇完。
- Java Web后端--入职技能任务单(新增插件信息)八
- Java Web后端--入职技能任务单(要求说明)☞置顶
- Java Web后端--入职技能任务单(Maven父工程创建)一
- Java Web后端--入职技能任务单(Maven子工程创建)二
- Java Web后端--入职技能任务单(SSM框架搭建)三
- Java Web后端--入职技能任务单(Mysql5.7安装和数据准备)四
- Java Web后端--入职技能任务单(Mybatis逆向工程--数据关系映射)五
- Java Web后端--入职技能任务单(前端首页布局和展示)七
- Java Web后端--入职技能任务单(plugin表的dao层增删改查)六
- java web后端基本搭建
- java web后端学习思路
- Java Web学习笔记(八)hibernate
- Java web登入界面
- Java 并发编程之任务取消(八)
- 新增加一项技能
- JS分页处理(web前端+后端JAVA)
- [Java Web]后端接口版本控制
- Java WEb后端WebSocket的Tomcat实现
- 基于神经网络的实体识别和关系抽取联合学习 | PaperWeekly #54
- 基于Java的卡诺图化简
- SQL:DML&DDL
- 解决SwipeRefreshLayout下拉刷新与SwipeMenuListView的冲突
- 间断初值双曲守恒问题的Lax-Friedrichs和后向欧拉数值解法
- Java Web后端--入职技能任务单(新增插件信息)八
- Vue项目启动时报 Error: spawn EACCES
- 1.SC命令——图形缩放
- 算法分析---回文数判断
- qnx efs文件系统binary修复
- Linux centos7环境下MySQL安装教程
- Linux指令用之记之-shell双引号单引号区别
- hadoop2.8.0 安装与环境搭建
- IMX.6Q 移植FFmpeg libx264软件编码 libmp3lame