慕课网课程--Spring MVC起步 控制层代码:
package com.imooc.mvcdemo.controller;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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.multipart.MultipartHttpServletRequest;
import com.imooc.mvcdemo.model.Course;
import com.imooc.mvcdemo.service.CourseService;
@Controller
@RequestMapping("/courses")
// /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?courseId=123 形式的URL
//@RequestParam("courseId") 接收courseId赋值给Integer courseId
//Model:Spring mvc特有的类型
//返回值就是JSP页面的名称部分
@RequestMapping(value="/view", method=RequestMethod.GET)
//model的第一种形式(一共三种)
public String viewCourse(@RequestParam("courseId") Integer courseId,
Model model) {
//日志记录
log.debug("In viewCourse, courseId = {}", courseId);
Course course = courseService.getCoursebyId(courseId);
model.addAttribute(course);
//把course放到model中 检索到 页面中 默认的名称为course
return "course_overview";
}
//本方法将处理 /courses/view2/123 形式的URL
@RequestMapping("/view2/{courseId}")
//model的第二种形式Map<String, Object> model
/**花括号:指明是路径变量 @PathVariable("courseId")得到入参是路径变量
这样Spring完成了变量的绑定和路径变换 Integer courseId*/
public String viewCourse2(@PathVariable("courseId") Integer courseId,
Map<String, Object> model) {
log.debug("In viewCourse2, courseId = {}", courseId);
Course course = courseService.getCoursebyId(courseId);
model.put("course",course);
return "course_overview";
}
//本方法将处理 /courses/view3?courseId=123 形式的URL
@RequestMapping("/view3")
public String viewCourse3(HttpServletRequest request) {
Integer courseId = Integer.valueOf(request.getParameter("courseId"));
Course course = courseService.getCoursebyId(courseId);
request.setAttribute("course",course);
return "course_overview";
}
/**-----------------------------------------------------
Binding
*/
//请求路径:http://localhost:8080/courses/admin?add
@RequestMapping(value="/admin", method = RequestMethod.GET, params = "add")
public String createCourse(){
//多目录下如何书写 :在根下写下相对路径即可
return "course_admin/edit";
}
@RequestMapping(value="/save", method = RequestMethod.POST)
//第三种model形式:@ModelAttribute--》 参数级别的annotation @ModelAttribute通过这个也可以完成参数的绑定
public String doSave(@ModelAttribute Course course){
log.debug("Info of Course:");
log.debug(ReflectionToStringBuilder.toString(course));
//在此进行业务操作,比如数据库持久化
course.setCourseId(123);
//请求重定向:两次请求:Url改变 可以试一下请求转发
return "redirect:view2/"+course.getCourseId();
}
/**-------------------------------------------
FileUpload-----单文件上传
在web.xml配置这样的一个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>
*/
@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{
/*文件不为空拷贝到F:\\temp\\imooc\\
保存名称:System.currentTimeMillis()+ file.getOriginalFilename():文件名加上时间戳*/
if(!file.isEmpty()){
log.debug("Process file: {}", file.getOriginalFilename());
FileUtils.copyInputStreamToFile(file.getInputStream(), new File("F:\\temp\\imooc\\", System.currentTimeMillis()+ file.getOriginalFilename()));
}
return "success";
}
@RequestMapping(value="/doUpload2", method=RequestMethod.POST)
public String doUploadFile2(MultipartHttpServletRequest multiRequest) throws IOException{
Iterator<String> filesNames = multiRequest.getFileNames();
while(filesNames.hasNext()){
String fileName =filesNames.next();
MultipartFile file = multiRequest.getFile(fileName);
if(!file.isEmpty()){
log.debug("Process file: {}", file.getOriginalFilename());
FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\\temp\\imooc\\", System.currentTimeMillis()+ file.getOriginalFilename()));
}
}
return "success";
}
/** 1. Spring MVC 支持Json的配置
* <!-- ContentNegotiatingViewResolver:Spring MVC提供的相同数据不同应用方式的呈现形式(机器用户和人用户(html页面)) -->
<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
<!-- 把模型数据转换成Json格式 的类库-->
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
2.在POM.XML中引入Json依赖
*/
/*
* 第一种方式:
* 返回值是一个course对象
* @ResponseBody Course 标记了course类 说明这个course会被响应所使用
*/
@RequestMapping(value="/{courseId}",method=RequestMethod.GET)
public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
return courseService.getCoursebyId(courseId);
}
/**
* 第二种方式:ResponseEntity<Course>
* 这就可以返回给浏览器一个course对象的json数据(model转换成json)
* @param courseId
* @return
*/
@RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
public ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
Course course = courseService.getCoursebyId(courseId);
return new ResponseEntity<Course>(course, HttpStatus.OK);
}
}
springMVC传递参数的三种方式:
1)使用参数注解@RequestParam
url形式:http://host:8080/courses/view?courseID=123
controller参数中传入:@RequestParam("courseID") Integer courseID
2)使用路径变量注解@PathVariable
url形式:http://host:8080/courses/view2/{courseID}
方法的requestMapping:@RequestMapping(value="/view2/{courseID}",method=RequestMethod.GET)
controller参数中传入:@PathVariable("courseID") Integer courseID
3)使用传统的从HttpServletRequest获取参数
url形式:http://host:8080/courses/view3?courseID=123
controller参数中传入HttpServletRequest,使用request.getParameter("key")来获取参数值。
4)使用传统的httpSession获取参数
1.@Controller:类级别 ,让HandlerMapping可以识别
2.@RequestMapping:类级别:组成项目的根目录;方法级别:组成下一级目录
@RequestMapping(value="/admin", method = RequestMethod.GET, params = "add")
method:请求的方式 params:请求的url参数
组成的url:--》http://localhost:8080/courses/admin?add=123
在add后面加值 不改变响应视图
方法级别的@RequestMapping可以只有value 如:@RequestMapping(“/view”)
3.@PathVariable():参数级别,(如:@RequestMapping("/view2/{courseId}") 花括号里的就表示路径变量),获取路径变量绑定到参数名为courseId 的Integer类型上,类型的转换就交给Spring MVC
4.@RequestParam():参数级别,(如:@RequestParam("courseId")获取URL为--》http://localhost:8080/courses/view?courseId=123 的courseId的值123,获取的值就绑定到参数名相同的courseId上,类型的转换就交给Spring MVC)
5.redirect/forward:请求重定向/请求转发
6.MutipartFile:上传的文件类型 jsp页面的form属性中必须加入enctype="multipart/form-data"
就如上面的方法:public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{};
7.@ModelAttribute:通常使用在Controller方法的参数注解中,用于解释model entity.此时分两种情况:从Model中获取或者从Form表单/URL参数中获取,如果是后者,则不添加此注释实际也能拿到对象。
但同时@ModelAttribute也可以放在方法注解里, 如果把@ModelAttribute放在方法的注解上时,代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法。(自己也不懂这句话是什么意思)
8.multipartResolver: 使用Spring MVC 上传单个文件时 在mvc-dispatcher-servlet.xml配置这样的一个Bean:id为:multipartResolver 这个bean是一个试图解析器ViewResolver 需要配置在InternalResourceViewResolver的后面 当然还需要在POM文件中加入依赖包:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
9.Json是一种数据格式 :
①.@ResponseBody:
如:
@RequestMapping(value="/{courseId}",method=RequestMethod.GET)
public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
return courseService.getCoursebyId(courseId);
}
@ResponseBody Course 标记了course类 说明这个course会被响应所使用
②.ResponseEntity<Course>
方法:
@RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
public ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
Course course = courseService.getCoursebyId(courseId);
return new ResponseEntity<Course>(course, HttpStatus.OK);
}
第二种方式:ResponseEntity<Course>
这就可以返回给浏览器一个course对象的json数据(model转换成json)