这里使用SpringMVC + Hibernate实现功能的开发。
先建立项目,并加入这两个支持,注意,加入Spring时需要多选择一个支持包Spring web Flow 2.0 core。
多加入一个Spring Web Flow 2.0支持包。
由于使用SpringMVC开发时,必须使用Annotation配置,因此还要加入以下的配置到spring配置文件中:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> |
配置允许使用Annotation和Annotation的范围。
<context:annotation-config></context:annotation-config> <context:component-scan base-package="org.liky.mvc.dao.impl,org.liky.mvc.service.impl,org.liky.mvc.action"></context:component-scan> <mvc:annotation-driven/> |
同时,在web.xml中加入针对SPringMVC的配置支持。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext-*.xml</param-value> </context-param>
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext-*.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> |
启动服务器,查看是否有问题。
项目环境没有问题后,开始编写数据库操作,这里先把后台的登陆方法实现,也使用Spring + Hibernate,因此后台代码直接实现即可。
开始完成登陆表单,注意,使用SpringMVC最好使用其提供的表单标签,而不要使用html默认的表单。
<center> <form:form action="user_login.action" method="post" commandName="user"> 用户名: <form:input path="userid"/> <br/> 密码: <form:password path="password"/> <br/> <input type="submit" value="登陆"/> </form:form> </center> |
建立一个Action,完成登陆验证功能,这个Action不需要继承任何类。
@Controller // 如果映射的路径为 / , 可以不写这个路径配置 // @RequestMapping(value="/") public class UserAction {
private ITUserService service;
@RequestMapping(value = "user_login") public ModelAndView login(TUser user, HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView();
boolean flag = service.login(user);
if (flag) { // 将用户信息保存到session范围 request.getSession().setAttribute("user", user);
mv.setViewName("/pages/suc.jsp"); } else { // 等同于request.setAttribute() mv.addObject("message", "用户名或密码错误,请重新输入!"); mv.setViewName("/index.jsp"); }
return mv; } |
编写suc.jsp和index.jsp的提示功能。
测试时会提示找不到user对象的错误,这是因为SpringMVC在进入表单前必须准备一个空白的对象以便回填数据。
因此这里编写一个loginPre操作,来作为进入表单前的预处理。
@RequestMapping(value = "user_loginPre") public ModelAndView loginPre() { ModelAndView mv = new ModelAndView("/index.jsp"); mv.addObject("user", new TUser()); return mv; } |
2、SpingMVC实现新闻管理功能
后台的数据库操作直接复制到这个项目中,继续使用原有的代码。
在登陆成功页中加入超连接。
<a href="pages/news_insertPre.action">添加新闻</a> <br/> <a href="pages/news_list.action">新闻列表</a> <br/> |
完成Action中的insertPre操作:
@Controller @RequestMapping(value = "/pages") public class NewsAction {
private INewsService service;
@RequestMapping(value = "news_insertPre") public ModelAndView insertPre() throws Exception { ModelAndView mv = new ModelAndView("/pages/news/news_insert.jsp");
List<NewsType> allType = service.insertPre();
mv.addObject("allType", allType); mv.addObject("news", new News());
return mv; } |
编写insert.jsp页面。
<center> <form:form action="pages/news_insert.action" method="post" commandName="news"> 新闻标题: <form:input path="title"/> <br/> 新闻内容: <form:textarea path="content"/> <br/> 新闻发布日期: <form:input path="pubDate"/> <br/> 新闻分类: <form:select path="newsType.tid"> <form:options items="${allType}" itemValue="tid" itemLabel="tname"/> </form:select> <br/> <input type="submit" value="提交"/> </form:form> </center> |
完成Action中的添加功能
@RequestMapping(value = "news_insert") public ModelAndView insert(News news) throws Exception { ModelAndView mv = new ModelAndView("/forward.jsp");
service.insert(news);
mv.addObject("message", "发布成功"); mv.addObject("url", "pages/suc.jsp");
return mv; } |
测试时会发现,日期类型无法自动转型,必须手工进行类型转换。
因此在News的pojo类中单独声明一个pubDateStr的String类型属性。
同时,页面表单也要改为提交到news中的pubDateStr里。
最后,在Action中进行自己手工的日期格式转换。
@RequestMapping(value = "news_insert") public ModelAndView insert(News news) throws Exception { ModelAndView mv = new ModelAndView("/forward.jsp");
// 日期格式化 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); news .setPubDate(new Timestamp(sf.parse(news.getPubDateStr()) .getTime()));
service.insert(news);
mv.addObject("message", "发布成功"); mv.addObject("url", "pages/suc.jsp");
return mv; } |
而且中文信息需要进行编码处理,所以最好完成一个编码过滤器来实现此功能。
添加功能实现后,完成分页列表功能,编写Action中的list方法。
@RequestMapping(value = "news_list") public ModelAndView list( @RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageSize", defaultValue = "5") int pageSize, @RequestParam(value = "keyword", defaultValue = "") String keyword, @RequestParam(value = "column", defaultValue = "title") String column) throws Exception { ModelAndView mv = new ModelAndView("/pages/news/news_list.jsp");
Map<String, Object> map = service.list(pageNo, pageSize, keyword, column); // 可以自动将map集合中的每个值直接传递到request属性范围中 mv.addAllObjects(map);
return mv; } |
页面迭代循环,使用c标签。
<center> <table border="1" width="80%"> <tr> <td> 编号 </td> <td> 标题 </td> <td> 内容 </td> <td> 所属分类 </td> <td> 发布日期 </td> <td> 照片 </td> <td> 操作 </td> </tr> <c:forEach var="news" items="${allNews}"> <tr> <td> ${news.id } </td> <td> ${news.title } </td> <td> ${news.content } </td> <td> ${news.newsType.tname } </td> <td> <fmt:formatDate value="${news.pubDate}" pattern="yyyy-MM-dd" /> </td> <td> <img src="upload/${news.photo==null?'nophoto.png':news.photo}" width="100" height="75" /> </td> <td> <a href="pages/news_updatePre.action?id=${news.id}">修改</a> <a href="pages/news_delete.action?id=${news.id}" onclick="return window.confirm('确定要删除吗?');">删除</a> </td> </tr> </c:forEach> </table>
<br />
<jsp:include page="/split_page_plugin.jsp"> <jsp:param value="${pageNo}" name="pageNo" /> <jsp:param value="${pageSize}" name="pageSize" /> <jsp:param value="${keyword}" name="keyword" /> <jsp:param value="${column}" name="column" /> <jsp:param value="${allCount}" name="count" /> <jsp:param value="pages/news_list.action" name="URL" /> <jsp:param value="title:新闻标题|content:新闻内容" name="columnData" /> <jsp:param value="3" name="pageStyle" /> </jsp:include> </center> <br> |
pageNo等四个参数必须手工设置到属性范围,否则还会提示错误。
@RequestMapping(value = "news_list") public ModelAndView list( @RequestParam(value = "pageNo", defaultValue = "1") int pageNo, @RequestParam(value = "pageSize", defaultValue = "5") int pageSize, @RequestParam(value = "keyword", defaultValue = "") String keyword, @RequestParam(value = "column", defaultValue = "title") String column) throws Exception { ModelAndView mv = new ModelAndView("/pages/news/news_list.jsp");
Map<String, Object> map = service.list(pageNo, pageSize, keyword, column); // 可以自动将map集合中的每个值直接传递到request属性范围中 mv.addAllObjects(map);
// 手工将pageNo等4个值加入到request范围里 mv.addObject("pageNo", pageNo); mv.addObject("pageSize", pageSize); mv.addObject("keyword", keyword); mv.addObject("column", column);
return mv; }
|
完成删除功能
@RequestMapping(value = "news_delete") public ModelAndView delete(@RequestParam(value = "id") int id) throws Exception { ModelAndView mv = new ModelAndView("/forward.jsp");
service.delete(id);
mv.addObject("message", "删除成功"); mv.addObject("url", "pages/news_list.action");
return mv; } |
修改功能
@RequestMapping(value = "news_updatePre") public ModelAndView updatePre(@RequestParam(value = "id") int id) throws Exception { ModelAndView mv = new ModelAndView("/pages/news/news_update.jsp");
Map<String, Object> map = service.updatePre(id); mv.addAllObjects(map);
return mv; }
|
完成修改页
<center> <form:form action="pages/news_update.action" method="post" commandName="news"> 新闻标题: <form:input path="title"/> <br/> 新闻内容: <form:textarea path="content"/> <br/> 新闻发布日期: <form:input path="pubDateStr"/> <br/> 新闻分类: <form:select path="newsType.tid"> <form:options items="${allType}" itemValue="tid" itemLabel="tname"/> </form:select> <br/> <form:hidden path="id"/> <input type="submit" value="提交"/> </form:form> </center> |
测试时,日期类型没有自动回填,需要手工在updatePre()方法中进行日期格式化。
@RequestMapping(value = "news_updatePre") public ModelAndView updatePre(@RequestParam(value = "id") int id) throws Exception { ModelAndView mv = new ModelAndView("/pages/news/news_update.jsp");
Map<String, Object> map = service.updatePre(id);
// 为了回填表单,进行格式化操作 News news = (News) map.get("news"); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); news.setPubDateStr(sf.format(news.getPubDate()));
mv.addAllObjects(map);
return mv; } |
最后提交修改
@RequestMapping(value = "news_update") public ModelAndView update(News news) throws Exception { ModelAndView mv = new ModelAndView("/forward.jsp");
// 日期格式化 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); news .setPubDate(new Timestamp(sf.parse(news.getPubDateStr()) .getTime()));
service.update(news);
mv.addObject("message", "修改成功"); mv.addObject("url", "pages/news_list.action");
return mv; } |