springMVC笔记系列(19)——控制器实现详解(上)
2016-12-03 17:36
585 查看
说明:本文章的内容转载至:https://my.oschina.net/happyBKs/blog/420310
如有侵权的地方,请联系本人,本人将会立即删除!
本文我们在前文基础上引入一个例子,边做边聊控制器。
我们想实现一个课程查询的功能。
首先大脑应该条件反射——如何定义MVC。
M:课程(包含章节)——Course(包含Chapter)
V:课程页面——course_overview.jsp
C:编写一个控制器接收springMVC前端控制器dispatcherServlet的请求转发——CourseController
另外,Service——一些业务逻辑调用——业务接口CourseService,业务实现CourseServiceImpl
然后,在思考如何在springMVC下组织上述各个部分。
C控制器是M、V、Service的中间桥梁,如何组织都是围绕着C展开的。
请求URL由springMVC前端控制器dispatcherServlet转发给控制器C——在web.xml配置dispatcherServlet,给出前端控制器配置文件路径
如何标记控制器C——配置前端控制器配置文件,定义搜索包范围空间、激活注解;在类定义的地方为类添加控制器注解
如何将URL请求与控制器之间建立映射——RequestMapping注解控制器类和方法
控制器C调用Service业务逻辑——在控制器类相应方法中调用Service接口方法;Service被控制器C所关联,控制器C中的Service属性引用需要用spring的依赖注入的方式完成初始化,所以要配置spring容器(一是要在web.xml配置spring,指明spring容器配置文件路径;二是在spring容器配置文件中配置好这些bean,本文的示例采用注解方法)
控制器C与视图V建立映射——前端控制器配置文件配置ViewResolver(定义前缀和后缀);控制器类的对应的接收请求的方法返回字符串;拼接出webapp下的资源路径字符串。
以上我通过两两关系描述了几部分是如何组织起来的,各种配置分别解决哪一个两两关系。好,我们直接进入项目来看。
首先是定义M、V、C、Service几个部分:
M部分:
Course:
Chapter:
V:
\src\main\webapp\WEB-INF\jsps\course_overview.jsp
值得注意的是,这里的href=”<%=request.getContextPath()%>/resources/css/main.css”这里url资源路径中的resources/**会在前端控制器配置文件中被配置映射到webapp项目资源路径。
这个后面会有详细的配置文件。
另外,jsp页面中的EL表达式中course,其名称也与控制器类中的相关参数和配置相对应。
Service:
业务模块部分都是讲接口调用和业务实现分类的。一个接口对应一个实现。
CourseService
CourseServiceImpl
控制器C:
好好好,终归到了几个部分的中心环节了。CourseController类是控制器类,用@Controller注解。其类和方法注解@RequestMapping,实现请求url到控制器类的映射。当然控制器类的相应方法会返回相关字符串,与前端控制器配置文件\WEB-INF\configs\spring\mvc-dispatcher-servlet.xml中的项目视图资源映射,即这里映射到\WEB-INF\jsps\course_overview.jsp
CourseController
在这个控制器类中,我们注入了一个Service。Service和控制器C之间存在依赖,我们使用spring依赖注入Service的实现类对象,使用的自动化注入成员变量引用某个具体的bean,用@Autowired注解,相应的被注解的业务实现类需要标注@Service,并且,spring配置文件的搜索包空间必须包含它。
另外,本控制器类中增加了一个日志工具,帮助我们记录下执行步骤和信息。因为需要用slf4j中的log相关类型。所以我们需要重新对pom.xml增加一些jar的依赖坐标。
pom.xml
还需要一log的配置文件:
注意,这个配置文件属于源代码的配置文件,与webapp的配置文件不同,所以这里所处的resouces文件夹其实不同的一个,特别注意!!
springMVC的配置文件\WEB-INF\configs\spring\mvc-dispatcher-servlet.xml
spring容器配置文件applicationContext.xml:
另外需要一些css文件和js文件,这个不细说。
最后请求的结果如下:
如有侵权的地方,请联系本人,本人将会立即删除!
本文我们在前文基础上引入一个例子,边做边聊控制器。
我们想实现一个课程查询的功能。
首先大脑应该条件反射——如何定义MVC。
M:课程(包含章节)——Course(包含Chapter)
V:课程页面——course_overview.jsp
C:编写一个控制器接收springMVC前端控制器dispatcherServlet的请求转发——CourseController
另外,Service——一些业务逻辑调用——业务接口CourseService,业务实现CourseServiceImpl
然后,在思考如何在springMVC下组织上述各个部分。
C控制器是M、V、Service的中间桥梁,如何组织都是围绕着C展开的。
请求URL由springMVC前端控制器dispatcherServlet转发给控制器C——在web.xml配置dispatcherServlet,给出前端控制器配置文件路径
如何标记控制器C——配置前端控制器配置文件,定义搜索包范围空间、激活注解;在类定义的地方为类添加控制器注解
如何将URL请求与控制器之间建立映射——RequestMapping注解控制器类和方法
控制器C调用Service业务逻辑——在控制器类相应方法中调用Service接口方法;Service被控制器C所关联,控制器C中的Service属性引用需要用spring的依赖注入的方式完成初始化,所以要配置spring容器(一是要在web.xml配置spring,指明spring容器配置文件路径;二是在spring容器配置文件中配置好这些bean,本文的示例采用注解方法)
控制器C与视图V建立映射——前端控制器配置文件配置ViewResolver(定义前缀和后缀);控制器类的对应的接收请求的方法返回字符串;拼接出webapp下的资源路径字符串。
以上我通过两两关系描述了几部分是如何组织起来的,各种配置分别解决哪一个两两关系。好,我们直接进入项目来看。
首先是定义M、V、C、Service几个部分:
M部分:
Course:
package com.happyBKs.model; import java.util.List; public class Course { // 课程Id private Integer courseId; // 课程名称 private String title; // 图片路径 private String imgPath; // 学习人数 private Integer learningNum; // 课程时长 private Long duration; // 课程难度 private Integer level; // 课程难度描述 private String levelDesc; // 课程介绍 private String descr; // 课程提纲 private List chapterList; public Integer getCourseId() { return courseId; } public void setCourseId(Integer courseId) { this.courseId = courseId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Integer getLearningNum() { return learningNum; } public void setLearningNum(Integer learningNum) { this.learningNum = learningNum; } public Integer getLevel() { return level; } public void setLevel(Integer level) { this.level = level; } public String getImgPath() { return imgPath; } public void setImgPath(String imgPath) { this.imgPath = imgPath; } public List getChapterList() { return chapterList; } public void setChapterList(List chapterList) { this.chapterList = chapterList; } public Long getDuration() { return duration; } public void setDuration(Long duration) { this.duration = duration; } public String getDescr() { return descr; } public void setDescr(String descr) { this.descr = descr; } public String getLevelDesc() { return levelDesc; } public void setLevelDesc(String levelDesc) { this.levelDesc = levelDesc; } }
Chapter:
package com.happyBKs.model; public class Chapter { private Integer id; private Integer courseId; private Integer order; private String title; private String descr; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getCourseId() { return courseId; } public void setCourseId(Integer courseId) { this.courseId = courseId; } public Integer getOrder() { return order; } public void setOrder(Integer order) { this.order = order; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescr() { return descr; } public void setDescr(String descr) { this.descr = descr; } }
V:
\src\main\webapp\WEB-INF\jsps\course_overview.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java. 17bf4 sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>HappyBKs喜欢原先的osc博客页面</title> <link rel="stylesheet" href="<%=request.getContextPath()%>/resources/css/main.css" type="text/css" /> </head> <body> <div id="main"> <div class="newcontainer" id="course_intro"> <div class="course-title">${course.title}</div> <div class="course_info"> <div class="course-embed l"> <div id="js-course-img" class="img-wrap"> <img width="600" height="340" alt="" src="<%=request.getContextPath()%>/${course.imgPath}" class="course_video" /> </div> <div id="js-video-wrap" class="video" style="display: none"> <div class="video_box" id="js-video"></div> </div> </div> <div class="course_state"> <ul> <li><span>学习人数</span> <em>${course.learningNum }</em></li> <li class="course_hour"><span>课程时长</span> <em class="ft-adjust"><span>${course.duration }</span>秒</em></li> <li><span>课程难度</span> <em>${course.levelDesc }</em></li> </ul> </div> </div> <div class="course_list"> <div class="outline"> <h3 class="chapter_introduces">课程介绍</h3> <div class="course_shortdecription">${course.descr}</div> <h3 class="chapter_catalog">课程提纲</h3> <ul id="couList"> <c:forEach items="${course.chapterList}" var="chapter"> <li class="clearfix open"><a href="#"> <div class="openicon"></div> <div class="outline_list l"> <!-- <em class="outline_zt"></em> --> <h5 class="outline_name">${chapter.title }</h5> <p class="outline_descr">${chapter.descr }</p> </div> </a></li> </c:forEach> </ul> </div> </div> </div> </div> </body> </html>
值得注意的是,这里的href=”<%=request.getContextPath()%>/resources/css/main.css”这里url资源路径中的resources/**会在前端控制器配置文件中被配置映射到webapp项目资源路径。
这个后面会有详细的配置文件。
另外,jsp页面中的EL表达式中course,其名称也与控制器类中的相关参数和配置相对应。
Service:
业务模块部分都是讲接口调用和业务实现分类的。一个接口对应一个实现。
CourseService
package com.happyBKs.service; import com.happyBKs.model.Course; import org.springframework.stereotype.Service; @Service public interface CourseService { Course getCoursebyId(Integer courseId); }
CourseServiceImpl
package com.happyBKs.service.impl; import java.util.ArrayList; import java.util.List; import com.happyBKs.model.Chapter; import com.happyBKs.model.Course; import com.happyBKs.service.CourseService; import org.springframework.stereotype.Service; @Service("courseService") public class CourseServiceImpl implements CourseService { public Course getCoursebyId(Integer courseId) { Course course = new Course(); course.setCourseId(courseId); course.setTitle("springMVC笔记系列"); course.setImgPath("resources/imgs/course-img.jpg"); course.setLearningNum(12345); course.setLevel(2); course.setLevelDesc("中级"); course.setDuration(7200l); course.setDescr("springMVC哈哈哈哈。"); List<Chapter> chapterList = new ArrayList<Chapter>(); warpChapterList(courseId,chapterList); course.setChapterList(chapterList); return course; } private void warpChapterList(Integer courseId,List<Chapter> chapterList) { Chapter chapter = new Chapter(); chapter.setId(1); chapter.setCourseId(courseId); chapter.setOrder(1); chapter.setTitle("第1章 什么springMVC"); chapter.setDescr("此处略去1个字"); chapterList.add(chapter); chapter = new Chapter(); chapter.setId(2); chapter.setCourseId(courseId); chapter.setOrder(2); chapter.setTitle("第2章 环境搭建"); chapter.setDescr("此处略去2个字"); chapterList.add(chapter); chapter = new Chapter(); chapter.setId(3); chapter.setCourseId(courseId); chapter.setOrder(3); chapter.setTitle("第3章 前端控制器"); chapter.setDescr("此处略去3个字"); chapterList.add(chapter); chapter = new Chapter(); chapter.setId(4); chapter.setCourseId(courseId); chapter.setOrder(4); chapter.setTitle("第4章 spring上下文环境配置"); chapter.setDescr("此处略去4个字"); chapterList.add(chapter); chapter = new Chapter(); chapter.setId(5); chapter.setCourseId(courseId); chapter.setOrder(5); chapter.setTitle("第5章 示例"); chapter.setDescr("此处略去5个字"); chapterList.add(chapter); } }
控制器C:
好好好,终归到了几个部分的中心环节了。CourseController类是控制器类,用@Controller注解。其类和方法注解@RequestMapping,实现请求url到控制器类的映射。当然控制器类的相应方法会返回相关字符串,与前端控制器配置文件\WEB-INF\configs\spring\mvc-dispatcher-servlet.xml中的项目视图资源映射,即这里映射到\WEB-INF\jsps\course_overview.jsp
CourseController
package com.happyBKs.controller; import com.happyBKs.model.Course; import com.happyBKs.service.CourseService; 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; /** * Created by happyBKs on 2016/6/15. */ @Controller @RequestMapping("/courses") // /courses/** public class CourseController { //完成日志信息 private static Logger log= LoggerFactory.getLogger(CourseController.class); private CourseService courseService; //使用spring容器管理里了对应的依赖关系 @Autowired public void setCourseService(CourseService courseService) { this.courseService = courseService; } //提供完成一个业务的方法:根据课程ID查询课程内容。 //本方法将处理 /courses/view?courseId=123 形式的URL @RequestMapping(value="/view", method= RequestMethod.GET) public String viewCourse(@RequestParam("courseId") Integer courseId, Model model) { //日志输出,查看请求的courseId是不是我们的courseId log.debug("In viewCourse, courseId = {}", courseId); Course course = courseService.getCoursebyId(courseId); model.addAttribute(course); return "course_overview"; } }
在这个控制器类中,我们注入了一个Service。Service和控制器C之间存在依赖,我们使用spring依赖注入Service的实现类对象,使用的自动化注入成员变量引用某个具体的bean,用@Autowired注解,相应的被注解的业务实现类需要标注@Service,并且,spring配置文件的搜索包空间必须包含它。
另外,本控制器类中增加了一个日志工具,帮助我们记录下执行步骤和信息。因为需要用slf4j中的log相关类型。所以我们需要重新对pom.xml增加一些jar的依赖坐标。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>testIdea.happBKs.mvc</groupId> <artifactId>springMVC</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>springMVC Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <commons-lang.version>2.6</commons-lang.version> <slf4j.version>1.7.21</slf4j.version> <spring.version>4.2.6.RELEASE</spring.version> <jackson.version>2.7.4</jackson.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>${spring.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>${commons-lang.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <finalName>springMVC</finalName> </build> </project>
还需要一log的配置文件:
注意,这个配置文件属于源代码的配置文件,与webapp的配置文件不同,所以这里所处的resouces文件夹其实不同的一个,特别注意!!
log4j.appender.Cons=org.apache.log4j.ConsoleAppender log4j.appender.Cons.layout=org.apache.log4j.PatternLayout log4j.appender.Cons.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n # Root logger set to DEBUG using the A2 appender defined above. log4j.rootLogger=info, Cons log4j.additivity=false #Application Logger+ log4j.logger.com.imooc.mvcdemo=debug, Cons log4j.logger.org.springframework=debug, Cons log4j.additivity.com=false
springMVC的配置文件\WEB-INF\configs\spring\mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 本配置文件是工名为mvc-dispatcher的DispatcherServlet使用, 提供其相关的Spring MVC配置 --> <!-- 启用Spring基于annotation的DI, 使用户可以在Spring MVC中使用Spring的强大功能。 激活 @Required @Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注 --> <context:annotation-config /> <!-- DispatcherServlet上下文, 只管理@Controller类型的bean, 忽略其他型的bean, 如@Service --> <context:component-scan base-package="com.happyBKs.controller"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- HandlerMapping, 无需配置, Spring MVC可以默认启动。 DefaultAnnotationHandlerMapping annotation-driven HandlerMapping --> <!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 --> <mvc:annotation-driven /> <!-- 静态资源处理, css, js, imgs --> <mvc:resources mapping="/resources/**" location="/resources/" /> <!-- 配置ViewResolver。 可以用多个ViewResolver。 使用order属性排序。 InternalResourceViewResolver放在最后。 --> <!--<bean--> <!--class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">--> <!--<property name="order" value="1" />--> <!--<property name="mediaTypes">--> <!--<map>--> <!--<entry key="json" value="application/json" />--> <!--<entry key="xml" value="application/xml" />--> <!--<entry key="htm" value="text/html" />--> <!--</map>--> <!--</property>--> <!--<property name="defaultViews">--> <!--<list>--> <!--<!– JSON View –>--> <!--<bean--> <!--class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">--> <!--</bean>--> <!--</list>--> <!--</property>--> <!--<property name="ignoreAcceptHeader" value="true" />--> <!--</bean>--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsps/" /> <property name="suffix" value=".jsp" /> </bean> <!--200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 --> <!--<bean id="multipartResolver"--> <!--class="org.springframework.web.multipart.commons.CommonsMultipartResolver">--> <!--<property name="maxUploadSize" value="209715200" />--> <!--<property name="defaultEncoding" value="UTF-8" />--> <!--<property name="resolveLazily" value="true" />--> <!--</bean>--> </beans>
spring容器配置文件applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:annotation-config /> <context:component-scan base-package="com.happyBKs"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> </beans>
另外需要一些css文件和js文件,这个不细说。
最后请求的结果如下:
相关文章推荐
- 分享微信开发Html5轻游戏中的几个坑
- Shiro学习之路 Hello Shiro(一)
- C# MVC模式下商品抽奖功能实现
- Zend的MVC机制使用分析(二)
- ASP.NET MVC 4 捆绑和缩小实例介绍
- asp.net mvc实现简单的实时消息推送
- ASP.NET Mvc开发之查询数据
- ASP.NET MVC中将控制器分离到类库的实现
- asp.net实现在非MVC中使用Razor模板引擎的方法
- MVC默认路由实现分页(PagerExtend.dll下载)
- ASP.NET MVC中使用JavaScriptResult的用法示例
- ASP.NET MVC中的AJAX应用
- .Net MVC网站中配置文件的读写
- 微信公众号支付(MVC版本)
- mvc form表单提交的几种形式整理总结
- mvc file控件无刷新异步上传操作源码
- 为ASP.NET MVC及WebApi添加路由优先级
- ASP.NET MVC中图表控件的使用方法
- Asp.net mvc实时生成缩率图到硬盘
- 剖析ASP.NET MVC的DependencyResolver组件