springMVC(二)response


1.注解

1.1 @ResponseBody

  • 该注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据

  • 在使用 @RequestMapping后,返回值通常解析为跳转路径 ; 但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中

  • Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,使用该注解需要加入jackson的包

    @RequestMapping("/test")
    public @ResponseBody User test(@RequestBody User user){
        System.out.println("testAjax方法执行了...");
        // 客户端发送ajax的请求,传的是json字符串,后端接收json字符串并处理再返回给前端实现交互
        System.out.println(user);//打印前端传递的数据
        user.setUsername("修改后的名字");
        user.setAge(18);
        // 做响应
        return user;
    }
    

1.2 @RestController

  • @RestController注解相当于@ResponseBody + @Controller合在一起的作用
  • 使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html ; 因为配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容

2.响应数据和结果视图

2.1 返回值为void

2.1.1 页面跳转(转发)

@Controller
@RequestMapping("test")
public class test {        
    @RequestMapping("test1")    
    public void test1(HttpServletRequest request,HttpServletResponse response) throws Exception {
        //页面跳转(转发)到/WEB-INF/pages/success.jsp,该路径需写全,因为视图解析器在此处不起作用
        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);    
    }
}

2.1.2 response页面重定向

@Controller
@RequestMapping("test")
public class test {    
    @RequestMapping("test1")    
    public String test1() throws Exception {        
        System.out.println("test1方法执行了");        
        return "success";    
    }    
    @RequestMapping("test2")    
    public void test2(HttpServletResponse response) throws Exception 
    {        
        System.out.println("test2方法执行了");
        //请求转发到当前控制器下的其它方法,此处的test1指@RequestMapping("test1")
        response.sendRedirect("test1");//所以会执行test/test1路径的控制层方法    
    }
}
@Controller
@RequestMapping("test")
public class test {    
    @RequestMapping("test2")    
    public void test2(HttpServletRequest request,HttpServletResponse response) throws Exception 
    {        
        System.out.println("test2方法执行了");
        //重定向到webapp根目录下的index.jsp文件,/不能省略
        //如果网址设置了项目名字为启动目录,则需要request.getContextPath()获取项目名字
        response.sendRedirect(request.getContextPath()+"/index.jsp");    
    }
}

2.1.3 直接指定响应结果

@Controller
@RequestMapping("test")
public class test {    
    @RequestMapping("test1")    
    public void test1(HttpServletResponse response) throws Exception {        					//直接响应json数据,并设置为utf-8支持中文显示
        response.setCharacterEncoding("utf-8");        											response.setContentType("application/json;charset=utf-8");        						response.getWriter().write("测试响应json串");    
	}
}

2.2返回值为String

2.2.1 无关键字

@Controller
@RequestMapping("test")
public class test {    
    @RequestMapping("test1")    
    public String test1() {
        //因为配置了视图解析器,所以此处会跳转到视图解析器的目录下的对应页面
        return "success";    
    }
}

2.2.2 forward关键字(请求转发)

@Controller
@RequestMapping("test")
public class test {
    @RequestMapping("test1")
    public String test1() {
        return "success";
    }

    @RequestMapping("test2")
    public String test2() {
    //return "forward:test1"; //请求转发,调用控制层的方法,此处test1指RequestMapping
    //return "forward:/index.jsp";//页面转发到webapp根目录下的index.jsp
    return "forward:/WEB-INF/pages/success.jsp";//页面转发到/WEB-INF/pages/success.jsp文件
	}
}

2.2.3 redirect关键字(重定向)

@Controller
@RequestMapping("test")
public class test {       
    @RequestMapping("test1")    
    public String test1() {        
        return "success";    
    }        
    @RequestMapping("test2")    
    public String test2() {        
       //return "redirect:/response.jsp";//页面重定向到webapp根目录下的response.jsp
       return "redirect:test1";//重定向,定向到指定控制层的方法,此处test1指RequestMapping
    }
}

2.3 重定向和页面跳转(转发)

2.3.1 区别

  • 转发使用的是getRequestDispatcher()方法; 重定向使用的是sendRedirect();

  • 转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;

  • 转发是服务器行为,重定向是客户端行为;

  • 转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;

  • 转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

  • 通过重定向无法访问WEB-INF中的资源,因为重定向是客户端行为,相当于浏览器重新输入URL,而WEB-INF中的内容无法通过输入URL来访问。

  • 重定向的流程是:当客户端向服务器发起请求时,服务器重新给客户端一个URL地址,让客户端重新发起一个新的请求,在这个过程中,客户端第一次请求所携带的头信息将消失,在重定向之后而且地址栏显示的是重定向的页面,这是一种客户端行为。

2.3.2 选择

  • 重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。

  • 因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。

  • 重定向还有一个应用场景:避免在用户重新加载页面时两次调用相同的动作。

    例如,当提交产品表单的时候,执行保存的方法将会被调用,并执行相应的动作;这在一个真实的应用程序中,很有可能将表单中的所有产品信息加入到数据库中。但是如果在提交表单后,重新加载页面,执行保存的方法就很有可能再次被调用。同样的产品信息就将可能再次被添加,为了避免这种情况,提交表单后,你可以将用户重定向到一个不同的页面,这样的话,这个网页任意重新加载都没有副作用;

  • 采用转发,则可以简单地将属性添加到Model,使得目标视图可以轻松访问。

  • 由于重定向经过客户端,所以Model中的一切都会在重定向时丢失,无法将值轻松地传递给目标页面

    • 在Spring3.1版本以后,我们可以通过Flash属性,解决重定向时传值丢失的问题

    • 需要在方法上添加一个新的参数类型:org.springframework.web.servlet.mvc.support.RedirectAttributes

      @RequestMapping(value="saveProduct",method=RequestMethod.POST)
      public String saveProduct(RedirectAttributes redirectAttributes){
        //传递参数
          //相当于在重定向链接地址追加传递的参数   重定向链接地址?key=value
        	redirectAttributes.addAttributie("key","value");
        	//这种方法是隐藏了参数,链接地址上不直接暴露
          redirectAttributes.addFlashAttribute("key","value");
      
        //执行重定向
        return "redirect:/……";
      }
      

重定向到控制器:

addAttribute :

@RequestMapping(value="hello")
public String test(RedirectAttributes ra){
    ra.addAttribute("key", "value");
    return "redirect:test";
}
@RequestMapping(value="test")
public String test(HttpServletRequest request){
    String test = request.getParameter("key");
     System.out.println(test);
	 return "redirect:/....";
}

addFlashAttribute :

@RequestMapping(value="hello")
public String test(RedirectAttributes ra){
    ra.addFlashAttribute("key", "value");
    return "redirect:test";
}
@RequestMapping(value="test")
public String test(@ModelAttribute("key")String test){
    System.out.println(test);
    return "redirect:/...";
}

2.4 结果视图

  • 在页面上获取值使用的是requestScope.key取的,所以返回ModelAndView类型时,浏览器跳转只能是请求转发。
@RequestMapping("/test")
public ModelAndView testModelAndView(){
    // 创建ModelAndView对象
    ModelAndView mv = new ModelAndView();
    // 将数据存入,前端可通过key获取value
    mv.addObject("key","value");
    // 跳转到哪个页面
    mv.setViewName("success");
    return mv;
}
@RequestMapping("/test")
public String testString(Model model){
    //model对象
    model.addAttribute("key","value");
    return "success";
}
springMVC
  • 作者:管理员(联系作者)
  • 发表时间:2019-11-21 23:17
  • 版权声明:自由转载-非商用-非衍生-保持署名(null)
  • undefined
  • 评论