SpringMVC

SpringMVC是围绕DispatcherServlet设计的

SpringMVC的执行原理

SpringMVC

 

 

  •  DispatcherServlet表示前置控制器。是整个SpringMVC的控制中心,用户发送请求,DispatcherServlet接收并拦截请求
  • HandlerMapping为处理器映射,DispatcherServlet调用HandlerMa批评,HandlerMapping根据请求的url查找handler
  • HandlerExecution表示具体的handler,主要作用是根据根据url查找控制器。
  • HandlerExecution将解析后的信息传递给DispatcherServlet
  • HandlerAdapter表示处理器适配器,按照特定的规则去执行handler
  • handler让具体的controller执行
  • controller将具体的执行信息返回给HandlerAdapter(如:Model And View)
  • HandlerAdapter将其传递给DispatcherServlet
  • DispatcherServlet调用视图解析器View Resolver来对信息进行解析
  • DispatcherServlet根据视图解析器的解析结构调用具体的视图
  • 将视图呈现给用户

HelloSpring

配置版

导入springMVC依赖

配置web.xml文件,注册DispatcherServlet,所有的请求都经过DispatcherServlet拦截处理

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
<!--关联一个springMVC配置文件--> <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> <!--/ 匹配所有的请求;(不包括.jsp)--> <!--/* 匹配所有的请求;(包括.jsp)--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
</servlet>

在springmvc-servlet.xml的配置文件中添加处理器映射器和处理器适配器

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

添加视图解析器,解析ModelAndView对象

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
</bean>

编写业务实现Controller接口,返回一个ModelAndView对象,封装数据与视图

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

将业务类交给spring管理,编写jsp文件并配置Tomcat服务器即可启动

注解版

修改springmvc-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">
    <context:component-scan base-package="com.deng.controller" />

    <context:annotation-config/>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver
" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

 

编写Controller

@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping("/hello")
    public String sayHello(Model model){
        model.addAttribute("msg","hello,SpringMVC");
        return "hello";
    }
}

Controller及RestFul

Controller

由接口定义和注解定义两种方法实现,负责解析用户的请求并将其转换为一个模型

实现Controller接口

Controller接口在org.springframework.web.servlet.mvc包下,接口中只有一个方法

//实现该接口的类获得控制器功能
public interface Controller {
    //处理请求且返回一个模型与视图对象
    ModelAndView handleRequest(HttpServletRequest var1,HttpServletResponse var2) throws Exception;
}

实现该方法即可获得控制器功能

ModelAndView mv = new ModelAndView();
//绑定一个数据model
mv.addObject("msg","Test1Controller");
//绑定一个视图
mv.setViewName("test");

使用注解@Controller

@Controller用于声明Spring类的实例是一个控制器

Spring可以通过包扫描机制来找到应用程序中所有基于注解的控制器类,只需在配置文件中声明:

 <context:component-scan base-package="com.deng.controller"/>

@RequestMapping

@RequestMapping用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上表示类中所有响应请求的方法都是以该地址作为父路径

RestFul风格

RestFul就是一个资源定位和资源操作的风格。

传统的方式操作资源:通过不同的参数来实现不同的效果

http://127.0.0.1/item/queryItem.action?id=1 查询,GET 
http://127.0.0.1/item/saveItem.action 新增,POST 
http://127.0.0.1/item/updateItem.action 更新,POST 
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

RestFul操作资源:通过不同的请求方式实现不同的效果,请求地址引用,但是根据不同的请求方式实现的功能不一样

http://127.0.0.1/item/1 查询,GET 
http://127.0.0.1/item 新增,POST 
http://127.0.0.1/item 更新,PUT 
http://127.0.0.1/item/1 删除,DELETE

使用@RequestMapping的method属性可以指定请求的类型

//映射访问路径,必须是POST请求
@RequestMapping(value = "/hello",method = {RequestMethod.POST})
public String index2(Model model){
  model.addAttribute("msg", "hello!");
  return "test";
}

所有的地址栏请求默认是Get请求

注解的变体有

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

结果跳转的方式

ModelAndView

设置ModelAndView对象,根据view的名称和视图解析器跳转到指定页面

页面:{视图解析器前缀}+view名称+{视图解析器后缀}

<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception {
    //返回一个模型视图对象
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg","ControllerTest1");
    mv.setViewName("test");
    return mv;
   }
}

ServletAPI

通过设置ServletAPI进行输出和跳转,就不需要视图解析器

@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping("/test1")
    public void test1(HttpServletRequest request,HttpServletResponse response) throws IOException {
        response.getWriter().print("Hello,World!");
    }
    //重定向
    @RequestMapping("/test2")
    public void test2(HttpServletRequest request,HttpServletResponse response) throws IOException {
        response.sendRedirect("/hello/test1");
    }
    //请求转发
    @RequestMapping("/test3")
    public void test3(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/hello/test1").forward(request,response);
    }
}

SpringMVC

可以通过SpringMVC来实现转发和重定向,也无需视图解析器(配置视图解析器就是指定路径)

@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping("/test1")
    public  String test1(){
        return "/index.jsp";
    }
    //请求转发
    @RequestMapping("/test2")
    public String test2(){
        return "forward:/index.jsp";
    }
    //重定向
    @RequestMapping("/test3")
    public  String test3(){
        return "redirect:/index.jsp";
    }
}

数据处理

处理提交数据

提交域名参数和处理方法的参数名一致

    @RequestMapping("/test1")
    public  String test1(String name){
        System.out.println(name);
        return "/index.jsp";
    }

访问:localhost:8080/hello/test1?name=dengwenxiong,后台获取到参数

提交域名参数和处理方法不一致

    @RequestMapping("/test1")
    public  String test1(@RequestParam("username") String name){
        System.out.println(name);
        return "/index.jsp";
    }

访问:localhost:8080/hello/test1?username=dengwenxiong

提交一个对象

 @RequestMapping("/test1")
    public  String test1(User user){
        System.out.println(user);
        return "/index.jsp";
    }

访问:localhost:8080/hello/test1?id=1&name=dengwenxiong&age=11

提交对象的话,前端传递的参数名和对象名必须是一致的,否则参数为null

数据显示到前端

通过ModelAndView显示

public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception {
     //返回一个模型视图对象
     ModelAndView mv = new ModelAndView();
     mv.addObject("msg","ControllerTest1");
     mv.setViewName("test");
     return mv;
   }
}

通过ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
    //封装要显示到视图中的数据
    //相当于req.setAttribute("name",name);
    model.addAttribute("name",name);
    System.out.println(name);
    return "hello";
} 

通过Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
    //封装要显示到视图中的数据
    //相当于req.setAttribute("name",name);
    model.addAttribute("msg",name);
    System.out.println(name);
    return "test";
}

对比

  • Model只有少量方法适用于存储数据
  • Model Map继承了LinkedMap,除了实现自身的一些方法外,还继承了LinkedMap的方法和特性
  • ModelAndView可以在存储数据的同时设置返回的逻辑视图。

乱码问题

在web.xml配置过滤器即可,SpringMVC提供了一个默认的过滤器

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

 

JSON

JSON:js对象标记

  • 对象表现为键值对
  • 花括号保存对象
  • 方括号保存数组

Json对象转换为JS对象

var obj = JSON.parse('{"a": "Hello", "b": "World"}');
//结果是 {a: 'Hello', b: 'World'}

js对象转换为Json对象

var json = JSON.stringify({a: 'Hello', b: 'World'});
//结果是 '{"a": "Hello", "b": "World"}'

Controller返回JSON字符串

Jackson是目前较好的json解析工具

输出json字符串

导入jar包

<dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.11.4</version>
</dependency>
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/json")
    @ResponseBody
    public String json1() throws JsonProcessingException {
        //创建jackson的对象映射器来解析数据
        ObjectMapper objectMapper=new ObjectMapper();
        User user=new User(1,"dwx",11);
        //将对象解析成json格式
        String string=objectMapper.writeValueAsString(user);
        //@ResponseBody注解,直接返回字符串
        return string;
    }
}

如遇到乱码问题可以通过@RequestMapping的produces属性来设置返回类型和编码格式:

//produces:指定响应体返回类型和编码
@RequestMapping(value = "/json",produces ="application/json;charset=utf-8")

@Controller+@ResponseBody=@RestController

输出时间对象

jackson默认会把时间日期转换为时间戳的形式输出

public String json1() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
//不使用时间戳的方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//自定义日期格式对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//指定日期格式
        mapper.setDateFormat(sdf);
        Date date = new Date();
        String str = mapper.writeValueAsString(date);
        return str;

    }

FastJson

阿里开发的json转换的jar包

导入

<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.28</version>
</dependency>

有三个主要的类:

  • JSONObject:代表json对象,实现了map接口
  • JSONArray:代表json数组,实现了List
  • JSON:代表JSONArray和JSONObject的转化

 AJAX

Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)是一种在无需加载整个网页的情况下,就能更新部分网页的技术。ajax依赖于XMLHttpRequest对象(XHR)

XMLHttpRequest对象:

  • 用于后台与服务器交互数据是一种api
  • 可以在不重新加载页面的情况下更新网页
  • 可以在页面已加载后重服务器请求和接收数据
  • 可以向服务器发送数据

ajax请求的五个步骤:

  • 创建XMLHttpRequest对象
  • 连接服务器
  • 发送请求
  • 服务器响应
  • 接收响应数据

拦截器

SpringMVC的拦截器类似于Servlet中的过滤器,用于对处理器进行预处理和后处理,拦截器只会拦截控制器方法。

自定义拦截器必须实现HandlerInterceptor方法

public class MyInterceptor implements HandlerInterceptor {
    //预处理,返回true就继续执行,返回false不往下执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("处理前");
        return false;
    }
    //后处理
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("处理后");
    }
    //dispatcherServlet处理之后执行,完成一些清理工作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("清理");
    }
}

配置文件配置拦截器

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/*"/>
            <bean class="com.deng.controller.MyInterceptor"></bean>
        </mvc:interceptor>
</mvc:interceptors>

可以使用拦截器实现登录拦截

文件上传,下载

SpringMVC可以很好的支持文件上传,但是其上下文默认没装配MultipartResolver,因此默认情况下不能处理文件上传工作。需要在上下文配置MultipartResolver才能使用文件上传功能

上一篇:SpringMVC笔记(二)


下一篇:Spring MVC系列教材 (六)- SPRING MVC 如何使用Session