1.SpringMVC

1.1 MVC架构模式

MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合
MVC框架要做哪些事情

  1. 将url映射到java类或java类的方法 .
  2. 封装用户提交的数据 .
  3. 处理请求—调用相关的业务处理—封装响应数据 .
  4. 将响应的数据进行渲染 . jsp / html 等表示层数据 .

1.2 SpringMVC简述

1.2.1 中心控制器

DispatcherServlet作用是将请求分发到不同的处理器,是一个实际的Servlet (它继承自HttpServlet 基类)

1.2.2 SpringMVC执行原理(了解)

实线部分由框架自己完成,开发者只关注虚线部分,常用组件处理器映射器、处理器适配器、视图解析器

通常,我们只需要手动配置视图解析器,而处理器映射器处理器适配器只需要开启注解驱动即可,而省去了大段的xml配置

SpringMVC - 图1

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
    我们假设请求的url为 : http://localhost:8080/SpringMVC/hello,url可以拆分成三部分:
    http://localhost:8080服务器域名、SpringMVC部署在服务器上的web站点、hello表示控制器
    通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
  6. Handler让具体的Controller执行。
  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。
  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
  12. 最终视图呈现给用户。

1.3 入门程序(使用注解)

(1)创建maven项目,添加springmvc相关依赖;

(2)在web.xml中注册前端控制器;

  1. <!--注册一个前端控制器-->
  2. <servlet>
  3. <servlet-name>springmvc</servlet-name>
  4. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  5. <init-param>
  6. <param-name>contextConfigLocation</param-name>
  7. <param-value>classpath:/spring/springmvc-*</param-value>
  8. </init-param>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>springmvc</servlet-name>
  12. <url-pattern>/</url-pattern>
  13. </servlet-mapping>

(3)创建springmvc自己的xml文件spring-servlet,开启注解扫描并配置视图解析器;

<!--开启扫描-->
<context:component-scan base-package="包名"></context:component-scan>
<mvc:default-servlet-handler />
   <!--
   支持mvc注解驱动
       在spring中一般采用@RequestMapping注解来完成映射关系
       要想使@RequestMapping注解生效
       必须向上下文中注册DefaultAnnotationHandlerMapping
       和一个AnnotationMethodHandlerAdapter实例
       这两个实例分别在类级别和方法级别处理。
       而annotation-driven配置帮助我们自动完成上述两个实例的注入。
    -->
   <mvc:annotation-driven />
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

(4)测试类编写

@Controller
public class Controllerf {
    @RequestMapping("/controllerf")
    public String f(Model model){
        model.addAttribute("model","mod");
        return "controllerf";
    }

3.4 常用注解

  • @RequestMapping :用于映射URL到控制器类(可以使用restful风格如@GetMapping等)
  • ============================================================
  • @Pathvariable:获取URL中的占位符的值

    // http://localhost:8090/hello/2
    @GetMapping("/test/{id}")
    public String test1(@PathVariable("id") Integer id) {}
    
  • @RequestParam(“username”) 支持GET和POST请求,当前端提交的域名称和处理方法的参数名不一致时指定

    // http://localhost:8090/hello?id=2&name=tom
    public String test2(@RequestParam("id") String id,@RequestParam("name") String name){}
    
  • @RequesBody 只支持POST请求

    // http://localhost:8090/hello
    public String test3(@RequestBody User user){}
    
  • ============================================================

  • @ResponseBody :请求不再经过视图解析器,直接返回字符串
  • @RestController :功能同上,但这个作用在类上,@ResponseBody作用在方法
@Controller
public class RestFulController {

   //映射访问路径
   @GetMapping("/commit/{p1}/{p2}")
   public String index(@PathVariable int p1, @PathVariable int p2, Model model){
       int result = p1+p2;
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "结果:"+result);
       //返回视图位置
       return "test";
  }
}

3.5 转发和重定向

return "forward:/index.jsp";//默认转发,forward:可以不写
return "redirect:/index.jsp";

3.6 拦截器

过滤器与拦截器的区别:拦截器是AOP思想的具体应用。

过滤器

  • servlet规范中的一部分,任何java web工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

编写一个拦截器

public class MyInterceptor implements HandlerInterceptor {

   //在请求处理的方法之前执行
   //如果返回true执行下一个拦截器
   //如果返回false就不执行下一个拦截器
   public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
       System.out.println("------------处理前------------");
       return true;
  }

   //在请求处理方法执行之后执行
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
       System.out.println("------------处理后------------");
  }

   //在dispatcherServlet处理后执行,做清理工作.
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
       System.out.println("------------清理------------");
  }
}

在springmvc的配置文件中配置拦截器

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <!--/** 包括路径及其子路径-->
       <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
       <!--/admin/** 拦截的是/admin/下的所有-->
       <mvc:mapping path="/**"/>
       <!--bean配置的就是拦截器-->
       <bean class="com.kuang.interceptor.MyInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

3.7 springmvc的文件上传和下载

导入文件上传的jar包,commons-fileupload

在springmvc的配置文件中配置拦截器multipartResolver

<!--文件上传配置-->
<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
   <property name="defaultEncoding" value="utf-8"/>
   <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
   <property name="maxUploadSize" value="10485760"/>
   <property name="maxInMemorySize" value="40960"/>
</bean>

前端表单的method设置为POST,并将enctype设置为multipart/form-data

编写上传controller

/*
* 采用file.Transto 来保存上传的文件
*/
@RequestMapping("/upload")
public String  fileUpload(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) throws IOException {

   //上传路径保存设置
   String path = request.getServletContext().getRealPath("/upload");
   File realPath = new File(path);
   if (!realPath.exists()){
       realPath.mkdir();
  }
   //上传文件地址
   System.out.println("上传文件保存地址:"+realPath);

   //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
   file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));

   return "redirect:/index.jsp";
}

@RequestMapping(value="/download")
public String downloads(HttpServletResponse response ,HttpServletRequest request) throws Exception{
   //要下载的图片地址
   String  path = request.getServletContext().getRealPath("/upload");
   String  fileName = "基础语法.jpg";

   //1、设置response 响应头
   response.reset(); //设置页面不缓存,清空buffer
   response.setCharacterEncoding("UTF-8"); //字符编码
   response.setContentType("multipart/form-data"); //二进制传输数据
   //设置响应头
   response.setHeader("Content-Disposition",
           "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));

   File file = new File(path,fileName);
   //2、 读取文件--输入流
   InputStream input=new FileInputStream(file);
   //3、 写出文件--输出流
   OutputStream out = response.getOutputStream();

   byte[] buff =new byte[1024];
   int index=0;
   //4、执行 写出操作
   while((index= input.read(buff))!= -1){
       out.write(buff, 0, index);
       out.flush();
  }
   out.close();
   input.close();
   return null;
}