ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端首页的开发

    前面介绍完了util包的各种工具类、service层、model层以及dao层的实现,可以说是分享了一大半了!可能有些博友对于其中的code的作用不是很知晓,但是我相信随着我controller以及页面的开发分享,我想,你会逐渐知晓前面介绍的作用的。特别是比较实用的各种工具类:比如日期处理、加密解密、web文件如图片等的处理、文件下载等等、分页工具类、异步或者同步response工具类等等。

    本篇博文将介绍介绍前端页面的开发。主要有首页的列表展示、首页分页与分类查询、首页数据的全文检索查询、博客详情、博客评论以及源代码或者叫文件下载

    1、首页请求/index可以得到首页,请求/downloadFile可以得到本博客系统的源码压缩包,控制器代码IndexController.java,其中首页博客列表展示时采用了缩略图的形式:这里面采用的技术是jsoup,去检索出博客内容中前三张图片,进行展示

package com.steadyjack.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.steadyjack.entity.Blog;
import com.steadyjack.entity.PageBean;
import com.steadyjack.service.BlogService;
import com.steadyjack.util.PageUtil;
import com.steadyjack.util.StringUtil;
import com.steadyjack.util.WebFileUtil;

/**
 * title:IndexController.java
 * description:前端主页Controller
 * time:2017年1月21日 下午10:28:50
 * author:debug-steadyjack
 */
@Controller
public class IndexController {

	@Resource
	private BlogService blogService;
	
	@RequestMapping("/")
	public String defaultPage(){
		return "redirect:/index";
	}
	
	/**
	 * title:IndexController.java
	 * description:请求主页
	 * time:2017年1月21日 下午10:30:17
	 * author:debug-steadyjack
	 * @param page
	 * @param typeId
	 * @param releaseDateStr
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/index")
	public ModelAndView index(@RequestParam(value="page",required=false)String page,
			@RequestParam(value="typeId",required=false)String typeId,
			@RequestParam(value="releaseDateStr",required=false)String releaseDateStr,
			HttpServletRequest request)throws Exception{
		
		ModelAndView mav=new ModelAndView();
		if(StringUtil.isEmpty(page)){
			page="1";
		}
		Integer pageNo=Integer.parseInt(page);
		
		PageBean pageBean=new PageBean(pageNo,10);
		Map map=new HashMap();
		map.put("start", pageBean.getStart());
		map.put("size", pageBean.getPageSize());
		map.put("typeId", typeId);
		map.put("releaseDateStr", releaseDateStr);
		List blogList=blogService.list(map);
		
		for(Blog blog:blogList){
			//用于存放博客内容里面的图片,从而生成缩略图-用于前端页面展示
			List imagesList=blog.getImagesList();
			
			String blogInfo=blog.getContent();
			Document doc=Jsoup.parse(blogInfo);
			
			//查找扩展名是jpg的图片:根据页面需要拿n张图片,这里拿了3张
			Elements jpgs=doc.select("img[src$=.jpg]"); 
			if (jpgs!=null && jpgs.size()>0) {
				for(int i=0;i
    其实,这个控制器controller就已经展示了springmvc的角色,彻底对springmvc的工作原理进行淋漓尽致的应用。看过springmvc的宏观工作原理的博友都知道,springmvc的工作原理大概是这样的:

1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.

2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。

3、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。

4、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。

5、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。

6、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端

   看完之后,是不是觉得我的那个controller确实表示的淋漓尽致。只不过,现在自己写的时候,可以对上面的写法进行诸多优化,而且随着spring4.3还是4.2起对于controller的写法更加简洁了。

   比如对于请求参数的写法,可以用参数封装(当然啦,这个可能不是spring4.x的功能),controller返回的一般是String,即一个视图的地址等等。

   对于springmvc的详细介绍可以另外看多几篇博客。

   2、完了之后,介绍一下博客详情、博客的全文检索模糊查询(这里采用lucene实现)以及博客的分页(在这里采用 同步刷新)logController.java以及评论控制器CommentController.java:

package com.steadyjack.controller;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.steadyjack.entity.Blog;
import com.steadyjack.lucene.BlogIndex;
import com.steadyjack.service.BlogService;
import com.steadyjack.service.CommentService;
import com.steadyjack.util.StringUtil;

/**
 * title:BlogController.java
 * description:前端博客Controller层
 * time:2017年1月17日 下午9:44:19
 * author:debug-steadyjack
 */
@Controller
@RequestMapping("/blog")
public class BlogController {

	@Resource
	private BlogService blogService;
	
	@Resource
	private CommentService commentService;
	
	// 博客索引
	private BlogIndex blogIndex=new BlogIndex();
	
	
	/**
	 * title:BlogController.java
	 * description:博客详细信息
	 * time:2017年1月17日 下午9:51:50
	 * author:debug-steadyjack
	 * @param id
	 * @param request
	 * @throws Exception
	 */
	@RequestMapping("/articles/{id}")
	public ModelAndView details(@PathVariable Integer id,HttpServletRequest request)throws Exception{
		ModelAndView modelAndView=new ModelAndView();
		
		Blog blog=blogService.findById(id);
		String keyWords=blog.getKeyWord();
		
		if(StringUtil.isNotEmpty(keyWords)){
			String arr[]=keyWords.split(" ");
			modelAndView.addObject("keyWords",StringUtil.filterWhite(Arrays.asList(arr)));			
		}else{
			modelAndView.addObject("keyWords",null);			
		}
		
		modelAndView.addObject("blog", blog);
		
		Integer clickHit=blog.getClickHit();
		clickHit = clickHit==null?0:clickHit+1;
		//博客点击次数加1
		blog.setClickHit(clickHit); 
		blogService.update(blog);
		
		Map map=new HashMap();
		//查询审核通过的评论
		map.put("blogId", blog.getId());
		map.put("state", 1);
		
		//System.out.println(request.getServletContext().getContextPath());
		
		modelAndView.addObject("commentList", commentService.list(map)); 
		modelAndView.addObject("pageCode", this.genUpAndDownPageCode(blogService.getLastBlog(id),blogService.getNextBlog(id),request.getServletContext().getContextPath()));
		modelAndView.addObject("mainPage", "foreground/blog/view.jsp");
		modelAndView.addObject("pageTitle",blog.getTitle());
		modelAndView.setViewName("mainTemp");
		
		//查询审核通过的评论
		return modelAndView;
	}
	
	/**
	 * title:BlogController.java
	 * description:根据查询信息查询相关博客信息
	 * time:2017年1月17日 下午11:11:29
	 * author:debug-steadyjack
	 * @param q
	 * @param page
	 * @param request
	 * @return ModelAndView
	 * @throws Exception
	 */
	@RequestMapping("/q")
	public ModelAndView search(@RequestParam(value="q",required=false)String q,@RequestParam(value="page",required=false)String page,HttpServletRequest request)throws Exception{
		if(StringUtil.isEmpty(page)){
			page="1";
		}
		ModelAndView mav=new ModelAndView();
		
		mav.addObject("mainPage", "foreground/blog/result.jsp");
		
		blogIndex.setRequest(request);
		List blogList=blogIndex.searchBlog(q.trim());
		Integer pageNo=Integer.parseInt(page);
		Integer pageSize=10;
		Integer toIndex=blogList.size()>=pageNo*pageSize?pageNo*pageSize:blogList.size();
		
		//list的subList是分页的一种:返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图
		mav.addObject("blogList",blogList.subList((pageNo-1)*pageSize, toIndex));
		mav.addObject("pageCode",this.genUpAndDownPageCode(pageNo, blogList.size(), q,10,request.getServletContext().getContextPath()));
		mav.addObject("q",q);
		mav.addObject("resultTotal",blogList.size());
		mav.addObject("pageTitle","搜索关键字'"+q+"'结果页面_Java修炼之博客系统");
		mav.setViewName("mainTemp");
		
		return mav;
	}
	
	/**
	 * title:BlogController.java
	 * description: 获取下一篇博客和下一篇博客
	 * time:2017年1月17日 下午10:14:03
	 * author:debug-steadyjack
	 * @param lastBlog
	 * @param nextBlog
	 * @param projectContext
	 * @return String
	 */
	private String genUpAndDownPageCode(Blog lastBlog,Blog nextBlog,String projectContext){
		StringBuffer pageCode=new StringBuffer();
		if(lastBlog==null || lastBlog.getId()==null){
			pageCode.append("

上一篇:没有了

"); }else{ pageCode.append("

上一篇:"+lastBlog.getTitle()+"

"); } if(nextBlog==null || nextBlog.getId()==null){ pageCode.append("

下一篇:没有了

"); }else{ pageCode.append("

下一篇:"+nextBlog.getTitle()+"

"); } return pageCode.toString(); } /** * 获取上一页,下一页代码 查询博客用到(简单的分页) * @param page 当前页 * @param totalNum 总记录数 * @param q 查询关键字 * @param pageSize 每页大小 * @param projectContext * @return */ private String genUpAndDownPageCode(Integer page,Integer totalNum,String q,Integer pageSize,String projectContext){ long totalPage=totalNum%pageSize==0?totalNum/pageSize:totalNum/pageSize+1; StringBuffer pageCode=new StringBuffer(); if(totalPage==0){ return ""; }else{ pageCode.append(""); } return pageCode.toString(); } }

    对于评论控制器,在这里比较简单,只是用于游客进行ip评论(前期没做用户那一块的管理,有兴趣的博友可以自己搞一套!)CommentController.java:

package com.steadyjack.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.steadyjack.entity.Blog;
import com.steadyjack.entity.Comment;
import com.steadyjack.service.BlogService;
import com.steadyjack.service.CommentService;
import com.steadyjack.util.ResponseUtil;

/**
 * 评论Controller层
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/comment")
public class CommentController {
	
	@Resource
	private CommentService commentService;
	
	@Resource
	private BlogService blogService;
	
	/**
	 * title:CommentController.java
	 * description:添加或者修改评论
	 * time:2017年1月23日 下午8:02:05
	 * author:debug-steadyjack
	 * @param comment
	 * @param imageCode
	 * @param request
	 * @param response
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/save")
	public String save(Comment comment,@RequestParam("imageCode") String imageCode,
			HttpServletRequest request,HttpServletResponse response,HttpSession session)throws Exception{
		//获取系统生成的验证码
		String sRand=(String) session.getAttribute("sRand");
		
		JSONObject result=new JSONObject();
		
		//操作的记录条数
		int resultTotal=0; 
		if(!imageCode.equals(sRand)){
			result.put("success", false);
			result.put("errorInfo", "验证码填写错误!");
		}else{
			//获取用户IP
			String userIp=request.getRemoteAddr(); 
			comment.setUserIp(userIp);
			if(comment.getId()==null){
				resultTotal=commentService.add(comment);
				//该博客的回复次数加1
				Blog blog=blogService.findById(comment.getBlog().getId());
				blog.setReplyHit(blog.getReplyHit()+1);
				blogService.update(blog);
			}else{
				
			}
			if(resultTotal>0){
				result.put("success", true);
			}else{
				result.put("success", false);
			}
		}
		ResponseUtil.write(response, result);
		return null;
	}

}

    最后一个介绍一下“关于博主”/aboutMe请求以及博主登录/login进行认证,通过之后进入后台BloggerController.java:

package com.steadyjack.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.steadyjack.entity.Blogger;
import com.steadyjack.service.BloggerService;
import com.steadyjack.util.CryptographyUtil;

/**
 * title:BloggerController.java
 * description:博主Controller层
 * time:2017年1月23日 下午10:01:10
 * author:debug-steadyjack
 */
@Controller
@RequestMapping("/blogger")
public class BloggerController {

	@Resource
	private BloggerService bloggerService;
	
	/**
	 * title:BloggerController.java
	 * description:用户登录
	 * time:2017年1月23日 下午10:01:20
	 * author:debug-steadyjack
	 * @param blogger
	 * @param request
	 * @return
	 */
	@RequestMapping("/login")
	public String login(Blogger blogger,HttpServletRequest request){
		Subject subject=SecurityUtils.getSubject();
		UsernamePasswordToken token=new UsernamePasswordToken(blogger.getUserName(), CryptographyUtil.md5(blogger.getPassword(), "debug"));
		try{
			//登录验证
			subject.login(token); 
			return "redirect:/admin/main.jsp";
		}catch(Exception e){
			e.printStackTrace();
			request.setAttribute("blogger", blogger);
			request.setAttribute("errorInfo", "用户名或密码错误!");
			return "login";
		}
	}
	
	/**
	 * title:BloggerController.java
	 * description:查找博主信息
	 * time:2017年1月23日 下午10:12:45
	 * author:debug-steadyjack
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/aboutMe")
	public ModelAndView aboutMe()throws Exception{
		ModelAndView mav=new ModelAndView();
		
		mav.addObject("blogger",bloggerService.find());
		mav.addObject("mainPage", "foreground/blogger/info.jsp");
		mav.addObject("pageTitle","关于博主_Java开源博客系统");
		mav.setViewName("mainTemp");
		
		return mav;
	}
}

    认证的过程走的是shiro框架的提供MyRealm.java(这在前面已经讲过了):

package com.steadyjack.realm;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.steadyjack.entity.Blogger;
import com.steadyjack.service.BloggerService;

/**
 * title:MyRealm.java
 * description:自定义Realm(域)
 * time:2017年1月22日 下午10:50:57
 * author:debug-steadyjack
 */
public class MyRealm extends AuthorizingRealm{

	@Resource
	private BloggerService bloggerService;
	
	/**
	 * 为当限前登录的用户授予角色和权
	 * (由于目前系统没有啥资源且只有admin超级用户,故而没写授予角色、权限(资源)逻辑)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		return null;
	}

	/**
	 * 验证当前登录的用户
	 * (成功时,将登陆用户绑定到会话中;失败时,其实会报各种exception,理当抛出用于前端页面展示(后期实现))
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//获取身份(在这里指 用户名)-凭证(在这里指 密码)
		String userName=(String)token.getPrincipal();
		Blogger blogger=bloggerService.getByUserName(userName);
		if(blogger!=null){
			//当前用户信息存到session中
			SecurityUtils.getSubject().getSession().setAttribute("currentUser", blogger); 
			AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(blogger.getUserName(),blogger.getPassword(),getName());
			return authcInfo;
		}else{
			return null;				
		}
	}

}

    最后是贴出效果:

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第1张图片


ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第2张图片

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第3张图片


ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第4张图片

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第5张图片

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第6张图片


     最后,把WebContent下的页面分享出来:前端用的是bootstrap,后端页面用的是easyui,目录如图:

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发_第7张图片

    页面以及样式来这里下载:

     如果有相关问题:如想找我付费开发其他功能,讨论其中相关问题等等,可以来以下两群找我,我叫debug!

     Java开源技术交流:583522159     鏖战八方群:391619659

你可能感兴趣的:(第三方框架实战,ssh,ssm整合案例)