markdown 发表文章


markdown 编辑器发表博客





个人主页:http://www.itit123.cn/ 更多干货等你来拿

今天花了点时间完成了发布博客的功能。页面很简陋,效果图如下:




直接上代码(只提供思路,所用框架为Spring + SpringMVC + Spring data jpa + shiro):

首先要一个博客的实体类,一开始没必要太复杂,有基本要素就可以了。
package com.real.blog.entity;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Table;

import lombok.Getter;
import lombok.Setter;

import org.hibernate.validator.constraints.NotBlank;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.real.entity.IdEntity;

@Getter
@Setter
@Entity
@Table(name = "xlblog")
public class Blog extends IdEntity{
	
	@NotBlank
	private String title;
	private String author;
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08:00") 	// 设定JSON序列化时的日期格式
	private Date createdDate;
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08:00") 	// 设定JSON序列化时的日期格式
	private Date updateDate;
	private String content;

}

这里用到了lombok,不懂的可以看一下这个:http://blog.csdn.net/qq_19558705/article/details/50277745

核心处理类controller
package com.real.blog.web;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.gson.Gson;
import com.real.blog.entity.Blog;
import com.real.blog.service.BlogService;
import com.real.service.qiniu.QiniuService;
import com.real.utils.GenerateUtils;

@Controller
@RequestMapping("blog")
public class BlogController{
	
	private static final Logger logger = LoggerFactory.getLogger(BlogController.class);
	
	@Autowired
	private QiniuService qiniuService;
	@Autowired
	private BlogService blogService;
	
	private static final String WEB_PATH = "http://ip:8080";
	
	@RequestMapping("all")
	public String execute(Model model){
		logger.info("blogs : {} " , blogService.findAll(Blog.class));
		model.addAttribute("blogs", blogService.findAll(Blog.class));
		return "blog/index";
	}
	
	@RequestMapping("detail")
	public String detail(){
		return "blog/detail";
	}
	
	@RequestMapping("java")
	public String java(){
		return "blog/java";
	}
	
	/**
	 * 跳转编辑博客页面
	 * 
	 * @param blogId
	 * @return
	 */
	@RequestMapping("edit")
	public String edit(@RequestParam(value="blogId",required=false) String blogId){
		if (null == blogId) {
			
		}
		return "blog/edit";
	}
	
	/**
	 * markdown 上传图片
	 * 
	 */
	@RequestMapping(value = "uploadImage" , method = RequestMethod.POST)
	@ResponseBody
	public String uploadImage(HttpServletRequest request,
			@RequestParam(value = "file" , required=false) MultipartFile file,
			@RequestParam(value = "text" , required=false) String fileName) {
		String realPath = request.getSession().getServletContext().getRealPath("/");
		String resourcePath = "static\\images\\uploadImages\\";
		String result = null;
		if(file!=null){
			if(GenerateUtils.allowUpload(file.getContentType())){
				// 存储本地
                File dir = new File(realPath + resourcePath);
                if(!dir.exists()){
                    dir.mkdirs();
                }
                File saveFile = new File(dir,file.getOriginalFilename());
                try {
					file.transferTo(saveFile);
					String callbackImgUrl = WEB_PATH + request.getSession().getServletContext().getContextPath() + "/" +resourcePath.replaceAll("\\\\","/") + file.getOriginalFilename();
					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.put("message", fileName);
					resultMap.put("url", callbackImgUrl);
					result = new Gson().toJson(resultMap);
				} catch (IllegalStateException e) {
					e.printStackTrace();
					result = "{\"error\":\"upload error\"}";
				} catch (IOException e) {
					e.printStackTrace();
					result = "{\"error\":\"upload error\"}";
				}
			}
		}
		logger.info("result : {} " ,result);
		return result;
	}
	
	/**
	 * 发布博客
	 * 
	 * @param blog
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(value = "update", method = RequestMethod.POST)
    public String updateBlogContent(@RequestParam(value = "blogTitle" , required=true) String blogTitle,
    		@RequestParam(value = "blogContent" , required=true) String blogContent,
    		RedirectAttributes redirectAttributes) {
		Blog blog = new Blog();
		// 完善权限后在弄,即登录的用户才会有权限发表博客
//		blog.setAuthor(SecurityUtils.getSubject().getPrincipal().toString());
		blog.setTitle(blogTitle);
		blog.setContent(blogContent);
		blog.setCreatedDate(new Date());
		try {
			blogService.save(blog);
			redirectAttributes.addFlashAttribute("message", "发布成功!");
		} catch (Exception e) {
			e.printStackTrace();
			// FIXME 有待完善
			redirectAttributes.addFlashAttribute("message", "发布失败,请稍后再试!");
		}
        return "redirect:all";
    }

}

编辑页面:
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<link rel="stylesheet" type="text/css" href="${ctx}/static/markdown/css/bootstrap.css"/>
<h1>编辑页面</h1>
<form id="blogForm" action="${ctx}/blog/update" method="post">
<input type="text" name="blogTitle" autofocus="autofocus" placeholder="请输入标题"><br/><br/>
<textarea id="markdown-textarea" rows="12" class="span7" name="blogContent" ></textarea>
<button>发布</button>
</form>
<script type="text/javascript" src="${ctx}/static/jquery/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="${ctx}/static/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="${ctx}/static/markdown/js/markdown.js"></script>
<script type="text/javascript" src="${ctx}/static/markdown/js/markdown-editor.js"></script>
<script type="text/javascript" src="${ctx}/static/markdown/js/custom.js"></script>
<script type="text/javascript" src="${ctx}/static/jquery-validation/jquery.validate-1.14.0.min.js"></script>

<script>
$().ready(function() {  
	$('#markdown-textarea').markdown();
    $("#blogForm").validate({  
        rules: {  
        	blogTitle: {  
                required: true,  
                minlength: 3  
            },  
        	blogContent: "required"  
        },  
        messages: {  
        	blogTitle: "标题不能为空",
            blogContent: "请填写内容" 
        },
        submitHandler:function(form){
            form.submit();
        }
    });  
}); 
</script>

展示页面:
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />

<script type="text/javascript" src="${ctx}/static/markdown/js/markdown.js"></script>
<script type="text/javascript" src="${ctx}/static/markdown/js/markdown-editor.js"></script>

<c:forEach items="${blogs}" var="blog" varStatus="num">
	<!-- 问题一:不能直接把${blog.content}作为值传给 markdown2html js对特殊字符敏感-->
	<h2 class="blog-title">${blog.title}</h2>
	<p>${blog.createdDate} ${blog.author}</p>
	<input type="hidden" value="${blog.content}" class="blogContent">
	<div class="blog-content"></div>
	<script>
	// 问题二:markdown2html(text) 内容相同 解决方法是给最后一个class添加
	$(".blog-content:last").html(markdown2html($(".blogContent:last").val()));
	</script>
	<a href="${ctx}/blog/detail">查看详细页</a>
	<br/>
</c:forEach>

只做了轮廓,之后在慢慢完善,优化,美观。
遇到的问题也写在代码中了,有什么问题,和建议可以提出来。一起学习一起成长一起装逼。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值