SpringMVC学习笔记

sevlet转发和重定向

用户访问servlet后,servlet处理完自己将结果给用户叫转发(url不变),给地址让用户请求叫重定向。

HelloMVC

1.在web.xml中配置

 <!--1.注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:[servlet-name]-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--匹配所有请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

2.编写HelloController

public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //模型和视图
        ModelAndView mv=new ModelAndView();
        //封装对象
        mv.addObject("msg","HelloSpringMVC");
        //封装要跳转的视图
        mv.setViewName("hello");
        return mv;
    }
}

3.关联一个springmvc配置文件

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    
    <!--视图解析器:DispatcherServlet给他的ModelAndView-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    
    <!--Handler-->
    <bean id="/hello" class="com.ma.controller.HelloController"/>

4.编写jsp文件,配置tomcat

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>  
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

可能遇到的问题

  1. 如果jar包存在,显示无法输出,就在IDEA的项目发布中(Tomcat)添加lib依赖
  2. spingmvc中没配好,没有配置注解驱动等。

SpringMVC执行原理

SpringMVC执行原理

  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. 最终视图呈现给用户。

SpringMVC注解开发

在Spring中一般采用@RequestMapping注解来完成映射关系,要想使@RequestMapping注解生效,必须注册DefaultAnnotationHandlerMappin和一个AnnotationMethodHandlerAdapter实例,这两个实例分别在类级别和方法级别处理。而annotation-driven配置帮助我们自动完成上述两个实例的注入。

RestFul风格

  1. 概念Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。
  2. 使用方法:
    • @RequestMapping(value = "/hello",method = {RequestMethod.POST})
    • 快捷方式GetMapping("/add{a}/{b})

SpringMVC结果跳转

  1. 在没有视图解析器的时候,使用全路径。
    • 转发
    return "forward:/WEB-INF/index.jsp" 
    
    • 重定向
    return "forward:/index.jsp" 
    
  2. 有视图解析器的时候,可以在视图解析器中设置前缀、后缀拼接。

spring接受参数

  1. 接受一个非对象时,在参数前加注解@RequestParam,为明确这是个前端接受的参数,不管需不需要都加上。
  2. 接收的字段名必须类中字段名一致
  3. 乱码问题
    加一个filter
  • 编写类继承servlet包下的Filter,重写doFilter方法
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,     ServletException {
      servletRequest.setCharacterEncoding("utf-8");
      servletResponse.setCharacterEncoding("utf-8");
      filterChain.doFilter(servletRequest,servletResponse);
  }
  • 在web.xml中配置filter
  <filter>
    <filter-name>encoding</filter-name>
    <filter-class>com.ma.filter.EncodingFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
      <filter-name>encoding</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
          <param-name>encoding</param-name>
          <param-value>utf-8</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>encoding</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

SpringMVC使用JSON

  1. 导入包
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.11.0</version>
    </dependency>
  1. 获取JSON字符串
    User user=new User(1,"马天乐",22);
    String str=new ObjectMapper().writeValueAsString(user);

乱码问题,在SpringMVC文件中配置

//JSON乱码问题配置
    <!--JSON乱码问题配置-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

Ajax

  • Ajax是一种之刷新页面部分内容而不刷新整个页面的技术,例如百度的搜索框,每次点击或键入一些内容都会有不同的推荐。
  • jQuery.ajax的主要属性
$.ajax({
  url:"${pageContext.request.contextPath}/a1",
  data:{"name":$("#username").val()},
  success: function (data) {
    alert(data);
  },
  error: function () {
  }
})

其他属性:官方文档

拦截器

拦截器是AOP思想的一个具体实现。
使用方法:

  • 编写拦截器类继承HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {

    //return true;放行,执行下一个拦截器,反之拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }
}
  • 在springmvc文件中配置
<mvc:interceptors>
    <mvc:interceptor>
        <!--/**拦截当前文件夹以及子文件夹,/*拦截当前文件夹,不包括子文件夹-->
        <mvc:mapping path="/**"/>
        <bean class="com.ma.config.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

springmvc实现文件上传

  • 在springmvc配置文件中配置:
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--配置编码格式,必须与pageEncoding属性一致,以便能正常读取表单内容-->
        <property name="defaultEncoding" value="utf-8"/>
        <!--上传文件大小限制,单位为字节,10m=10485760字节-->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>
  • 编写页面
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
  <input type="file" name="file">
  <input type="submit" name="upload">
</form>
  • 编写Controller
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file ,HttpServletRequest request) throws IOException {
        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();
        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);
        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);
        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
        //读取写出
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }

    @RequestMapping(value="/download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String path = request.getServletContext().getRealPath("/upload");
        String fileName = "timg.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 "ok";
    }
原文地址:https://www.cnblogs.com/Tig3r/p/13128961.html