Spring MVC起步

x33g5p2x  于2021-03-14 发布在 其他  
字(19.1k)|赞(0)|评价(0)|浏览(267)

MVC的核心思想是业务数据抽取同业务数据呈现相分离。
MVC静态概念:
DispatcherServelet是前端控制器
HandlerAdapter相当于controller,DispatcherServelet调用各种HandlerAdapter来实现任务分发给相关的业务逻辑
HandlerInterceptor是一个接口,可以用来在Handler调用之前,之后,以及view呈现后可以做很多事情
HandlerMapping是负责确定DispatcherServelet与controller之间映射的类,告诉DispatcherServelet,在请求到来后,由哪个controller来响应这个请求
MVC动态工作图

使用maven创建文本工程实例:
首先编写pom.xm<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>com.sbq.webdemo1</groupId>
	<artifactId>webdemo1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>webdemo1 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
  	<commons-lang.version>2.6</commons-lang.version>
  	<slf4j.version>1.7.6</slf4j.version>
  	<spring.version>4.1.3.RELEASE</spring.version>
  </properties>
  
  <!-- 依赖管理 可以使其使用上面已经写好的4.1.3版本-->
  <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>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>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
	<dependency>
	    <groupId>javax.servlet</groupId>
	    <artifactId>javax.servlet-api</artifactId>
	    <version>4.0.0</version>
	    <!-- 只在编译 和测试时运行-->
	    <scope>provided</scope>
	</dependency>
  </dependencies>
  
  <!-- 加入插件 -->
  <build>
  	<finalName>webdemo1</finalName>
  	<plugins>
  		<plugin>
  			<groupId>org.eclipse.jetty</groupId>
  			<artifactId>jetty-maven-plugin</artifactId>
  			<version>9.2.2.v20140723</version>
  		</plugin>
  	</plugins>
  </build>
</project>l文件
<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>com.sbq.webdemo1</groupId>
	<artifactId>webdemo1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>webdemo1 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
  	<commons-lang.version>2.6</commons-lang.version>
  	<slf4j.version>1.7.6</slf4j.version>
  	<spring.version>4.1.3.RELEASE</spring.version>
  </properties>
  
  <!-- 依赖管理 可以使其使用上面已经写好的4.1.3版本-->
  <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>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>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
	<dependency>
	    <groupId>javax.servlet</groupId>
	    <artifactId>javax.servlet-api</artifactId>
	    <version>4.0.0</version>
	    <!-- 只在编译 和测试时运行-->
	    <scope>provided</scope>
	</dependency>
  </dependencies>
  
  <!-- 加入插件 -->
  <build>
  	<finalName>webdemo1</finalName>
  	<plugins>
  		<plugin>
  			<groupId>org.eclipse.jetty</groupId>
  			<artifactId>jetty-maven-plugin</artifactId>
  			<version>9.2.2.v20140723</version>
  		</plugin>
  	</plugins>
  </build>
</project>

接下来编辑web.xml文件

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
  <servlet>
  	<servlet-name>mvc-dispatcher</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<!--  DispatcherServlet对应上下文配置,默认为/WEV-INF/$servlet-name$-servlet.xml-->
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value>
  	</init-param>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>mvc-dispatcher</servlet-name>
  	<!--  mvc-dispatcher拦截所有请求-->
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

接着在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标注类不搜索其它标注的类 -->
	<context:component-scan base-package="com.sbq.webdemo1">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
	
	<!-- HandlerMapping, 无需配置, Spring MVC可以默认启动。 DefaultAnnotationHandlerMapping 
		annotation-driven HandlerMapping -->

	<!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
	<mvc:annotation-driven />
	
	<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>
</beans>

在web.xml配置文件中添加

  <!-- Spring应用上下文,理解层次化的ApplicationContext -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
  </context-param>
  
  <listener>
  	<listener-class>
  		org.springframework.web.context.ContextLoaderListener
  	</listener-class>
  </listener>

回到mvc-dispatcher-servlet.xml配置文件添加以下配置

	<!-- 静态资源处理, css, js, imgs -->
	<mvc:resources mapping="/resources/**" location="/resources/" />

在configs/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.sbq.demo1">
		<context:exclude-filter type="annotation" 
			expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
</beans>

创建Course 类

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<Chapter> 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<Chapter> getChapterList() {
		return chapterList;
	}

	public void setChapterList(List<Chapter> 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类

public class Chapter {

	private Integer id;
	private Integer courseId;
	private Integer order;
	private String title;
	private String descr;

	// private List<Section> sectionList;

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

创建接口CourseService

package com.mvcdemo.service;

import com.mvcdemo.model.Course;

public interface CourseService {
	Course getCoursebyId(Integer courseId);
}

创建service类CourseServiceImpl

package com.mvcdemo.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.mvcdemo.model.Chapter;
import com.mvcdemo.model.Course;
import com.mvcdemo.service.CourseService;

@Service("courseService")
public class CourseServiceImpl implements CourseService {

	public Course getCoursebyId(Integer courseId) {
		
		Course course = new Course();
		
		course.setCourseId(courseId);
		course.setTitle("深入浅出Java多线程");
		course.setImgPath("resources/imgs/course-img.jpg");
		course.setLearningNum(12345);
		course.setLevel(2);
		course.setLevelDesc("中级");
		course.setDuration(7200l);
		course.setDescr("多线程是日常开发中的常用知识,也是难用知识。bala bala...");
		
		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章 多线程背景知识介绍");
		chapter.setDescr("本章将介绍与多线程编程相关的背景概念");	
		chapterList.add(chapter);
		
		chapter = new Chapter();
		chapter.setId(2);
		chapter.setCourseId(courseId);
		chapter.setOrder(2);
		chapter.setTitle("第2章 Java 线程初体验");
		chapter.setDescr("Java语言层面对线程的支持,如何创建,启动和停止线程。如何使用常用的线程方法。用隋唐演义理解线程的代码");
		chapterList.add(chapter);
		
		chapter = new Chapter();
		chapter.setId(3);
		chapter.setCourseId(courseId);
		chapter.setOrder(3);
		chapter.setTitle("第3章 Java 线程的正确停止");
		chapter.setDescr("本章讨论如何正确的停止一个线程,既要线程停得了,还得线程停得好。");		
		chapterList.add(chapter);
		
		chapter = new Chapter();
		chapter.setId(4);
		chapter.setCourseId(courseId);
		chapter.setOrder(4);
		chapter.setTitle("第4章 线程交互");
		chapter.setDescr("争用条件,线程的交互,及死锁的成因及预防。");		
		chapterList.add(chapter);
		
		chapter = new Chapter();
		chapter.setId(5);
		chapter.setCourseId(courseId);
		chapter.setOrder(5);
		chapter.setTitle("第5章 进阶展望");
		chapter.setDescr("简单介绍 Java 并发相关的类,及常用的多线程编程模型。");		
		chapterList.add(chapter);
		
	}
}

回到pom.xml配置文件添加依赖

  	<dependency>
  		<groupId>org.slf4j</groupId>
  		<artifactId>slf4j-api</artifactId>
  		<version>${slf4j.version}</version>
  	</dependency>

创建CourseController类作为Controller基础代码

package com.mvcdemo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;

import com.mvcdemo.model.Course;
import com.mvcdemo.service.CourseService;

public class CourseController类作为C {
	
	private static Logger log = LoggerFactory.getLogger(CourseController.class);
	
	private CourseService courseService;
	
	public void setCourseService(CourseService courseService){
		this.courseService = courseService;
	}
	
	public String viewCorse(Integer courseId,Model model){
		Course course = courseService.getCoursebyId(courseId);
		model.addAttribute(course);
		
		return "course_overview";
	}
}

Controller现代方式---使用注解

@Controller
@RequestMapping("/courses")
public class CourseController {
	
	private static Logger log = LoggerFactory.getLogger(CourseController.class);
	
	private CourseService courseService;
	
	@Autowired
	public void setCourseService(CourseService courseService){
		this.courseService = courseService;
	}
	
	//本方法将处理/courses/view
	@RequestMapping(value="/view",method=RequestMethod.GET)
	public String viewCorse(@RequestParam("courseId") Integer courseId,Model model){
    	log.debug("In viewCourse,courseId = {}",courseId);
		Course course = courseService.getCoursebyId(courseId);
		model.addAttribute(course);
		return "course_overview";
	}
}

Controller传统方式

	@RequestMapping("view3")
	public String viewCourse3(HttpServletRequest request){
		
		Integer courseId = Integer.valueOf(request.getParameter("courseId"));
		log.debug("In viewCourse3,courseId = {}",courseId);
		Course course = courseService.getCoursebyId(courseId);
		request.setAttribute("course", course);
		return "course_overview";
	}

通过 @Controller生成一个controller,然后通过@RequestMapping映射了url和方法,最后通过URL template(@RequestParam and @PathVariable)可以将URL路径中的参数绑定,或者通过HttpServletRequest获取我们想要的结果

Binding
请求中的字段按照名字匹配的原则填入模型对象,通过@ModelAttribute把模型跟页面数据绑定

@RequestMapping(value="/admin",method=RequestMethod.GET,params="add")
	public String createCourse(){
		return "course_admin/edit";
	}
	
	@RequestMapping(value="/save",method=RequestMethod.POST)
	public String dosave(@ModelAttribute Course course){
		
		log.debug("Info of Course");
		log.debug(ReflectionToStringBuilder.toString(course));
		
		//进行业务操作,比如数据库持久化
		course.setCourseId(123);
		return "redirect:view2/"+course.getCourseId();
	}

FileUpload单文件上传
首先在mvc-dispatcher-servlet.xmlp配置文件中配置一段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>

然后回到pom.xml配置文件引入CommonsMultipartResolver包的依赖

		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>

回到 类添加功能代码

	@RequestMapping(value="/upload", method=RequestMethod.GET)
	public String showUploadPage(@RequestParam(value= "multi", required = false) Boolean multi){	
		if(multi != null && multi){
			return "course_admin/multifile";	
		}
		return "course_admin/file";		
	}
    
    @RequestMapping(value="/doUpload", method=RequestMethod.POST)
	public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{
		
		if(!file.isEmpty()){
			log.debug("Process file: {}", file.getOriginalFilename());
			FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\\temp\\imooc\\", System.currentTimeMillis()+ file.getOriginalFilename()));
		}
		
		return "success";
	}

JSON
首先在mvc-dispatcher-servlet.xml配置文件配置ViewResolver

	<!-- 配置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>

其次在pom.xml文件引入JSON的依赖

		<dependency>
						<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>

回到CourseController类中写JSON方法

@RequestMapping(value="/{courseId}",method=RequestMethod.GET)
	public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
		return  courseService.getCoursebyId(courseId);
	}

先通过ContentNegotiatingViewResolver把相同格式数据呈现请求转换到不同的view,在服务端代码中使用ResponseEntity来处理返回结果,或者使用@ResponseBody/@ResquestBody标签来处理我们返回数据

相关文章