IDEA项目实践——springMVC概述

news2024/11/18 23:32:08

系列文章目录

动力节点Java项目的开发原则与核心业务介绍

IDEA项目实践——JavaWeb简介以及Servlet编程实战

IDEA项目实践——Spring当中的切面AOP

IDEA项目实践——Spring框架简介,以及IOC注解

IDEA项目实践——动态SQL、关系映射、注解开发

IDEWA项目实践——mybatis的一些基本原理以及案例

IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介

文章目录

系列文章目录

前言

第1章 SpringMVC概述

1.1 SpringMVC简介

1.2 SpringMVC的优点

1. 基于MVC 架构

2. 容易理解,上手快,使用简单

3. 作为Spring框架一部分,能够使用Spring的IOC和AOP

4. SpringMVC 强化注解的使用

5.可适配性好

1.3 SpringMVC优化的方向

1.4 SpringMVC执行的流程

1.5 基于XML的SpringMVC程序

1)新建maven_web项目

2)添加依赖

3)删除web.xml文件重新添加

4)在web.xml中配置DispatcherServlet核心控制器

5)编写一个Controller类

6)完成springmvc.xml文件的配置。

7)删除index.jsp页面,重新建index.jsp页面

8)在webapp/WEB-INF目录上新添目录/jsp。

9)在/jsp目录下新建main.jsp页面。

10)运行项目

1.6 基于注解的SpringMVC程序

1)新建maven_web项目

2)添加依赖

3)配置web.xml

4)配置springmvc.xml,需要配置组件扫描器

5)创建控制器,无须实现任何接口

6)index.jsp和main.jsp

7)运行项目

第2章 SpringMVC注解式开发

2.1 @Controller

2.2 @RequestMapping定义请求规则

2.2.1 指定模块名称

2.2.2 对请求提交方式的定义

(1) post提交方式

(2) get提交方式

2.3 数据提交的方式

(1)单个数据(基本数据类型)注入

(2)对象封装注入

(3)动态占位符提交/路径变量(仅用于超链接)

中文乱码:

(4)请求参数名称与形参名称不一致

(5)数组类型的请求参数

(6)使用HttpServletRequest对象提取

2.4 请求参数中文乱码解决

(1)解决方案

(2)源码分析

2.5 处理器方法的返回值

2.5.1 返回 ModelAndView

2.5.2 返回 String

2.5.3 无返回值void

2.5.4 返回对象Object

总结


前言

本文主要介绍springMVC,介绍起注解开发与xml开发。

servlet图解

第1章 SpringMVC概述

1.1 SpringMVC简介

SpringMVC 也叫Spring web mvc。是Spring 框架的一部分,是在Spring3.0 后发布的。

控制层的优化

1.2 SpringMVC的优点

1. 基于MVC 架构

基于 MVC 架构,功能分工明确。解耦合。

2. 容易理解,上手快,使用简单

就可以开发一个注解的 SpringMVC 项目,SpringMVC 也是轻量级的,jar 很小。不依赖的特定的接口和类。

3. 作为Spring框架一部分,能够使用Spring的IOC和AOP

方便整合Strtus,MyBatis,Hiberate,JPA 等其他框架。

4. SpringMVC 强化注解的使用

在Controller, Service, Dao 都可以使用注解。方便灵活。使用@Controller 创建处理器对象,@Service 创建业务对象,@Autowired 或者@Resource 在控制器类中注入 Service,在Service 类中注入 Dao。

5.可适配性好

可适配性好,通过HandlerAdapter就可以支持任意一个类作为处理器。

1.3 SpringMVC优化的方向

1.4 SpringMVC执行的流程

执行流程说明:

  1. 向服务器发送HTTP请求,请求被前端控制器 DispatcherServlet 捕获。

  2. DispatcherServlet 根据<servlet-name>中的配置对请求的URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用 HandlerMapping 获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回。

  3. DispatcherServlet 根据获得的Handler,选择一个合适的 HandlerAdapter。

  4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。

数据转换:对请求消息进行数据转换。如String转换成Integer、Double等。

数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。

数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。

  1. Handler(Controller)执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象。

  2. 根据返回的ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet。

  3. ViewResolver 结合Model和View,来渲染视图。

  4. 视图负责将渲染结果返回给客户端

1.5 基于XML的SpringMVC程序

项目案例功能:用户提交一个请求,服务端处理器在接收到这个请求后,给出一条欢迎信息,在响应页面中显示该信息,采用传统的配置式开发方式。

xml的方式较为繁琐,实际开发使用1.6 注解的方式

创建步骤:

1)新建maven_web项目

2)添加依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.26</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <!--切记要加scope,否则tomcat插件启动时会报错-->
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>

3)删除web.xml文件重新添加

因为自动生成的web.xml文件版本太低了。

4)在web.xml中配置DispatcherServlet核心控制器

url-pattern设置为"/"表示, 客户端发出的所有请求都会被DispatcherServlet核心控制器(中央调度器)拦截, DispatcherServlet再交给springmvc.xml进行处理,springmvc.xml接下来会 为客户端的url请求找到对应的控制器Controller类进行处理。

如果<url-pattern>*.do</url-pattern>,则表示拦截以“.do”结尾的URL请求。

中央调度器的全限定性类名在导入的 Jar 文件 spring-webmvc-x.x.x.RELEASE.jar 的第一个包org.springframework.web.servlet下可找到。

<!--配置核心控制器(中央调度器)-->
 <servlet>
     <servlet-name>springmvc</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>
 </servlet>
 <servlet-mapping>
     <servlet-name>springmvc</servlet-name>
     <url-pattern>/</url-pattern>
 </servlet-mapping>

<param-value>classpath:springmvc.xml</param-value>表示从类路径下加载SpringMVC的配置文件。

<init-param>节点是可选项,可以省略。

问题来了,Spring拦截所有的请求后,下一步交给谁进行解释呢,即到哪里找Spring MVC配置文件呢?答案是应用程序在启动时会默认到WEB-INF目录下查找命名格式为“ServletName-servlet.xml”的MVC配置文件。

其中ServletName应与web.xml中的<servlet-name>中的一致。

此外核心配置器还可选用<load-on-startup>1</load-on-startup>表示Servlet容器在服务器启动时立即加载。如果没有这条配置,则表示应用程序在第一个Servlet请求时加载该Servlet。

 选择第四个

 

5)编写一个Controller类

在com.foxbill.controller包下,新建一个FirstController,实现Controller接口。

 完整代码:

package com.ambow.controller;

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 FirstController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mav = new ModelAndView();
        //作用域里面加入属性,属性名称为Hello,属性值为后面的内容
        mav.addObject("hello","Hello My First SpringMVC!");
        //设置视图
        mav.setViewName("main");//逻辑视图 --->  /WEB-INF/jsp/main.jsp
        return mav;
    }
}

FirstController -->控制器(相当于以前的servlet)

类中的方法的作用:创建一个ModelAndView对象,在对象中添加一个名叫“hello”的字符串对象,并设置逻辑视图为main。这个逻辑视图本身还不是完整的视图路径,将在下述有关步骤(视图解析器)进一步解释为完整路径。

此方法意味着程序将携带hello对象数据,跳转到名为main的逻辑视图。

6)完成springmvc.xml文件的配置。

在工程的类路径即resources目录下创建 SpringMVC 的配置文件 springmvc.xml。该文件名可以任意命名。推荐使用springmvc.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--1.配置处理器映射器,确定一种请求-相应的映射规则-->
     <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
     <!--2.配置处理器适配器,配置对处理器的handleRequest()方法的调用-->
     <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
     <!--3.配置自定义控制器,一条具体的映射关系,name对应客户端URL请求,class对应服务端响应程序-->
     <bean name="/first" class="com.foxbill.controller.FirstController" />
 ​
     <!--上述类型的1.处理器映射器是默认的,同样上述类型的2.处理器适配器也是默认的,两者均可省略不要-->
 ​
     <!--4.配置视图解析器-->
     <!--说明:视图解析器不是必须的,如果没有,则控制层的返回值需要从"main"改为"/WEB-INF/jsp/main.jsp",即必须写完整路径的视图名称。-->
     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/jsp/"></property>
         <property name="suffix" value=".jsp"></property>
     </bean>
 </beans>

(1)配置处理器映射器

创建一种类型为BeanNameUrlHandlerMapping的处理器映射器,即定义一种“请求/响应”映射规则,客户端的URL请求如果跟某一个Bean的name属性匹配,则由该Bean的class属性指定的控制器Controller类进行响应处理。

(2)配置处理器适配器

创建一种处理器适配器,类型为SimpleControllerHandlerAdapter,用于对上述指定的控制器Controller类的handleRequest()方法的调用与执行

(3)配置自定义控制器

定义一条具体的“请求/响应”映射关系,表示假如客户端发出的URL请求的是/first,则指定由服务端的com.foxbill.controller.FirstController来处理,通过这行代码确定了一条具体的“请求/响应”映射关系,是一对一的对应关系,即name属性对应客户端URL请求,class对应服务端响应程序

【注意:这个Bean的配置要有效,前提是要配置类型为BeanNameUrlHandlerMapping的映射器和类型为SimpleControllerHandlerAdapter的适配器,它们相当于制定了一个规则,如乒乓球比赛的“男女混合双打”,而自定义控制器则是这个规则下的具体某某男和某某女进行配对,进行混合双打。】

(4)配置视图解析器

视图解析器用来解析控制器返回的逻辑视图的真实路径,这样更方便,易于扩展。

视图解析器不是必须的,如果没有,则控制层的返回值需要从"main"改为"/WEB-INF/jsp/main.jsp",即必须写完整路径的视图名称。

上述类型的处理器映射器是默认的,同样上述类型的处理器适配器也是默认的,两者均可省略不要,因此springmvc.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--1.配置自定义控制器,一条具体的映射关系,name对应客户端URL请求,class对应服务端响应程序-->
     <bean name="/first" class="com.foxbill.controller.FirstController" />
 ​
     <!--2.配置视图解析器-->
     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/jsp/"></property>
         <property name="suffix" value=".jsp"></property>
     </bean>
 </beans>

添加了前缀prefix与后缀suffix 

7)删除index.jsp页面,重新建index.jsp页面

因为自动生成的页面缺失指令设置。

开发页面,发出请求。

<a href="${pageContext.request.contextPath}/first">访问控制器FirstController</a>

完整的代码段:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
      <%-- 此处根据EL表达式来获取项目的虚拟路径,即项目名称 此处为动态获取,即便项目名称改变了也可以获取到--%>
      <a href="${pageContext.request.contextPath}/first">访问控制器FirstController</a>
  </body>
</html>

8)在webapp/WEB-INF目录上新添目录/jsp。

 

9)在/jsp目录下新建main.jsp页面。

用来进行服务器处理完毕后数据的回显。

在<body></body>之间输入如下代码:

 <h1>${hello}</h1>

完整代码段: 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--此处为EL表达式,获取到FirstController里方法的属性名称,获取里面的内容--%>
    <h1>${hello}</h1>
</body>
</html>

10)运行项目

先将页面置到first页面,点击请求,就会去找firstcontroller,找到之后,通过适配器处理请求,执行handerRequest方法,返回mav对象,告诉访问的页面是main页面,之后main页面取出Hello里面的内容并且在页面显示。

 

1.6 基于注解的SpringMVC程序

所谓 SpringMVC 的注解式开发是指,在代码中通过对类与方法的注解,便可完成处理器在 springmvc 容器的注册。注解式开发是重点。

项目案例功能:用户提交一个请求,服务端处理器在接收到这个请求后,给出一条欢迎信息,在响应页面中显示该信息。

创建步骤:

1)新建maven_web项目

同上

2)添加依赖

此处比上一个项目,多了一个aop的依赖。

 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-aop</artifactId>
     <version>5.3.26</version>
 </dependency>

3)配置web.xml

配置方法及内容同上。

4)配置springmvc.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
     <!--1.配置组件扫描器-->
     <context:component-scan base-package="com.foxbill.controller" />
 ​
     <!--2.配置视图解析器-->
     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/jsp/"></property>
         <property name="suffix" value=".jsp"></property>
     </bean>
 ​
 </beans>

与配置式开发的相比,少了一大堆配置,无须配置处理器映射器和处理器适配器,但问题来了,“请求/响应”的映射关系在哪定义呢?客户端的URL请求从哪里可以找到对应的服务端处理器来处理呢?可以发现上面代码中多了一个配置组件扫描器,表示通过扫描指定的包下面的类中的注解从而获取映射关系。

5)创建控制器,无须实现任何接口

代码如下:

 package com.foxbill.controller;
 ​
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.servlet.ModelAndView;
 ​
 @Controller
 public class FirstController {
     @RequestMapping("/first")
     public ModelAndView doHello() {
         ModelAndView mav = new ModelAndView();
         mav.addObject("hello","Hello My First SpringMVC!");
         mav.setViewName("main");
         return mav;
     }
 }

第一个注解@Controller表示将本类定义为一个控制器类,这个无须再实现Controller接口。

第二个注解@RequestMapping("/first")表示定义一种“请求/响应”的映射关系,即如果客户端浏览器发出“/first”的URL请求,则由该注解下面的doHello()方法来响应。即客户端的请求,被映射到控制器类的方法上,大大减少了配置工作量。

6)index.jsp和main.jsp

同上

7)运行项目

第2章 SpringMVC注解式开发

2.1 @Controller

传统的配置式开发中的控制器Controller类必须实现Controller接口,并实现接口中的HandleRequest()方法,还需要再配置文件中配置处理器映射,且一个处理器(控制器)只能有一个方法,为了实现程序功能,不得不创建大量的处理器(控制器)类,不够方便灵活。

而,注解开发中,将一个普通的类转化为控制器类只需要在该类的声明上添加@Controller注解即可。一个基于注解的控制器可以有多个方法,能大大减少处理器(控制器)类的数量。

要使注解被扫描到,必须在springmvc.xml中配置组件扫描器,代码如下:

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

2.2 @RequestMapping定义请求规则

基于注解的控制器无须在xml配置文件中配置处理器映射器,仅需要用@RequestMapping对应控制器类中任意一个方法进行注解即可建立“请求/响应”映射关系,将客户端请求与处理器的方法一一对应。

通过@RequestMapping 注解可以定义处理器对于请求的映射规则。该注解可以注解在方法上,也可以注解在类上,但意义是不同的。value 属性值常以“/”开始。@RequestMapping 的 value 属性用于定义所匹配请求的 URI。

2.2.1 指定模块名称

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

//基于注解开发可以直接在这个里面写其他的方法
@Controller
//将所有的类路径写在前面,解决不同模块相同方法的冲突
//实例
@RequestMapping("/student")

示例:

 

提取后

@Controller
@RequestMapping("/zar")
public class HelloSpringMvc {
    //相当于一个控制器处理的方法
    @RequestMapping("/hello")
    public String one() {
        return "main";
    }
    @RequestMapping("/two")
    public String two() {
        return "main";
    }
//客户端的请求:
// <form action="${pageContext.request.contextPath}/zar/hello.action">
    // <form action="${pageContext.request.contextPath}/zar/two.action">
}

2.2.2 对请求提交方式的定义

对于@RequestMapping,其有一个属性 method,用于对被注解方法所处理请求的提交方式进行限制,即只有满足该 method 属性指定的提交方式的请求,才会执行该被注解方法。Method 属性的取值为 RequestMethod 枚举常量。常用的为 RequestMethod.GET 与RequestMethod.POST,分别表示提交方式的匹配规则为 GET 与 POST 提交。

@RequestMapping(value = "/hello",method = RequestMethod.POST)
public String one() {
	return "main";
}

以上处理器方法只能处理 POST 方式提交的请求。

客户端浏览器常用的请求方式,及其提交方式有以下几种:

也就是说,只要指定了处理器方法匹配的请求提交方式为 POST,则相当于指定了请求发送的方式:要么使用表单请求,要么使用 AJAX 请求。其它请求方式被禁用。

当然,若不指定 method 属性,则无论是 GET 还是 POST 提交方式,均可匹配。即对于请求的提交方式无要求。 

(1) post提交方式

(2) get提交方式

 

2.3 数据提交的方式

前四种数据注入的方式,会自动进行类型转换。但无法自动转换日期类型。

(1)单个数据(基本数据类型)注入

在方法中声明一个和表单提交的参数名称相同的参数,由框架按照名称直接注入。

(2)对象封装注入

在方法中声明一个自定义的实体类参数,框架调用实体类中相应的setter方法注入属性值,只要保证实体类中成员变量的名称与提交请求的name属性值一致即可。

 

  • 实体Bean含对象属性

比如:Student对象,其中有一个Address的对象属性,在Address对象中有country和city两个基本类型的属性。

    <form action="${pageContext.request.contextPath}/objectParam" method="post">
        <fieldset>
            <legend>对象数据提交</legend>
            姓名:<input type="text" name="stuname" /> <br />
            年龄:<input type="text" name="stuage" /> <br />
            国家:<input type="text" name="address.country" /> <br />
            城市:<input type="text" name="address.city" /> <br />
            <input type="submit" value="提交">
        </fieldset>
    </form>

(3)动态占位符提交/路径变量(仅用于超链接)

使用框架提供的一个注解@PathVariable,将请求url中的值作为参数进行提取,只能是超链接。restful风格下的数据提取方式。restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

 

RESTful风格是把请求参数变为请求路径的一种编程风格。通过路径变量的使用,可以实现RESTful风格的编程。

中文乱码:

由于tomcat默认使用ISO-8859-1对接收的文本编码,因此要获得正确中文有两种解决方式:

1. 自己转码

使用如下转码方式。先把name以ISO-8859-1再编码,还原成字节数组,再用UTF-8进行解码,即可获得正确中文。

String newName=new String(name.getBytes("ISO-8859-1"),"UTF-8");

另外一种:

//拿到字节数组
byte[] bytes = name.getBytes("ISO-8859-1");
//再重新构造一下
name = new String(bytes, "UTF-8");

 2. 修改tomcat | conf | server.xml

在server.xml的Connector中添加URIEncoding="utf-8",这样默认就是用utf-8解码了,参数绑定中文也可以正确显示:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" URIEncoding="utf-8"/>

另,web.xml配置的filter只对post请求有效,因此对此问题不是解决之道。

对于Maven项目来说,直接修改pom文件夹

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <uriEncoding>UTF-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

(4)请求参数名称与形参名称不一致

请求与形参中的名字不对应,可以使用

@RequestParam(value="name1",required=true) String namea来进行参数名称绑定。

 

(5)数组类型的请求参数

@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
    System.out.println("我的爱好:");
    for(String s:hobby){
    	System.out.println(s);
    }
    return "main";
}

(6)使用HttpServletRequest对象提取

在方法参数中声明一个request对象,使用request的getParameter()获取表单提交的数据,这样得到的数据还要手工进行数据类型的转换。

public String five(HttpServletRequest request){
    int age=new Integer(request.getParameter("stuage"));
    String name=request.getParameter("stuname");
    System.out.println(age+"*********"+name);
    return "main";
}

2.4 请求参数中文乱码解决

对于前面所接收的请求参数,若含有中文,则会出现中文乱码问题。Spring 对于请求参数中的中文乱码问题,给出了专门的字符集过滤器: spring-web-5.2.5.RELEASE.jar 的org.springframework.web.filter 包下的 CharacterEncodingFilter 类。

 

(1)解决方案

在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。

 

(2)源码分析

 

2.5 处理器方法的返回值

使用@Controller 注解的处理器的方法,其返回值常用的有四种类型:

Ø 第一种:ModelAndView

Ø 第二种:String

Ø 第三种:无返回值void

Ø 第四种:返回对象类型

2.5.1 返回 ModelAndView

若处理器方法处理完后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回 ModelAndView 比较好。当然,若要返回 ModelAndView,则处理器方法中需要定义 ModelAndView 对象。在使用时,若该处理器方法只是进行跳转而不传递数据,或只是传递数据而并不向任何资源跳转(如对页面的 Ajax 异步响应),此时若返回 ModelAndView,则将总是有一部分多余:要么 Model 多余,要么 View 多余。即此时返回 ModelAndView 将不合适。较少使用。

2.5.2 返回 String

处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析可以将其转换为物理视图地址。

 

 

当然,也可以直接返回资源的物理视图名。不过,此时就不需要再在视图解析器中再配置前辍与后辍了。

 

使用ModelAndView对象作为控制器方法的返回值类型,可以很好地同时解决跳转路径和携带数据的问题,但String作为控制器方法的返回值类型只解决了跳转路径问题,如果跳转到目标页面同时还需要携带数据怎么办呢?有3个解决方案:

  1. 使用方法中的Model参数

  2. 使用方法中的HttpServletRequest对象

  3. 使用方法中的HttpSession对象

2.5.3 无返回值void

对于处理器方法返回 void 的应用场景,应用在AJAX 响应处理。若处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回 void。我们SSM整合案例中的分页使用的就是无返回值。代码见后面。

通过jackson-databind把对象转换为json字符串。

2.5.4 返回对象Object

处理器方法也可以返回 Object 对象。这个 Object 可以是 Integer,自定义对象,Map,List 等。但返回的对象不是作为逻辑视图出现的,而是作为直接在页面显示的数据出现的。返回对象,需要使用@ResponseBody 注解,将转换后的 JSON 数据放入到响应体中。Ajax请求多用于Object返回值类型。由于转换器底层使用了Jackson 转换方式将对象转换为JSON 数据,所以需要添加Jackson的相关依赖。

项目案例:使用ajax请求返回一个JSON结构的学生.

实现步骤:

A.在pom.xml文件中添加依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId
    <version>2.9.8</version>
</dependency>

B.添加jQuery的函数库,在webapp目录下,新建js目录,拷贝jquery-3.3.1.js到目录下

C.在页面添加jQuery的函数库的引用

 <script src="js/jquery-3.3.1.js"></script>

D.发送ajax请求

function show() {
    $.ajax({
        url:"${pageContext.request.contextPath}/ajax.action",
        type:"post",
        dataType:"json",
        success:function (stu) {
            $("#oneStu").html(stu.name+"------"+stu.age);
        }
    });
}

E.开发action

 @Controller
 public class AjaxDemo {
     @RequestMapping("/ajax")
     @ResponseBody  //此注解用来解析ajax请求
     public Object ajax(){
         Student stu = new Student("张三",22);
         return stu;
     }
 }

F.在springmvc.xml文件中添加注解驱动

  <mvc:annotation-driven />

G.index.jsp页面

  <a href="javascript:show()">ajax访问服务器,返回一个学生</a>
  <br>
  <div id="oneStu"></div>

Ajax/JSON专项突破:

  1. 服务端接收对象返回 JSON 字符串 objectMapper.writeValueAsString(user);

  2. 服务端接收Bean返回 JSON 对象 @ResponseBody

  3. 服务端接收属性返回 JSON 对象

  4. 客户端发送 JSON 字符串返回 JSON 字符串

  5. 数据接收与返回的限制 @RequestMapping(consumes="application/json",produces="application/json")

    consumes限制前台传递过来的数据格式必须是JSON

    produces设置返回的数据要转成JSON对象并回传给客户端

  6. 直接输出响应字符串

前端JSON字符串和对象的相互转换:

//1.用于将服务端传回来的JSON字符串解释转化为JSON对象

var jsonobject = JSON.parse(data);

//2.JSON对象转化为字符串

var jsonObj = {username:"张三",password:"123"};//定义一个JSON对象

var jsonStr = JSON.stringify(jsonObj);

总结

以上就是今天的内容~

欢迎大家点赞👍,收藏⭐,转发🚀,
如有问题、建议,请您在评论区留言💬哦。

最后:转载请注明出处!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/919892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF 查看绑定错误——Snoop 的基本使用

关于 可以通过 Snoop 查看 WPF 程序的 Visual Tree&#xff0c;更多介绍请看 snoopwpf 快速开始 一、下载 snoopwpf.msi 安装后打开&#xff0c;选择自己的程序&#xff0c;点击 snoop&#xff08;望远镜&#xff09; 二、筛选 点击左侧下拉列表&#xff0c;选择 Show onl…

Spring框架中的Singleton和Prototype Bean作用域

Spring框架是依赖注入的事实上的框架&#xff0c;在开发可扩展、弹性和安全的云原生环境中具有良好的记录。 在使用Spring Beans时&#xff0c;初学者经常会对Spring beans和它们的作用域感到有些困惑。 以下是我对Singleton和Prototype Bean作用域的简单示例进行阐述的尝试。 …

Midjourney API 的对接和使用

“ 阅读本文大概需要 4 分钟。 ” 在人工智能绘图领域&#xff0c;想必大家听说过 Midjourney 的大名吧。 Midjourney 以其出色的绘图能力在业界独树一帜。无需过多复杂的操作&#xff0c;只要简单输入绘图指令&#xff0c;这个神奇的工具就能在瞬间为我们呈现出对应的图像。无…

C#实现简单TCP服务器和客户端网络编程

在C#中进行网络编程涉及许多类和命名空间&#xff0c;用于创建和管理网络连接、传输数据等。下面是一些主要涉及的类和命名空间&#xff1a; System.Net 命名空间&#xff1a;这个命名空间提供了大部分网络编程所需的类&#xff0c;包括&#xff1a; IPAddress&#xff1a;用于…

2.IO控制器

第五章 I/O管理 2.I/O控制器 I/O控制器的组成&#xff1a; I/O控制器负责接收和识别从CPU发来的各种命令&#xff0c;同时需要翻译为具体的设备可以明白的命令&#xff0c;通过控制器与设备的接口发送给具体的设备&#xff0c;让设备执行相应的操作。 一个I/O控制器有可能会负…

跨越边界:从前端切图仔走进iOS开发(Swift版--上集)

本文简介 点赞 关注 收藏 学会了 本文将以前端开发者的视角&#xff0c;和各位工友进入iOS开发的世界。 本文以实战为导向&#xff0c;快速掌握iOS开发这个技能。 无论你是想要扩展技能领域&#xff0c;还是对iOS开发充满好奇&#xff0c;花一个下午学习本文都能打开iOS开…

AUTOSAR规范与ECU软件开发(实践篇)5.6 基于ISOLAR-A的系统级设计与配置方法(下)

目录 3 、系统配置 4、 ECU信息抽取 3 、系统配置 在完成了VehicleComposition建立后, 可以进行系统配置。 右键点击System→Create System Info→Elements|System(图5.83) 可以新建System Info, 命名为VehicleSystem, 结果如图5.84所示。 图5.83 System Info新建(一)

Unity 3D之 利用Vector3 计算移动方向,以及实现位移多少

文章目录 先分析代码&#xff0c;从代码中了解Vector3 moveDirection new Vector3(10f, 0f, 100f);合法吗Vector3 moveDirection new Vector3 (xf,yf,zf)不是用来表示三维坐标的怎么表示在某个方向的位移 先分析代码&#xff0c;从代码中了解 这段代码是一个在游戏开发中常见…

回归预测 | MATLAB实现DBN-ELM深度置信网络结合极限学习机多输入单输出回归预测

回归预测 | MATLAB实现DBN-ELM深度置信网络结合极限学习机多输入单输出回归预测 目录 回归预测 | MATLAB实现DBN-ELM深度置信网络结合极限学习机多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现DBN-ELM深度置信网络结合极限学习…

七夕学算法

目录 P1031 [NOIP2002 提高组] 均分纸牌 原题链接 : 题面 : 思路 : 代码 : P1036 [NOIP2002 普及组] 选数 原题链接 : 题面 : 思路 : 代码 : P1060 [NOIP2006 普及组] 开心的金明 原题链接 : 题面 : 思路 : 01背包例题 : 代码 : P1100 高低位交换 原题…

stm32之7.位带操作---volatile---优化等级+按键控制

源码--- #define PAin(n) (*(volatile uint32_t *)(0x42000000 (GPIOA_BASE0x10-0x40000000)*32 (n)*4)) #define PEin(n) (*(volatile uint32_t *)(0x42000000 (GPIOE_BASE0x10-0x40000000)*32 (n)*4)) #define PEout(n) (*(volatile uint32_t *)(0x420…

SQL优化之诊断篇:快速定位生产性能问题实践

1.优化背景 用户提交一个 SQL 作业后&#xff0c;一方面是希望作业能够成功运行&#xff0c;另一方面&#xff0c;对于成功完成的作业&#xff0c;需要进一步分析作业瓶颈&#xff0c;进行性能调优。针对这两个方面的需求&#xff0c;本文将介绍如何解决作业运行时的常见问题、…

C语言刷题训练DAY.11

1.有序序列插入一个整数 解题思路&#xff1a; 这里我们采用从后向前的比较法&#xff0c;如果最后面的数字比N大&#xff0c;我们就把这个数字向后移动一位&#xff0c;就比如把下标为3的数据移动到下标为4的位置。 注意&#xff1a;可能有一个数字是整个数组里面最小的&#…

无涯教程-PHP - 移除的扩展

以下扩展已从PHP 7开始删除- eregmssqlmysqlsybase_ct 以下SAPI已从PHP 7开始删除- aolserverapacheapache_hooksapache2filtercaudiumcontinuityisapimilternsapiphttpdpi3webroxenthttpdtuxwebjames PHP - 移除的扩展 - 无涯教程网无涯教程网提供以下扩展已从PHP 7开始删除…

UnionTech OS(统信桌面操作系统)安装 g++ 和 cmake

文章目录 前言一、debian 10简介二、安装 g三、安装cmake参考资料 前言 统信桌面操作系统支持x86、龙芯、申威、鲲鹏、飞腾、兆芯等国产CPU平台&#xff0c;基于debian 10.x 的稳定版本&#xff0c;长期维护的统一内核版本(4.19)。 一、debian 10简介 Debian 10 是一款广泛使…

Java 对图片进行上传或下载后发生了90度的旋转

一、背景介绍 在开发给上传图片打水印的时候&#xff0c;发现了一个奇怪的事情。某张图片在上传后发生了90度的旋转&#xff0c;但是在window打开来是竖的&#xff0c;上传后在打开就是横的。后来上网查询是由于手机在拍摄时候是横着拍的&#xff0c;在图片处理时将旋转角度存…

postman接口参数化设置

为什么需要参数化&#xff1f; 我们在做接口测试的过程中&#xff0c;会遇到需要测试同一个接口使用不同的数据的情况&#xff0c;如果每次去一个个填写数据就太麻烦了&#xff0c;这时我们就需要用到接口参数化&#xff0c;我们把数据单独的存放在一个文件中管理&#xff0c;…

一生一芯8——在github上添加ssh key

为在github上下载代码框架&#xff0c;这里在github上使用ssh key进行远程连接&#xff0c;方便代码拉取 参照博客https://blog.csdn.net/losthief/article/details/131502734 本机 系统ubuntu22.04 git 版本2.34.1 本人是第一次配置&#xff0c;没有遇到奇奇怪怪的错误&…

AI绘画:SDXL版ControlNet模型和使用方法!

SDXL是目前最强的AI绘画基础模型&#xff0c;直接加载模型&#xff0c;就可以生成不错的效果。但是它有一个致命的问题&#xff0c;就是不支持ControlNet。 在AI绘画中&#xff0c;ControlNet是一个非常重要的工具。有了它&#xff0c;就可以生成更加可控精准的图片。ControlN…

贪心算法:简单而高效的优化策略

在计算机科学中&#xff0c;贪心算法是一种简单而高效的优化策略&#xff0c;用于解决许多组合优化问题。虽然它并不适用于所有问题&#xff0c;但在一些特定情况下&#xff0c;贪心算法能够产生近似最优解&#xff0c;而且计算成本较低。在本文中&#xff0c;我们将深入探讨贪…