Java Web后端--入职技能任务单(新增插件信息)八

一、插件新增功能页面jsp的添加


(1)创建一个jsp页面,命名plugin-add.jsp


Java Web后端--入职技能任务单(新增插件信息)八_第1张图片


(2)plugin-add.jsp内容


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>



用户名:
插件名称:
插件类型:
插件图标: 上传图片
运行环境:
关键字:
描述:

(3)需要注意的几个地方


A.富文本编辑器的引用添加




B.easyUI风格的表单引用


Java Web后端--入职技能任务单(新增插件信息)八_第2张图片



C.表单的name要与数据表Plugin的字段列名对应,后期表单数据【POST参数】序列化成Plugin对象很重要


1.


Java Web后端--入职技能任务单(新增插件信息)八_第3张图片


2.


Java Web后端--入职技能任务单(新增插件信息)八_第4张图片



D.表单数据ajax-post提交


Java Web后端--入职技能任务单(新增插件信息)八_第5张图片




二、运行项目,查看效果


(1)


Java Web后端--入职技能任务单(新增插件信息)八_第6张图片


(2)


Java Web后端--入职技能任务单(新增插件信息)八_第7张图片


(3)我们看下ide中控制台中的输出信息




找不到/plugin-add的http映射请求,说白了,就是Controller没有处理好URI映射


(4)解决办法


A.

Java Web后端--入职技能任务单(新增插件信息)八_第8张图片




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
 */
@Controller
public class IndexPageController {
  @RequestMapping("/")
  public String ShowIndex(){
	  return "index";
  } 
  
  //添加一个Handler 用来返回XX相关的页面
  @RequestMapping("/{page}")
  public String ShowPage(@PathVariable String page){
	  return page;
  }
}


C.运行项目后,再次刷新页面,就可以看到效果了


Java Web后端--入职技能任务单(新增插件信息)八_第9张图片



三、统一定义【技能任务单后台管理系统返回数据格式


(1)


Java Web后端--入职技能任务单(新增插件信息)八_第10张图片


(2)DataResult.java【实现序列化】


Java Web后端--入职技能任务单(新增插件信息)八_第11张图片


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 Web后端--入职技能任务单(新增插件信息)八_第12张图片



四、先实现,图片上传功能【Java客户端+Nginx+FastDFS】


上传的操作请参考我的博文 --> 点击打开链接


(1)启动装有Nginx+FastDFS环境的Linux系统


A.启动Nginx反向代理服务器


Java Web后端--入职技能任务单(新增插件信息)八_第13张图片


B.启动FastDFS的tracker调度器




C.启动FastDFS的storage存储器




D.停掉防火墙服务【避免本地上传图片至Linux系统,出现对应端口号无法访问的问题,索性直接停掉】




E.暂未上传任何图片


Java Web后端--入职技能任务单(新增插件信息)八_第14张图片


稍后,我们会折返回来,验证一下我们上传图片的功能,怎么验证,就是上图中存储图片的目录下面不在等于空白


(2)FastDFS客户端jar包依赖【已依赖】


Java Web后端--入职技能任务单(新增插件信息)八_第15张图片


(3)SpringMVC配置文件中注入多媒体解析器bean【已注入】





(4)添加FastDFS的tracker调度器节点的地址属性配置文件【IP+Port】


A.


Java Web后端--入职技能任务单(新增插件信息)八_第16张图片



B.


Java Web后端--入职技能任务单(新增插件信息)八_第17张图片



(5)配置FastDFS上传成功后的图片访问的http地址头


Java Web后端--入职技能任务单(新增插件信息)八_第18张图片


(6)定义图片上传请求的的响应消息数据格式


A.


Java Web后端--入职技能任务单(新增插件信息)八_第19张图片



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.


Java Web后端--入职技能任务单(新增插件信息)八_第20张图片

B.


Java Web后端--入职技能任务单(新增插件信息)八_第21张图片


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);
    }

    /**
     * 上传文件方法
     * 

Title: uploadFile

*

Description:

* @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); } /** * 上传文件方法 *

Title: uploadFile

*

Description:

* @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.


Java Web后端--入职技能任务单(新增插件信息)八_第22张图片




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字符串。
     * 

Title: pojoToJson

*

Description:

* @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 jsonToPojo(String jsonData, Class beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成pojo对象list *

Title: jsonToList

*

Description:

* @param jsonData * @param beanType * @return */ public static List jsonToList(String jsonData, Class beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); return null; } } }



(8)编写图片上传的Service 接口+实现


A.


<1>


Java Web后端--入职技能任务单(新增插件信息)八_第23张图片



<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);
}



B.接口实现


<1>

Java Web后端--入职技能任务单(新增插件信息)八_第24张图片


<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
 *
 */

@Service
public class PictureServiceImpl implements PictureService {

    //spring容器一启动,就会加载*.properties文件中的信息
    //利用@Value注解,拿到属性文件里面的 指定变量的值
	@Value("${FASTDFS_IMG_HTTP_HEADER}")
	private String http_url_header;
	
	
	@Override
	public 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.


Java Web后端--入职技能任务单(新增插件信息)八_第25张图片


B.


Java Web后端--入职技能任务单(新增插件信息)八_第26张图片



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;

@Controller
public 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.


Java Web后端--入职技能任务单(新增插件信息)八_第27张图片


B.


Java Web后端--入职技能任务单(新增插件信息)八_第28张图片


C.Linux中,在storage存储文件的目录下面验证一下这两张图是否成功了


Java Web后端--入职技能任务单(新增插件信息)八_第29张图片


D.上传成功后,插入图片


Java Web后端--入职技能任务单(新增插件信息)八_第30张图片



Java Web后端--入职技能任务单(新增插件信息)八_第31张图片


E.点击图片,进行大图的地址浏览查看


Java Web后端--入职技能任务单(新增插件信息)八_第32张图片


图片上传功能配置好后,接下来就是实现Plugin的插入Service层接口的创建+业务实现


五、Plugin插件数据操作对应的Service层编写



A.


Java Web后端--入职技能任务单(新增插件信息)八_第33张图片


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
 */
@Service
public class PluginServiceImpl implements PluginService {

	@Autowired 
	private UsersMapper  uMapper = null;
	@Autowired
	private PluginMapper pMapper = null;
	
	@Override
	public DataResult savePlugin(Plugin plugin,String userName) {
		
	//这里要判断一下,用户名对应的Users表里是否存在记录
	//因为plugin表和users表关联ID == u_id
    
	/** 表单提交数据参数 除了第一个外,其他都可看成是一个Plugin对象
	userName	appleyk111
	name	    ddd
	type	    ddd
	image	    null
	pre	        ddd
	keyword	    ddd
	description	你们不知道的事,是什么呢
	fileAddress	dddd.txt		
	 */
	UsersExample example = new UsersExample();
	Criteria criteria = example.createCriteria();
	criteria.andUsernameEqualTo(userName);
	List list = uMapper.selectByExample(example);
	int uID = 0;
	if(list!=null && list.size()>0){
		//这里取出对应用户名的  uId
		uID = 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.


Java Web后端--入职技能任务单(新增插件信息)八_第34张图片



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 {

	@Autowired
	private PluginService pService;


	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ResponseBody
	public DataResult createItem(Plugin plugin, String userName) {
		DataResult result = pService.savePlugin(plugin, userName);
		return result;
	}

	
}

七、Plugin插件信息插入前端测试



Java Web后端--入职技能任务单(新增插件信息)八_第35张图片


A.先测试用户不存在的情况【上述图中显示了当前系统注册的用户有哪些】


(1)

Java Web后端--入职技能任务单(新增插件信息)八_第36张图片



(2)点击提交,发生了什么呢?


Java Web后端--入职技能任务单(新增插件信息)八_第37张图片



B.测试用户存在的情况


(1)


Java Web后端--入职技能任务单(新增插件信息)八_第38张图片



(2)提交表单后,会发生什么呢?


Java Web后端--入职技能任务单(新增插件信息)八_第39张图片





八、Plugin插件信息插入成功后,后台数据库查询验证


由于,Plugin插件信息的查询列表展示我们本篇还没涉及到,放到以后再加,因此,新增了一条插件信息后,我们只能手动的去数据库进行查询:


Java Web后端--入职技能任务单(新增插件信息)八_第40张图片




本篇完。

你可能感兴趣的:(插件,用户,文件管理系统(入职技能任务))