springmvc(一)

简介: springmvc(一)

第一章 SpringMVC 概述

1.1 SpringMVC 基本说明

SpringMVC是基于spring的, 是spring中的一个模块,做web开发使用的。 springmvc 叫做spring web mvc

说明他是spring的核心技术, 做web开发,springmvc内部是使用mvc架构模式。


SpringMVC 是一个容器, 管理对象的,使用IoC核心技术。 springmvc管理界面层中的控制器对象。


SpringMVC底层也是Servlet。 以Servlet为核心, 接收请求,处理请求。 显示处理结果给用户。


处理用户的请求:


用户发起请求----SpringMVC—Spring—MyBatis–mysql数据库

1.2 SpringMVC中的核心Servlet – DispatcherServlet

DispatcherServlet 是框架一个Servlet对象。 负责接收请求, 响应处理结果。

DispatcherServlet 他的父类是HttpServlet

DispatcherServlet 也叫做前端控制器( front controller)。


SpringMVC是管理控制器对象, 原来没有SpringMVC之前使用 Servlet作为控制器对象使用。现在通过SpringMVC容器创建一种叫做控制器的对象,代替Servlet行驶控制器的角色。功能。


SpringMVC 主要使用注解的方式, 创建控制器对象, 处理请求。

<servlet>
    <servlet-name>myweb</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--自定义配置文件的位置-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--
       表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
       数值越小,创建对象的时间越早。
    -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>myweb</servlet-name>
    <!--
       url-pattern 作用: 把一些请求交给指定的servlet处理
       使用中央调度器(DispatcherServlet)
       1. 使用扩展名方式, 格式 *.xxx ,  xxx是自定义的扩展名。
          例如  *.do , *.action, *.mvc 等等. 不能使用*.jsp
          http://localhost:8080/myweb/some.do
          http://localhost:8080/myweb/user/list/queryUser.do
          http://localhost:8080/myweb/user/list/list.do
       2. 使用斜杠 "/"
    -->
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

1.3 springmvc请求的处理过程

简单的处理过程:用户发起请求some.do—>Tomcat接收了请求—DispatcherServlet–分配MyController(doSome()返回mv对象)–mv显示给用户了。


省略tomcat


用户some.do--------------DispatcherServlet--------------MyController


如果使用servlet处理请求


用户发起请求--------------------没有其他对象------------------------Servlet

image.png

1.4 复习

用户发起some.do—DispatcherServlet(Servlet接收请求)—转给MyController

public class DispatcherServlet extends HttpServlet{
 public void service(HttpServletRequest request, HttpServletResponse response){
 if(“some.do”.equals(request.getURI())){
 //从容器中获取MyController
 MyController c = ctx.getBean(“some”));
 c.doSome();
 } e lse if( “other.do”.equals(request.getURI())){
 OtherController c = ctx.getBean(“other”));
 c.doOther();
 }
 }
}

1.5 web开发中配置文件的说明

  1. web.xml 部署描述符文件 , 给服务器(tomcat)。
    作用:服务器在启动的时候,读取web.xml ,根据文件中的声明创建各种对象,
  2. 根据文件中的声明 知道 请求和servlet等对象的关系。
  3. 框架的配置文件, springmvc的配置文件
    作用:声明框架创建的项目中的各种对象, 主要是创建Controller对象的
  4. 配置文件的加载顺序和功能
  5. tomcat服务器启动, 读取web.xml. 根据web.xml文件中的说明,创建对象。
<servlet>
        <servlet-name>myweb</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--自定义配置文件的位置-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--
           表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
           数值越小,创建对象的时间越早。
        -->
        <load-on-startup>1</load-on-startup>
    </servlet>

创建DispatcherServlet他的对象, 会执行init()方法。 在init()方法中会执行 springmvc容器对象创建


WebApplicationContext ctx = new ClassPathXmlApplicationContext(“classpath:springmvc.xml”)


springmvc框架, new ClassPathXmlApplicationContext()读取springmvc的配置文件。

 <context:component-scan base-package="com.bjpowernode.controller" />
    <!--声明视图解析器:帮助处理视图-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:指定视图文件的路径-->
        <property name="prefix" value="/WEB-INF/view/" />
        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp" />
    </bean>

使用组件扫描器base-package=“com.bjpowernode.controller” ,遍历controller包中的所有类,MyController类, 找到这个类中的@Controller, @RequestMapping注解, 就能创建MyContoller对象。


知道some.do的请求是执行doSome()方法


以上 1, 2. 都是项目启动的过程, 没有执行任何的用户请求。


用户发起请求some.do----DispatcherServlet


DispatcherServlet里面有 WebApplicationContext 。 WebApplicationContext 里面有MyController对象。


请求some.do ,DispatcherServlet 就知道是 MyController处理的。

1.6 SpringMVC内部的执行流程

springmvc内部请求的处理过程:


用户发起请求给DispatcherServlet


DispatcherServlet把请求(request)交给了 处理器映射器。


处理器映射器: springmvc框架中的对象, 需要实现HandlerMapping接口。


映射器作用: 从springmvc容器中,获取控制器对象(MyController),把找到的控制器和拦截器对象都放到 处理器执行链对象中,保存,并返回给中央调度器。(MyController controller = ApplicationContext.getBean())

DispatcherServlet把获取到的处理器执行链中的控制器对象,交给了处理器适配器


处理器适配器:是springmvc框架中的对象, 实现HandlerAdapter接口。


适配器作用: 执行控制器的方法, 也就是执行MyController.doSome()方法。得到结果ModelAndView


DispatcherServlet把控制器执行结果mv交给了 视图解析器


视图解析器: springmvc中的对象,需要实现ViewResolver接口。


视图解析器作用: 处理视图的, 组成视图的完整路径。 能创建View类型的对象


DispatcherServlet调用View类的方法, 把Model中的数据放入到request作用域。 执行request.setAttribute(), 对视图执行forward()转发行为, request.getRequestDispather(“/show.jsp”).forward(request,response)

第二章 SpringMVC 注解式开发

2.1 @RequestMapping注解的使用。

属性: value 请求的uri地址。

位置: 1) 在方法的上面, 必须的。 2)在类的上面作为模块名称

@RequestMapping(value ="/some.do")
public ModelAndView doSome(){

属性 method 请求的方式, 使用RequestMehtod类的枚举,表示请求方式

@RequestMapping(value ="/other.do",method = RequestMethod.POST)
public ModelAndView doOther(){

2.2 接收请求中的参数

对应HttpServletRequest, HttpServletResponse, HttpSession 只需要在控制器方法的形参列表中,定义就可以了。框架会给参数赋值, 在控制器方法内部可以直接使用 request,response,session参数。


400 : http status , 表示客户端异常。 主要是发生在用户提交参数过程中。


接收请求中的参数: 逐个接收, 对象接收

2.2.1 逐个接收

逐个接收: 请求中的参数名和控制器方法的形参名一样。按照名称对象接收参数

<p>逐个接收请求参数</p>
<form action="receive-property.do" method="post">
    姓名:<input type="text" name="name"> <br/>
    年龄:<input type="text" name="age"> <br/>
    <input type="submit" value="提交参数">
</form>

Controller接收参数

@RequestMapping(value ="/receive-property.do")
public ModelAndView doPropertyParam(String name, Integer age) {} 

接收参数的问题:

  1. 参数最好使用包装类型。 例如Integer ,能接收空值情况, 接收的是null
  2. 框架可以使用String到int ,long, float, double等类型转换。
  3. post请求中有乱码的问题, 使用字符集过滤器。

2.2.2 CharacterEncodingFilter使用:

在web.xml 声明过滤器
 <filter>
        <filter-name>characterEncodingFilter</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>
        <init-param>
            <!--强制请求(request)对象使用encoding的编码方式-->
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <!--强制应答(response)对象使用encoding的编码方式-->
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <!--强制所有请求,先经过过滤器处理-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2.2.3 请求中参数名和形参名不一样,使用@RequestParam

/**
 * 逐个接收请求参数, 请求中参数名和形参名不一样
 * @RequestParam : 解决名称不一样的问题
 *       属性: value 请求中的参数名称
 *              required : boolean类型的,默认是true
 *                    true:请求中必须有此参数,没有报错。
 *                    false:请求中可以没有此参数。
 *       位置: 在形参定义的前面
 */
@RequestMapping(value ="/receive-param.do")
public ModelAndView doReceiveParam(
    @RequestParam(value = "rname",required = false) String name,
    @RequestParam(value = "rage",required = false) Integer age) { }

2.2.4 对象接收

对象接收: 在控制器方法的形参是java对象, 使用java对象的属性接收请求中参数值。

要求: java对象的属性名和请求中参数名一样。

例子:

 */
public class Student {
    // 属性名和请求中参数名一样
    private String name;
    private Integer age;
    // set| get方法
}
 @RequestMapping("/receive-object.do")
 public ModelAndView doReceiveObject(Student student){
    System.out.println("MyController的方法doReceiveObject="+student);
    ModelAndView mv = new ModelAndView();
    mv.addObject("myname", student.getName());
    mv.addObject("myage", student.getAge());
    mv.setViewName("show");
    return mv;
}

2.3 控制器方法的返回值

控制器方法的返回值表示本次请求的处理结果,返回值有ModelAndView, String, void , Object

请求的处理结果包含: 数据和视图。

2.3.1 ModelAndView 数据和视图

请求的结果有数据和视图,使用ModelAndView最方便

数据:存放request作用域。

视图:执行forward转发操作

2.3.2 String 视图

框架对返回值是String,执行的是forward转发操作。

视图可以表示为完整视图路径, 或者视图的逻辑名称

@RequestMapping(value ="/return-string-view.do")
public String doReturnStringView1(HttpServletRequest request,String name, Integer age) {
        System.out.println("执行了MyController的doReturnStringView1方法name=");
        //返回结果,forward,转发到show.jsp
        //逻辑名称, 需要配置视图解析器
        return "show";
}
@RequestMapping(value ="/return-string-view2.do")
public String doReturnStringView2(HttpServletRequest request,String name, Integer age) {
    System.out.println("执行了MyController的doReturnStringView2方法name=");
    //完整视图路径,不能使用视图解析器
    return "/WEB-INF/view/show.jsp";
}

2.3.3 void 没有数据和视图

void: 没有数据和视图, 可以使用HttpServletResponse对象输出数据,响应ajax请求。

2.3.4 Object

返回Student 表示数据,还是视图。 所以控制器方法返回对象Object, 用来响应ajax请求。


返回对象Object ,可以是List, Student , Map ,String ,Integer… 这些都是数据, 而ajax请求需要的旧是数据。 在ajax请求中,一般需要从服务器返回的是json格式的数据, 经常要处理java对象到json的转换。而且还需要输出数据响应ajax请求。 框架提供了处理 java对象到json转换, 还是数据输出工作。

2.3.4.1 HttpMessageConverter 消息转换器

HttpMessageConverter 接口,作用是 1)实现请求的数据转为java对象, 2) 把控制器方法返回的对象转为json,xml,text,二进制等不同格式的数据。

public interface HttpMessageConverter<T> {
   /**
      作用: 检查clazz这个类型的对象,能否转为 mediaType表示的数据格式
            如果能转为mediaType表示的类型, 返回true, 返回true调用read()
    */
   boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
   /**
      作用: 接收请求中的数据,把数据转为 clazz表示的对象
    */
   T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
         throws IOException, HttpMessageNotReadableException;
   /**
      作用:检查clazz这种数据类型,能否转为mediaType表示的数据格式
    */
   boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
   /**
      作用: 把t对象,按照contentType说明的格式,把对象转为json或者xml
    */
   void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
         throws IOException, HttpMessageNotWritableException;
}

MediaType:媒体类型,表示互联网中数据的格式。例如application/json, text/html, image/gif

HttpMessageConverter 接口的实现类:
MappingJackson2HttpMessageConverter : 用jackson工具库的ObjectMapper把java对象转为json数据格式
StringHttpMessageConverter : 把字符串类型的数据,进行格式转换和编码

怎么使用实现类:

框架根据控制器方法的返回类型, 自动查找使用的实现类。

@RequestMapping("/receive-object.do")
public Student doReceiveObject(String name,Integer age){
    System.out.println("MyController的方法doReceiveObject=");
    Student student = new Student();
    student.setName("lisi");
    student.setAge(20);
    return student;
}

默认情况下: springmvc使用了HttpMessageConveter接口的4个实现类。包括了StringHttpMessageConverter.


需要在springmvc的配置文件,加入注解驱动的标签 mvc:annotation-driven. 加入这个标签后, springmvc项目启动后,会创建HttpMessageConveter接口的7个实现类对象,包括StringHttpMessageConverter 和 MappingJackson2HttpMessageConverter。


2.3.4.2 @ResponseBody

@ResponseBody注解的作用,就是把student转换后的json通过HttpServletResponse对象输出给浏览器。

//输出json,响应ajax
response.setContentType("application/json;charset=utf-8");
PrintWriter pw  = response.getWriter();
pw.println(json);
pw.flush();
pw.close();
@ResponseBody注解作用就上面的代码的实现

2.3.4.3 控制器方法返回对象转为json的步骤

1)pom.xml加入jackson依赖,springmvc框架,默认处理json就是使用jackson


2)在springmvc的配置文件中,加入注解驱动的标签mvc:annotation-dirven


在控制器方法的上面加入@ResponseBody注解,表示返回值数据,输出到浏览器。

2.4 静态资源处理

访问地址:


当web.xml中DispatcherServlet的url-pattern是 *.do


http://localhost:8080/ch05_url_pattern/index.jsp tomcat


http://localhost:8080/ch05_url_pattern/js/jquery-3.4.1.js tomcat


http://localhost:8080/ch05_url_pattern/images/p1.jpg tomcat


http://localhost:8080/ch05_url_pattern/html/test.html tomcat


http://localhost:8080/ch05_url_pattern/some.do DispatcherServlet(springmvc框架)

2.4.1 tomcat的default servlet

tomcat安装目录/conf/web.xml

 <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>
default 叫做默认servlet ,作用:
1.它提供静态资源的处理
2.它处理所有未映射到其他请求的请求处理

2.4.2 中央调度器设置 “/”

http://localhost:8080/ch05_url_pattern/index.jsp tomcat 成功访问


http://localhost:8080/ch05_url_pattern/js/jquery-3.4.1.js 404 没有对应的控制器对象


http://localhost:8080/ch05_url_pattern/images/p1.jpg 404 没有对应的控制器对象


http://localhost:8080/ch05_url_pattern/html/test.html 404 没有对应的控制器对象


http://localhost:8080/ch05_url_pattern/some.do 200 MyController

    使用斜杠 "/" . 导致中央调度器称为了默认的default servlet。
    需要处理静态资源和其他的未映射的请求。  默认中央调度器没有处理
    静态资源的控制器对象, 所以静态资源都是 404 。 some.do这个请求
    有MyController对象, 所以能访问。
    如果项目中 , 中央调度器设置了“/” , 动态资源能访问,静态资源不能访问。
    需要处理静态资源的访问工作。

2.4.3 第一种方式处理静态资源

在springmvc的配置文件加入 mvc:default-servlet-handler标签, springmvc框架会在项目运行时,加入DefaultServletHttpRequestHandler对象,让这个对象处理静态资源的访问。

<!--声明注解驱动
    default-servlet-handler和@RequestMapping使用有冲突
-->
<mvc:annotation-driven />
<!--声明静态资源的第一种处理方式
    创建DefaultServletHttpRequestHandler处理静态资源。
    DefaultServletHttpRequestHandler把接收的静态资源的地址,转发给了tomcat的default
    优点:
      解决方式简单
    缺点:
      依赖tomcat服务器提供的能力。
-->
<mvc:default-servlet-handler />

2.4.4 第二种静态资源的处理方式

在springmvc配置文件中加入一个 mvc:resources标签, 框架会创建ResourceHttpRequestHandler控制器对象, 使用这个对象处理静态资源的访问。 不依赖tomcat服务器。 推荐使用的。

 <!--声明注解驱动
        resources和@RequestMapping使用有冲突
    -->
    <mvc:annotation-driven />
    <!--声明静态资源的第二种处理方式
        mapping: 访问静态资源的uri地址, 可以使用通配符(**)。
                  ** : 表示任意的目录和目录和资源名称
        location: 静态资源在项目中的位置, 不要使用/WEB-INF目录
    -->
    <mvc:resources mapping="/images/**" location="/images/" />
    <mvc:resources mapping="/html/**" location="/html/" />
    <mvc:resources mapping="/js/**" location="/js/" />
    <!--一句话设置静态资源-->
    <!--<mvc:resources mapping="/static/**" location="/static/" />-->


相关文章
|
前端开发 Java 程序员
|
前端开发 Java 数据处理
|
2月前
|
Java 数据库连接 数据库
SpringMVC(2)
SpringMVC(2)
|
6月前
|
JSON 前端开发 Java
|
5月前
|
前端开发 Java Maven
SpringMVC(一)(1)
SpringMVC(一)(1)
25 0
|
5月前
|
前端开发 Java 数据格式
SpringMVC(三)
SpringMVC(三)
18 0
|
6月前
|
前端开发 Java 应用服务中间件
|
前端开发 应用服务中间件
SpringMVC4
SpringMVC4
45 0
|
7月前
|
存储 JSON 前端开发
|
7月前
|
XML 前端开发 Java
SpringMvc专题
SpringMvc笔记(持续更新)此方法的执行时机是在控制器方法执行之前,所以我们通常是使用此方法对请求部分进行增强。同时由于结果视图还没有创建生成,所以此时我们可以指定响应的视图。