Spring MVC 学习总结(三)——请求处理方法Action详解

本文深入探讨SpringMVC框架中控制器的参数绑定机制,包括基本数据类型、自定义类型、复杂类型、数组、List集合、Map集合的绑定方法,以及@RequestParam、@RequestBody、@ResponseBody等注解的使用技巧。同时,详细解析了不同类型的Action返回值,如String、void、ModelAndView、Model等,以及如何处理视图中URL问题和乱码解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring MVC中每个控制器中可以定义多个请求处理方法,我们把这种请求处理方法简称为Action,每个请求处理方法可以有多个不同的参数,以及一个多种类型的返回结果。

一、Action参数类型

1.1、自动参数映射

1.1.1、基本数据类型

方法的参数可以是任意基本数据类型,如果方法参数名与http中请求的参数名称相同时会进行自动映射,视图user目录下的index.jsp与示例代码如下:

package cn.liuw.controller;

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

@Controller
@RequestMapping("/user")
public class UserController {
	
	// 自动参数映射
    @RequestMapping("/index")
    public String index(Model model, int id, String name) {
        model.addAttribute("message", "name=" + name + ",id=" + id);
        return "user/index";
    }

}
<%@ page language="java" contentType="text/html;utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC 
	"-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>User</title>
</head>
<body>
${message}
</body>
</html>

运行结果如下:

1.1.2、自定义数据类型

除了基本数据类型,也可以自定义的数据类型,如一个自定义的POJO对象,Spring MVC会通过反射把请中的参数设置到对象中,转换类型,示例代码如下:

package cn.liuw.controller;

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

import cn.liuw.domain.User;

@Controller
@RequestMapping("/user")
public class UserController {
	
	// 自动参数映射自定义数据类型
    @RequestMapping("/idx")
    public String index(Model model, User user) {
        model.addAttribute("message", user);
        return "user/index";
    }
}
package cn.liuw.domain;

public class User {

	private int id;
	private String name;
	
	public User() {
	}
	
	public User(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

运行结果:

示例中使用的是的URL中的参数,其实也可以是客户端提交的任意参数,特别是表单中的数据。

1.1.3、复杂数据类型

这里指的复杂数据类型指的是一个自定义类型中还包含另外一个对象类型,如用户类型中包含产品对象:

package cn.liuw.domain;

public class User {

	private int id;
	private String name;
	
	private Product product;
	
	public User() {
	}
	
	public User(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Product getProduct() {
		return product;
	}
	public void setProduct(Product product) {
		this.product = product;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}
}

class Product {

	private int pid;
	private String pname;
	
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	
	@Override
	public String toString() {
		return "Product [pid=" + pid + ", pname=" + pname + "]";
	}
}

复杂数据类型映射示例:

@RequestMapping("/idx2")
public String index2(Model model, User user) {
	model.addAttribute("message", user.getName()+","+user.getProduct().getPname());
	return "user/index";
}

运行结果:

为了方便这里我使用的是url,这里当然可以是一个表单,如下代码所示:

<form method="post" action="/user/idx3">
     username:<input name="username" /><br/>
     pdctname:<input name="product.name" /><br/>
    <button>提交</button>
</form>

1.1.4、数组

浏览器请求传递参数:http://localhost:8080/user/idx01?ids=1&ids=2&ids=3

第一种:

代码中用数组Integer[] ids接收,如下:

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/idx01")
    public String index2(Model model, Integer[] ids) {
        model.addAttribute("message", Arrays.toString(ids));
        return "user/index";
    }
}

第二种:

用集合List<Integer> id接收,但是List集合必须得用其他类包装起来。如下:

包装类:

public class User {

    private int id;
    private String name;
	
    List<Integer> ids;
    
    //getter and setter
}

代码类:

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/idx02")
    public String index2(Model model, User user) {
        model.addAttribute("message", user);
        return "user/index";
    }
}

以上两种浏览器url传参一样,接收不一样。

1.1.5、List集合类型

不能直接在index2()方法的参数中指定List<T>类型,定义一个类型包装List集合在其中。这里Controller中接收代码与数组类型的第二种方法一样,但是,传参数不一样。

浏览器请求传递参数:http://localhost:8080/user/idx01?ids[0]=1&ids[1]=2&ids[2]=3

这里同样可以使用一个表单向服务器提交数据,不过TomCat高版本可能会产生错误。因为get请求新规范规定不允许url带特殊字符,解决方法:对请求编码解码(UrlDecode、UrlEncode)。

1.1.6、Map集合类型

Map集合与List集合类似,也算封装在一个类中,请求参数方式也一样。

1.2、@RequestParam参数绑定

简单的参数可以使用上一节中讲过的自动参数映射,复杂一些的需使用@RequestParam完成,虽然自动参数映射很方便,但有些细节是不能处理的,如参数是否为必须参数,名称没有办法指定,参数的默认值就没有有办法做到了。如果使用@RequestParam可以实现请求参数绑定,Spring MVC会自动查找请求中的参数转类型并将与参数进行绑定,示例代码如下:

1.2.1、基本数据类型绑定与注解属性

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/index")
    public String index(Model model, @RequestParam(required = false, defaultValue = "99") int id) {
        model.addAttribute("message", id);
        return "user/index";
    }
}

@RequestParam共有4个注解属性,required属性表示是否为必须,默认值为true,如果请求中没有指定的参数会报异常;defaultValue用于设置参数的默认值,如果不指定值则使用默认值,只能是String类型的。name与value互为别名关系用于指定参数名称。

运行结果:

1.2.2、List与数组绑定基本数据类型

在上一节中我们使用自动参数映射是不能直接完成List与数组绑定的,结合@RequestParam可以轻松实现,示例代码如下所示:

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/index1")
    public String index1(Model model, @RequestParam(name = "u") List<String> usernames) {
        model.addAttribute("message", usernames.get(0)+","+usernames.get(1));
        return "user/index";
    }
}

运行结果:

直接在URL中输入测试数据可以绑定成功,使用表单同样可行,页面脚本如下:

user/form.jsp

<%@ page language="java" contentType="text/html;utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC 
	"-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>User</title>
</head>
<body>
<form action="/user/index1" method="post">
    <p>
        <label>爱好:</label> 
        <input type="checkbox" value="read" name="u" />阅读
        <input type="checkbox" value="online" name="u" />上网
        <input type="checkbox" value="game" name="u" />电游
    </p>
    <button>提交</button>
</form>
</body>
</html>

user/index.jsp

<%@ page language="java" contentType="text/html;utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC 
	"-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>User</title>
</head>
<body>
${message}
</body>
</html>

请求处理方法代码如下:

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/form")
    public String form(){
        return "user/form";
    }
	
    @RequestMapping("/index1")
    public String index1(Model model, @RequestParam(name = "u") List<String> usernames) {
        model.addAttribute("message", usernames.get(0)+","+usernames.get(1));
        return "user/index";
    }
}

运行结果:

@RequestParam("u")是必须的,因为页面中的表单name的名称为u,所有服务器在收集数据时应该使用u而非usernames,如果同名则可以省去。

1.2.3、@RequestBody

@RequestBody 注解将HTTP请求正文插入方法中,使用适合的 HttpMessageConverter将请求体写入某个对象。
作用:
1) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上; 
2) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

使用时机:

A) GET、POST方式提时, 根据request header Content-Type的值来判断:

application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理); 
multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据); 
其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);

B) PUT方式提交时, 根据request header Content-Type的值来判断:

application/x-www-form-urlencoded, 必须;multipart/form-data, 不能处理;其他格式, 必须;

说明:request的body部分的数据编码格式由header部分的Content-Type指定;

例如:

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/login")
    @ResponseBody
    //将ajax(datas)发出的请求写入 User对象中
    public User login(@RequestBody User user) { 
    	return user; 
    }
}

@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上。

$.ajax({
	url:"/login",
	type:"POST",
	data:'{"userName":"admin","pwd","admin123"}',
	content-type:"application/json charset=utf-8",
  success:function(data){
  	alert("request success ! ");
  	}
  });

当然,也可以将其分别绑定到对应的字符串上。

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/index")
    @ResponseBody
    public void index(@RequestBody String username,@RequestBody String password) { 
    	System.out.println(username+","+password);
    }
}

需要注意的是,JSON字符串中的key必须对应user中的属性名。

1.2.4、List与数组直接绑定自定义数据类型与AJAX

上一小节中我们绑定的集合中存放的只是基本数据类型,如果需要直接绑定更加复杂的数据类型则需要使用@RequestBody与@ResponseBody注解了,先解释一下他们的作用:

@RequestBody 将HTTP请求正文转换为适合的HttpMessageConverter对象。
@ResponseBody 将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。

@RequestBody默认接收的Content-Type是application/json,因此发送POST请求时需要设置请求报文头信息,否则Spring MVC在解析集合请求参数时不会自动的转换成JSON数据再解析成相应的集合,Spring默认的json协议解析由Jackson完成。要完成这个功能还需要修改配置环境,具体要求如下:

a)、修改Spring MVC配置文件,启用mvc注解驱动功能,<mvc:annotation-driven />

b)、pom.xml,添加jackson依赖,添加依赖的配置内容如下:

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

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

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.7.4</version>
</dependency>

c)、ajax请求时需要设置属性dataType 为 json,contentType 为 'application/json;charse=UTF-8',data 转换成JSON字符串,如果条件不满足有可能会出现415异常。

示例代码如下:

@Controller
@RequestMapping("/user")
public class UserController {
    
    @RequestMapping("/action")
    public void action(@RequestBody List<User> users,
    		HttpServletResponse response) throws IOException{
    	response.setCharacterEncoding("utf-8");
    	response.getWriter().write("添加成功!");
    }
}

action方法的参数@RequestBody List<User> users是接收从客户端发送到服务器的User集合。在参数前增加@RequestBody的作用是让Spring MVC在收到客户端请求时将选择合适的转换器将参数转换成相应的对象。默认的请求内容并非是application/json,而是application/x-www-form-urlencoded。因此,在客户端请求时设置内容类型为application/json。

我们写一个jsp页面form1.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>List与数组直接绑定自定义数据类型与AJAX</title>
</head>
<body>
    <button type="button" onclick="post_json();">向服务器发送json</button>
    <p id="msg"></p>
    <script type="text/javascript"
        src="<c:url value="/scripts/jQuery1.11.3/jquery-1.11.3.min.js"/>"></script>
    <script type="text/javascript">
        var users = new Array();
        users.push({
            id : 1,
            name : "zhangsan"
        });
        users.push({
            id : 2,
            name : "lisi"
        });
        users.push({
            id : 3,
            name : "wangwu"
        });
        function post_json() {
            $.ajax({
                type : "POST",
                url : "user/action",
                data : JSON.stringify(users), //将users对象转换成json字符串
                contentType : "application/json;charset=UTF-8",
                //发送信息至服务器时内容编码类型,(默认: "application/x-www-form-urlencoded")
                dataType : "text", //预期服务器返回的数据类型
                success : function(result) {
                    $("#msg").html(result);
                }
            });
        }
    </script>
</body>
</html>

页面中的方法是实现将一个json集合发送到服务器并映射成一个List集合。

1.3、重定向与转发

重定向:

@Controller
@RequestMapping("/user")
public class UserController {
    
	// 重定向
	@RequestMapping("/index")
	public String index(Model model) {
		return "user/index";
	}

	@RequestMapping("/login")
	public String login(Model model) {
		model.addAttribute("message", "login-name");
		return "redirect:index";
	}
}

转发:

@Controller
@RequestMapping("/user")
public class UserController {
	
    //转发
    @RequestMapping("/index")
    public String index(Model model){
        return "user/index";
    }

    @RequestMapping("/logout")
    public String logout(Model model){
        model.addAttribute("message","logout-status");
        return "forward:index";
    }
}

重定向和转发区别:

1.重定向是客户端重新发的请求,转发是服务端的。

2.重定向URL变化,转发URL不变。

3.我们看到重定向和转发的运行结果,请求是Request域,重定向只会在第二次请求中携带Model中的参数。

二、Action返回值类型

ModelAndView
Model
Map 包含模型的属性
View
String 视图名称
void
HttpServletResponse
HttpEntity<?>或ResponseEntity<?>
HttpHeaders
Callable<?>
DeferredResult<?>
ListenableFuture<?>
ResponseBodyEmitter
SseEmitter
StreamingResponseBody
其它任意类型,Spring将其视作输出给View的对象模型

2.1、视图中url问题

代码如下:

view目录下的hello/sayHello.jsp视图,内容如下:

我们看到jsp中图片的路径为:/static/img/zhongqiu.jpg。因为我们讲静态资源(css,js,img等)放在了WEB-INF下,所以MVC要对静态文件路径做处理,如下:

运行结果:

或者也可以用另外一种方式。因为静态资源一般不需要放到WEB-INF下,所以可以将静态资源移动到webapp目录下。此时,我们需要修改MVC处理静态文件的方式。

配置<mvc:default-servlet-handler/>,MVC在对请求处理的时候,如果是静态文件请求,那么不经过DispatchServlet,而是以webapp为根路径去查找对应静态资源。否则,让DispatchServlet处理。

此时,我们的JSP视图中,图片的路径应写成相对于webapp目录的"绝对路径"。我们使用JSTL中C标签的<c:url>可以做到。

2.2.2、String作为内容输出

如果方法声明了注解@ResponseBody ,将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。此时,返回值String不再是JSP路径而是响应内容,示例如下:

@Controller
@RequestMapping("/bye")
public class ByeController {
	@RequestMapping("")
	@ResponseBody
	public String index(Model model) {
		StringBuilder sb = new StringBuilder("<h1>你好</h1>");
		sb.append("\n<p>是的,今天很不开森!想骂人。</p>");
		return sb.toString();
	}
}

此时,运行出现了乱码!因为,@ResponseBody 将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。其中有7种转换器,StringHttpMessageConverter转换器默认转换字符集为:ISO-8859-1。此时,我们需要修改springmvc.xml配置文件:

<!-- 支持mvc注解驱动 -->
<mvc:annotation-driven>
	<!-- 解决响应中文乱码 -->
	<mvc:message-converters register-defaults="true">
		<bean class="org.springframework.http.converter.StringHttpMessageConverter">
			<property name="supportedMediaTypes" value="text/html;charset=UTF-8" />
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>

运行结果:

2.3、返回值为void

void在普通方法中是没有返回值的意思,但作为请求处理方法并非这样,存在如下两种情况:

2.3.1、方法名默认作为视图名

当方法没有返回值时,方法中并未指定视图的名称,则默认视图的名称为方法名,如下代码所示:

@Controller
@RequestMapping("/user")
public class UserController {
	
	@RequestMapping("/index")
	public void index(Model model) {
		
	}
}

直接会去访问的路径是:url=/WEB-INF/views/user/index.jsp。可见URL= prefix前缀+控制器路径+方法名称 +suffix后缀组成。

2.3.2、直接响应输出结果

当方法的返回值为void,但输出流中存在输出内容时,则不会去查找视图,而是将输入流中的内容直接响应到客户端,如下代码所示:

@Controller
@RequestMapping("/user")
public class UserController {
	
	@RequestMapping("/hello")
	public void hello(HttpServletResponse response) throws IOException {
		response.setHeader("Content-type", "text/html;charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		response.getWriter().write("<h2>你好,水晶之夜!</h2>");
	}
}

运行结果:

2.4、返回值为ModelAndView

 在旧的Spring MVC中ModelAndView使用频率非常高,它可以同时指定须返回的模型与视图对象或名称,示例代码如下:

@Controller
@RequestMapping("/user")
public class UserController {
	
	@RequestMapping("/msg")
    public ModelAndView msg() 
    {
        //1只指定视图
        //return new ModelAndView("/user/msg");
        
        //2分别指定视图与模型
        //Map<String, Object> model=new HashMap<String,Object>();
        //model.put("message", "ModelAndView msg");
        //return new ModelAndView("/user/msg",model);
        
        //3同时指定视图与模型
        //return new ModelAndView("/user/msg","message","英雄之战,冢之谷!");
        
        //4分开指定视图与模型
        ModelAndView modelAndView=new ModelAndView();
        //指定视图名称
        modelAndView.setViewName("/user/msg");
        //添加模型中的对象
        modelAndView.addObject("message", "<h2>Hello ModelAndView</h2>");
        return modelAndView;
    }
}

ModelAndView有多个构造方法重载,单独设置属性也很方便,运行结果如下:

2.5、返回值为Map

当返回结果为Map时,相当于只是返回了Model,并未指定具体的视图,返回视图的办法与void是一样的,即URL= prefix前缀+控制器路径+方法名称 +suffix后缀组成,示例代码如下:

@RequestMapping("/map")
public Map<String, Object> map()
{
	Map<String, Object> model=new HashMap<String,Object>();
	model.put("message", "Hello Map");
	model.put("other", "more item");
	return model;
}

2.6、返回值为Model类型

 Model接口定义在org.springframework.ui下,model对象会用于页面渲染,视图路径使用方法名,与void类似。示例代码如下:

@RequestMapping("/party")
public Model party(Model model)
{
	model.addAttribute("message", "返回类型为org.springframework.ui.Model");
	return model;
}

2.7、@ResponseBody

默认情况下面Spring MVC会使用如下流程处理请求与响应结果:

@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

2.8、@RestController

Spring 4 MVC中提供的@RestController,使用最少的代码来构建一个Restful Web Service,支持返回xml或json数据,这个可以让用户选择,通过URL后缀.xml或.json来完成。

REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
目前在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。

Rest风格的URL:

新增: http://localhost:8080/order      POST 
修改: http://localhost:8080/order/1   PUT update?id=1 
获取:http://localhost:8080/order/1     GET get?id=1 
删除: http://localhost:8080/order/1   DELETE delete?id=1

实现代码如下:

@RestController
@RequestMapping("/car")
public class CarController {
    //查询
    @GetMapping("/{id}")
    public Car getCar(@PathVariable int id){
        return null;
    }
	
	//删除
    @DeleteMapping("/{id}")
    public Car deleteCar(@PathVariable int id){
        return null;
    }
    
	//新增
    @PostMapping
    public Car addCar(Car car){
        return null;
    }

	//更新
    @PutMapping
    public Car updateCar(Car car){
        return null;
    }
    
}

2.9、小结

使用 String 作为请求处理方法的返回值类型是比较通用的方法,这样返回的逻辑视图名不会和请求 URL 绑定,具有很高的灵活性,而模型数据又可以通过Model控制。

  • 使用void,map,Model时,返回对应的逻辑视图名称真实url为:prefix前缀+控制器路径+方法名 +suffix后缀组成。
  • 使用String,ModelAndView返回视图名称可以不受请求的url绑定,ModelAndView可以设置返回的视图名称。
  • 另外在非MVC中使用的许多办法在Action也可以使用。

三、Spring MVC乱码解决方法

3.1、页面编码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>

3.2、URL中的乱码

改tomcat中server.xml中Connector的port="8080",加上一个 URIEncoding="utf-8"

3.3、配置过滤器,指定所有请求的编码

(1)配置spring的编码过滤器,为了防止spring中post方式提交的时候中文乱码。方法:修改web.xml文件,添加spring的编码过滤器。

<!-- 配置编码方式过滤器,注意一点:要配置在所有过滤器的前面 -->
<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-mapping>

(2)配置编码过滤器,方法:先创建filter类,再修改web.xml文件,注意的是放在spring的编码过滤器之后

Filter类:

package cn.liuw.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class EncodingFilter implements Filter {

    private String encoding="";
    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    
    //过滤方法  是否往下执行
    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest)arg0;
        HttpServletResponse response=(HttpServletResponse)arg1;
        
        request.setCharacterEncoding(encoding);
        response.setCharacterEncoding(encoding);

        //过滤通行证
        chain.doFilter(request, response);
    }

    //根据web.xml文件的配置进行初始化  
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        this.encoding = arg0.getInitParameter("Encoding");
        
    }

}

修改web.xml,添加如下配置:

<!-- 配置编码过滤 -->
<filter>
	<filter-name>EncodingFilter</filter-name>
	<filter-class>com.qiyuan.filter.EncoidingFilter</filter-class>
	<init-param>
	   <param-name>Encoding</param-name>
	   <param-value>utf-8</param-value>
	</init-param>
</filter>
<filter-mapping>
   <filter-name>EncodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

3.4、文件编码

将文件另存为utf-8格式

3.5、数据库编码

连接字符串指定编码格式

URL=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=UTF-8

参考自:https://www.cnblogs.com/best/p/5669010.html

目录 第一部分spring的核心 第1章开始spring之旅 1.1spring是什么 1.2开始spring之旅 1.3理解依赖注入 1.3.1依赖注入 1.3.2di应用 1.3.3企业级应用中的依赖注入 1.4应用aop 1.4.1aop介绍 1.4.2aop使用 1.5小结 第2章基本bean装配 2.1容纳你的bean 2.1.1beanfactory介绍 2.1.2使用应用上下文 2.1.3bean的生命 2.2创建bean 2.2.1声明一个简单的bean 2.2.2通过构造函数注入 2.3注入bean属性 2.3.1注入简单的数值 2.3.2使用其他的bean 2.3.3装配集合 2.3.4装配空值 2.4自动装配 2.4.1四种自动装配类型 2.4.2混合使用自动和手动装配 2.4.3何时采用自动装配 2.5控制bean创建 2.5.1bean范围化 2.5.2利用工厂方法来创建bean 2.5.3初始化和销毁bean 2.6小结 第3章高级bean装配 3.1声明父bean和子bean 3.1.1抽象基bean类型 3.1.2抽象共同属性 3.2方法注入 3.2.1基本的方法替换 3.2.2获取器注入 3.3注入非springbean 3.4注册自定义属性编辑器 3.5使用spring的特殊bean 3.5.1后处理bean 3.5.2bean工厂的后处理 3.5.3配置属性的外在化 3.5.4提取文本消息 3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给椰子上lime 3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop简介 4.1.1定义aop术语 4.1.2spring对aop的支持 4.2创建典型的spring切面 4.2.1创建通知 4.2.2定义切点和通知者 4.2.3使用proxyfactorybean 4.3自动代理 4.3.1为spring切面创建自动代理 4.3.2自动代理@aspectj切面 4.4定义纯粹的pojo切面 4.5注入aspectj切面 4.6小结 第二部分企业spring 第5章使用数据库 5.1spring的数据访问哲学 5.1.1了解spring数据访问的异常体系 5.1.2数据访问的模板化 5.1.3使用dao支持类 5.2配置数据源 5.2.1使用jndi数据源 5.2.2使用数据源连接池 5.2.3基于jdbc驱动的数据源 5.3在spring里使用jdbc 5.3.1处理失控的jdbc代码 5.3.2使用jdbc模板 5.3.3使用spring对jdbc的dao支持类 5.4在spring里集成hibernate 5.4.1选择hibernate的版本 5.4.2使用hibernate模板 5.4.3建立基于hibernate的dao 5.4.4使用hibernate3上下文会话 5.5spring和java持久api 5.5.1使用jpa模板 5.5.2创建一个实体管理器工厂 5.5.3建立使用jpa的dao 5.6spring和ibatis 5.6.1配置ibatis客户模板 5.6.2建立基于ibatis的dao 5.7缓存 5.7.1配置缓存方案 5.7.2缓存的代理bean 5.7.3注解驱动的缓存 5.8小结 第6章事务管理 6.1理解事务 6.1.1仅用4个词解释事务 6.1.2理解spring对事务管理的支持 6.2选择事务管理器 6.2.1jdbc事务 6.2.2hibernate事务 6.2.3jpa事务 6.2.4jdo事务 6.2.5jta事务 6.3在spring中编写事务 6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2根据数据库验证身份 7.2.3根据ldap仓库进行身份验证 7.3控制访问 7.3.1访问决策投票 7.3.2决定如何投票 7.3.3处理投票弃权 7.4保护web应用程序 7.4.1代理springsecurity的过滤器 7.4.2处理安全上下文 7.4.3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值