SpringMvc的数据响应【二】

一:Springmvc的数据响应

响应形式分类如下

  • 1、页面跳转
    • 直接返回字符串
    • 通过ModelAndView对象返回
  • 2、直接响应数据(都不用去找页面的)
    • 直接返回字符串
    • 返回对象或集合 (本质上还是返回字符串)
1.1:演示环境搭建
步骤:
1.使用maven骨架创建一个javaweb工程
2.导入spring-context(基础包)和spring-webmvc(DispatcherServlet)
3.在web.xml中配置DispatcherServlet
4.写Controller,然后使用@Controller标注,
5.配置spring-mvc.xml文件
6.最终使用tomcat部署,找到Deployment -> 加号 -> 选择xxx:war exploded

注:
1、其实每一步都是有关联的,就像上面为什么要导入spring-context和spring-webmvc呢?
因为spring-context是一个基础包不仅是加载spring配置文件的时候需要它,而且就算使用后面的@Controller也是需要它的,那么spring-webmvc呢?因为第三步需要使用到DispatcherServlet,还由于使用了@controller,所以还需要在spring-mvc.xml中配置组件扫描,都是一些因为所以的关系!

2、有时候你使用一个东西的时候,你脑海中始终要有这几个疑问,它是干什么的,不用它行不行,不要一上来想都没想就直接配,就想我之前一样,在使用springmvc的时候,一股脑的把 web.xml中spring和springmvc配置一起配了,其实在演示springmvc的一些功能时,不用启动spring也可以

1.2:页面跳转
1.2.1:直接返回字符串
  • 情况一:没有配置InternalResourceViewResolver中的prefixsuffix参数的时候
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/mode1")
    public String mode1(){
        return "success.jsp";
    }

}

这时默认去webapp找该success.jsp页面,但是由于类上加了一个@RequestMapping("/user")

所以此时在浏览器上请求该地址的时候 https:localhost:8080/user/mode1,服务器会找

webapp/user/success.jsp 返回给客户端,找不到资源就返回404

  • 细节
1.其实视图解析器不用配置,默认就有,可以在DispatcherServlet.properties查看,而且就是InternalResourceViewResolver这个视图解析器,之所以一上来有时候就配置prefix和suffix,是为了开发的方便,但是有时候这样却导致很多人以为这东西是必须配置的,不配就不行。

2.InternalResourceViewResolver的父类中,可以查看到
public static final String REDIRECT_URL_PREFIX = "redirect:";
public static final String FORWARD_URL_PREFIX = "forward:";
private String prefix = "";
private String suffix = "";
  • 情况二:直接返回字符串的时候使用forwardredirect
@Controller
public class UserController {

    @RequestMapping("/mode1")
    public String mode1(){
        return "redirect:success.jsp";
    }

    @RequestMapping("/mode2")
    public String mode2(){
        return "success.jsp";
    }

    @RequestMapping("/mode3")
    public String mode3(){
        return "forward:success.jsp";
    }
}

其实这里都是找webapp/success.jsp的资源,mode1使用重定向所以浏览器地址栏会变化

而model2和model3访问后地址都不会发生变化,说明model2默认就是forward 的效果

  • 情况三:指定InternalResourceViewResolver中的prefixsuffix参数后
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>
@Controller
public class UserController {

    @RequestMapping("/mode1")
    public String mode1(){
        return "success";
    }
}    

因为配置了前缀和后缀,所以此时访问的资源路径是 /WEB-INF/jsp/success.jsp

1.2.2:通过ModelAndView对象返回
@Controller
public class UserController {

    @RequestMapping("/mode1")
    public ModelAndView mode1(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("success");
        mv.addObject("username","wzj");
        return mv;
    }

    @RequestMapping("/mode2")
    public String mode2(ModelAndView mv){
        mv.addObject("username","wzj");
        return "success";
    }

    @RequestMapping("/mode3")
    public String mode3(Model model){
        model.addAttribute("username","wzj");
        return "success";
    }

    @RequestMapping("/mode4")
    public String mode4(HttpServletRequest request){
        request.setAttribute("username", "wzj");
        return "success";
    }
}
  • success页面
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>SUCCESS</h1>
    ${username}
</body>
</html>

使用了EL表达式,注意加上isELIgnored="false" ,或者将web.xml中的头部声明更换为3.0,或者更高!一劳永逸

  • 分析
1. mode1中的mv.setViewName("success"); 
这里其实就是根据我们配置的视图解析的前缀和后缀去寻找的jsp

2.除了mode2,其他几个最终在页面都可以显示出${username}的值wzj

3.使用HttpServletRequest的时候需要导入servlet-api和jsp-api的

4.ModelAndView的变形写法还有很多,会一些常用的即可!
1.3:回写数据
1.3.1:直接返回字符串
@Controller
public class UserController {

    @RequestMapping("/mode1")
    public void mode1(HttpServletResponse response) throws IOException {
        response.getWriter().println("hello world");
    }

    @RequestMapping("/mode2")
    public String mode2(){
        return "hello world";
    }

    @RequestMapping("/mode3")
    @ResponseBody
    public String mode3(){
        return "hello world";
    }

    @RequestMapping("/mode4")
    @ResponseBody
    public String mode4(){
        return "{\"username:wzj\",\"password:123456\"}";
    }

    @RequestMapping("/mode5")
    @ResponseBody
    public String mode5() throws JsonProcessingException {
        User user = new User();
        user.setUsername("wzj");
        user.setPassword("123456");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(user);
        return jsonStr;
    }

    @RequestMapping("/mode6")
    @ResponseBody
    public User mode6(){
        User user = new User();
        user.setUsername("wzj");
        user.setPassword("123456");
        return user;
    }

    @RequestMapping("/mode7")
    @ResponseBody
    public List<User> mode7(){
        List<User> users = new ArrayList<>();

        User user1 = new User();
        user1.setUsername("wzj");
        user1.setPassword("123456");
        User user2 = new User();
        user2.setUsername("dyt");
        user2.setPassword("abcdef");

        users.add(user1);
        users.add(user2);
        return users;
    }
}
  • 方式一:使用HttpServletResponse

页面直接输出hello world,注意方法是无返回值类型void

  • 方式二:

页面报错404,找不到/WEB-INF/jsp/hello world.jsp,没加@ResponseBody,把hello world当成了一个逻辑视图名

  • 方式三:使用@ResponseBody

页面输出 hello world,因为加了@ResponseBody注解,它告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回

  • 方式四:输出json字符串
页面输出了{"username:wzj","password:123456"}
  • 方式五:手动使用jackson将对象转换为json字符串输出

因为我的方法返回值是String类型,不能返回一个对象,所以我们只能将对象转换为json串,怎么转换呢?

使用我们的jackson 当然这时需要导入jar包的!,本质上其实还是返回一个字符串,记得加@ResponseBody注解,不然它会把你这一堆字符串,当成一个逻辑视图名去找了,到时候又是404的节奏

 <!--jackson-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>
  • 方式六

每次返回对象的时候,都需要转换为手动转换为json字符串这么麻烦,其实这么通用的东西,作为springmvc框架,它早就为你想好了,只需在RequestMappingHandlerAdapter中配置一下HttpMessageConverter接口的实现类MappingJackson2HttpMessageConverter消息转换器即可,就会自动将你的对象返回成json串

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter{

	private List<HttpMessageConverter<?>> messageConverters;
	public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        this.messageConverters = messageConverters;
    }
}

可以参照以上代码进行set注入等配置,RequestMappingHandlerAdapter不是自定义bean,所以一般就使用bean标签进行配置了

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
        </list>
    </property>
</bean>
  • 方式七:将List转换成字符串

  • 注意:其实可以使用<mvc:annotation-driven/>去代替上面配置的MappingJackson2HttpMessageConverter

<mvc:annotation-driven/>
1.<mvc:annotation-driven/>的作用:
在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用<mvc:annotation-driven>自动加载 RequestMappingHandlerMapping(处理映射器)和
RequestMappingHandlerAdapter( 处 理 适 配 器 )而且默认底层就会集成jackson进行对象或集合的json格式字符串的转换

注:在这里启动服务器时抛出一个异常,Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘cacheManager’ available,最终是mvc的命名空间和约束搞错了,TMD的这个xml要不报错提示,找了半天!

最后:来自虽然帅,但是菜的cxy,创作不易,给点鼓励。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值