5 数据处理及跳转
5.1 结果跳转方式
5.1.1 ModelAndView
这是ModelAndView对象,根据view的名称,和视图解析器调到指定的页面
页面:{视图解析器前缀} + viewName + {视图解析器后缀}
<!--视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!--Handler-->
<bean name="/t1" class="com.serene.controller.ControllerTest1"/>
对应Controller类:
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//返回一个视图模型对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg", "这是实现Controller接口控制器!");
mv.setViewName("test");
return mv;
}
}
访问路劲
5.1.2 ServletAPI
通过设置ServletAPI,不需要视图解析器,这里需要注释掉5.1.1中配置文件的代码
1.通过HttpServletResponse进行输出,请求页面打印信息
2.通过HttpServletResponse进行重定向,地址和页面都跳转
3.通过HttpServletResponse进行转发,页面跳转,地址不变
@Controller
public class ResultGoController {
//1.通过HttpServletResponse进行输出
@RequestMapping("/resultgo/t1")
public void test1(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.getWriter().println("Hello,Spring By servlet API");
}
//2.通过HttpServletResponse实现重定向 页面、地址都跳转
@RequestMapping("/resultgo/t2")
public void test2(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.sendRedirect("/index.jsp");
}
//3.通过HttpServletResponse 实现转发 页面跳转,地址不变
@RequestMapping("/resultgo/t3")
public void test3(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
//转发
req.setAttribute("msg", "通过HttpServletResponse 实现转发");
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
}
}
5.1.3 SpringMVC
1.通过SpringMVC来实现转发和重定向-无需视图解析器;
测试前,需要将视图解析器注释掉
@Controller
public class ResultSpringMVC {
@RequestMapping("rsm/t1")
public String test1(){
//转发一 页面跳转,地址不变
return "/index.jsp";
}
@RequestMapping("rsm/t2")
public String test2(){
//转发二
return "forward:/index.jsp";
}
@RequestMapping("rsm/t3")
public String test3(){
//重定向 页面、地址都跳转
return "redirect:/index.jsp";
}
}
2.通过SpringMVC来实现转发和重定向-有视图解析器;
重定向中,不需要视图解析器,本质就是重新请求一个新地址
@Controller
public class ResultSpringMVC2 {
@RequestMapping("rsm2/t1")
public String test1(){
//转发一
return "test";
}
@RequestMapping("rsm2/t2")
public String test2(){
//重定向
return "redirect:/index.jsp";
}
}
5.2 数据处理
5.2.1 处理提交的数据
-
提交的域名称和处理方法的参数名一致
提交数据:http://localhost:8080/user/t1?name=serene
处理方法:
@Controller @RequestMapping("/user") public class UserController { //1.提交的域名和处理方法的参数名一致 @RequestMapping("/t1") public String test1(String name, Model model){ System.out.println("parameter:"+name); model.addAttribute("msg","parameter:"+name); return "test"; } }
结果:
-
提交的域名称与处理方法的参数名不一致
提交数据:http://localhost:8080/user/t2?username=serene处理方法:@RequestParam(“username”)
@Controller @RequestMapping("/user") public class UserController { //2.提交的域名称处理方法和参数民不一致 @RequestMapping("/t2") public String test2(@RequestParam("username") String name, Model model){ System.out.println("parameter:"+name); model.addAttribute("msg","parameter:"+name); return "test"; } }
测试结果:
-
提交的是一个对象
-
提交的表单域和对象的属性名一致,参数使用对象即可
对象对应实体类属性:
package com.serene.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; //注解完成javaBean属性,注意导入Lombok依赖 @Data @AllArgsConstructor @NoArgsConstructor public class User { private int id; private String name; private int age; }
提交方法:http://localhost:8080/user/t3?name=serene
处理方法:
@Controller @RequestMapping("/user") public class UserController { //3.前端提交的是一个对象 @RequestMapping("/t3") public String test3(User user, Model model){ System.out.println("parameter:"+user); model.addAttribute("msg", "parameter:"+user); return "test"; } }
测试结果:
说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则为null。不用传入对象的所有属性。
5.2.2 数据显示到前端
-
通过ModelAndView
未使用注解一直使用的方式,
public class ControllerTest1 implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { //返回一个视图模型对象 ModelAndView mv = new ModelAndView(); mv.addObject("msg", "这是实现Controller接口控制器!"); mv.setViewName("test"); return mv; } }
<!--视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <bean name="/t1" class="com.serene.controller.ControllerTest1"/>
2.通过ModelMap
@Controller @RequestMapping("/user") public class UserController { //ModelMap @RequestMapping("/t4") public String test4(User user, ModelMap model){ System.out.println("parameter:"+user); model.addAttribute("msg", "parameter:"+user); return "test"; } }
|
-
通过Model
5.2.1中的Model方式,此处不举例了
-
几种数据显示到前端方式的对比
Model 只有寥寥几个方法适用于储存数据,简化了新手对于 Model 对象的操作个理解;
ModelMap 继承了 LinkedMap,除了实现自身的一些方法,同样继承该类的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进性控制展示层的跳转。
当然更多的以后开发考虑的更多的性能和优化,就不能单单仅限于此的了解。
6 乱码问题
测试步骤:
-
在首页编写一个提交表单,提交表单方式为 post
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> $***乱码问题测试!***$ <form action="/e/t" method="post"> <input type="text" name="name"> <input type="submit"> </form> </body> </html>
-
编写对应的处理方法
@Controller public class EncodingController { @RequestMapping("e/t") public String test(String name, Model model){ System.out.println("name="+name); model.addAttribute("msg", "name="+name); return "test"; } }
-
首页表单中输入中文测试,发现乱码
乱码问题在开发中很常见,是一个让程序猿头疼的问题!
以前乱码问题通过过滤器解决,而SpringMVC给我们提供了一个过滤器,可以再web.xml中配置,,修改了xml配置,需要重启服务器!
<!--过滤器解决乱码问题-->
<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>
此时测试首页表单中传入中文,便不会出现乱码
如果该过滤器解决不了的乱码问题:
1.修改Tomcat配置文件:设置编码! 路径:/Tomcat/conf/server.xml
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
2.自定义过滤器
package com.serene.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
public class GenericEncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//处理response的字符编码
HttpServletResponse myResponse=(HttpServletResponse) response;
myResponse.setContentType("text/html;charset=UTF-8");
// 转型为与协议相关对象
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 对request包装增强
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
//是否编码的标记
private boolean hasEncode;
//定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
public MyRequest(HttpServletRequest request) {
super(request);// super必须写
this.request = request;
}
// 对需要增强方法 进行覆盖
@Override
public Map getParameterMap() {
// 先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post请求
try {
// 处理post乱码
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get请求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) { // 确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 处理get乱码
values[i] = new String(values[i]
.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
//取一个值
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回参数的第一个值
}
//取所有值
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
<!--web.xml配置自定义过滤器 注意/* -->
<!--自定义过滤器解决乱码问题-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.serene.filter.GenericEncodingFilter</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>
这是大神写的一个过滤器,一般情况下,SpringMVC默认的编码处理就已经能够很好解决乱码问题了!
乱码问题,需要平时多注意,在尽可能设置编码的地方都同意设置为 utf-8 !
对应代码:springmvc-04-controller