Spring MVC 02:MVC的使用与接收参数


Spring MVC 02:MVC的使用与接收参数

示例程序:HelloWorld(xml形式)

1.新建一个maven工程 : webapp

2.配置pom.xml依赖

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.13.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.0</version>
    </dependency>
    <!--jsp的支持-->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

3.在Java目录下写Controller:HelloWorldController

package cn.silverCorridors;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        System.out.println("Hello,Spring MVC world"); // 控制台输出信息
        return new ModelAndView("/Jsp/HelloWorld.jsp"); // 向browser返回这个目录下的jsp文件
    }
}

4.注册处理器:在resources目录下配置SpringMVC.xml

<beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:context = "http://www.springframework.org/schema/context"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc = "http://www.springframework.org/schema/mvc"
       xsi:schemaLocation = "
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <bean name="/hello" class="cn.silverCorridors.HelloWorldController"></bean>

</beans>

5.配置中央调度器web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</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>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

<servlet/>中添加<Load-on-startup/>的作用是,,标记是否在Web服务器(这里是Tomcat) 启动时会创建这个 Servlet 实例,即是否在 Web 服务器启动时调用执行该 Servlet 的 init()方法,而不是在真正访问时才创建。它的值必须是一个整数。

  • 当值大于等于 0 时,表示容器在启动时就加载并初始化这个 servlet,数值越小,该 Servlet的优先级就越高,其被创建的也就越早;
  • 当值小于 0 或者没有指定时,则表示该 Servlet 在真正被使用时才会去创建。
  • 当值相同时,容器会自己选择创建顺序。

对于<url-pattern/>,可以写为 / ,建议写为*.do 的形式。

6.在webapp下新建一个Jsp文件夹,创建HelloWorld.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    Hello,Spring MVC World JSP!


输出结果

输出结果

示例程序:HelloWorld(annotation形式)

注册组件扫描器: 指定处理器所在的包

注册视图解析器:ResourceViewResolver,指定视图所在位置

<beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:context = "http://www.springframework.org/schema/context"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc = "http://www.springframework.org/schema/mvc"
       xmlns:p = "http://www.springframework.org/schema/p"
       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-3.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!--扫描包-->
    <context:component-scan base-package="cn.silverCorridors"></context:component-scan>
    
    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置视图 前缀:prefix  后缀:suffix-->
        <property name="prefix" value="/Jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
  • @Controller:表示当前类为处理器
  • @RequestMapping:表示当前方法为处理器方法。该方法要对 value 属性所指定的 URI 进行处理与响应。被注解的方法的方法名可以随意。通过@RequestMapping 注解可以定义处理器对于请求的映射规则。该注解可以注解在方法上,也可以注解在类上,但意义是不同的。value 属性值常以“/”开始,也可不加“/”。

在类上使用@RequestMapping(掌握)

@RequestMapping 的 value 属性用于定义所匹配请求的 URI。但对于注解在方法上与类上,其 value 属性所指定的 URI,意义是不同的。

一个@Controller 所注解的类中,可以定义多个处理器方法。当然,不同的处理器方法所匹配的 URI 是不同的。这些不同的 URI 被指定在注解于方法之上的@RequestMapping 的value 属性中。但若这些请求具有相同的 URI 部分,则这些相同的 URI,可以被抽取到注解在类之上的@RequestMapping 的 value 属性中。此时的这个 URI 表示模块的名称。URI 的请求是相对于 Web 的根目录。

换个角度说,要访问处理器的指定方法,必须要在方法指定 URI 之前加上处理器类前定义的模块名称。

Model 中的数据存储在 request 作用域中,SringMVC 默认采用转发的方式跳转到视图,本次请求结束,模型中的数据被销毁。若有多个请求路径均可匹配该处理器方法的执行,则@RequestMapping 的 value 属性中可以写上一个数组。

package cn.silverCorridors;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping(value = "/helloworld2") // 类级别注解
public class HelloWorld2 {
    //@RequestMapping(value = "/helloworld2/hello2")
    @RequestMapping(value = "/hello2",method = {RequestMethod.POST,RequestMethod.GET},params = {"a=5"}) // method:设置可接受访问请求的类型,params设置参数(访问时必须要加参数)
    public String sayHello() {
        System.out.println("Hello, Spring MVC world2");
        return "HelloWorld"; // 前缀 后缀不用写,视图解析器帮你找
    }
    //@RequestMapping(value = "/helloworld2/hello3")
    @RequestMapping(value = "/hello3")
    public String sayHello2() {
        System.out.println("Hello, Spring MVC world3");
        return "HelloWorld"; // 前缀 后缀不用写,视图解析器帮你找
    }
}

问题:利用PostMan发送POST请求中的中文乱码

package cn.silverCorridors;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/param")
public class Parameters {

    // /param/test1?a=5&b=6&c=888.0
    @RequestMapping("/test1")
    public String test1(String a, String b, String c) {// 获取请求访问中的参数,自动匹配
        System.out.println("test1()");
        System.out.println("a=" + a);
        System.out.println("b=" + b);
        System.out.println("c=" + c);
        return "HelloWorld";
    }

    // /param/test2?a=5&b=6&c=888.0
    @RequestMapping("/test2")
    public String test2(Pabc pabc) {// 自动组装
        System.out.println("test2()");
        System.out.println(pabc);
        return "HelloWorld";
    }

    // /param/test3?a=5&b=true&c=888.6
    @RequestMapping("/test3")
    public String test2(Integer a, Boolean b, Double c) {// 自动组装
        System.out.println("test2()");
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("c = " + c);
        return "HelloWorld";
    }

    // /param/test4?a=5&b=6&c=888.0&pd.d1=aaa&pd.d2=bbb
    @RequestMapping("/test4")
    public String test4(Pabc1 pabc) {// 自动组装
        System.out.println("test4()");
        System.out.println(pabc);
        return "HelloWorld";
    }
}

POST MAN

输出结果

可以看到输出结果中出现了中文的乱码问题。

解决办法:通过filter实现URI编码转换

在web.xml中添加filter、filterMapping

 <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>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern><!-- 所有目录下都执行这个filter -->
  </filter-mapping>
  

问题解决:

image-20220712124603281

请求中写集合对象的格式: List/Map的例子

/param/test4?a=5&b=6&c=888.0&pd.d1=aaa&pd.d2=b56b&listPd[0].d1=d1d1&listPd[0].d2=aabb&listPd[1].d1=5656&listPd[1].d2=132421&MapPd[one].d1=asdf&MapPd[one].d2=aaadf

自定义转换器

例如在请求方法中我们需要传递一个Date类型的数据

@RequestMapping("/test6")
public String test5(Date a) {
    System.out.println("test6()");
    System.out.println(a);
    return "HelloWorld";
}

在postman里发送请求发现只能按照特定格式输入

只能以这种形式输入

我们通过配置Converter来解决这个问题

Converter格式:

package cn.silverCorridors;
import org.springframework.core.convert.converter.Converter;
// S为转换前,T为转换后
public class SpringToDateConverter implements Converter<S,T> {
    @Override
    public T convert(S s) {
        return null;
    }
}

具体的类:SpringToDateConverter

public class SpringToDateConverter implements Converter<String,Date> {
    @Override
    public Date convert(String s) {
        if (null == s){
            throw  new RuntimeException("s cannot be null.");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return df.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("Parse Error!");
        }
    }
}

将Converter配置到SpringMVC.xml

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="cn.silverCorridors.SpringToDateConverter"></bean>
        </set>
    </property>
</bean>
<!--    通知给MVC配置了conversion-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

此时配置成功

输入

结果

参考资料

SpringMVC常见面试题总结

SpringMVC注解式开发项目


文章作者: 银色回廊
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 银色回廊 !
评论
  目录