文档章节

SpringMVC简单构造restful, 并返回json

未眠
 未眠
发布于 2014/12/04 15:42
字数 1926
阅读 75016
收藏 130

 

文章要要点:

  1. 快速搭建构造restful的StringMvc

  2. GET, POST , PUT , DELETE的各种调用

  3. 同一资源 多种表述 (ContentNegotiatingViewResolver解析器),既可以返回对象给JSP, 也可以返回JSON

快速搭建构造restful的StringMvc

首现搭建一个简单的restfulMvc框架,  并上配置文件, 后期会增加带JSON返回值的配置

JAR包

web.xml配置

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/spring-servlet.xml</param-value><!-- 现定义为src下config包里(个人习惯) -->
    </init-param>
    <load-on-startup>1</load-on-startup>
   </servlet>
  
 <servlet-mapping>
     <servlet-name>spring</servlet-name>
     <url-pattern>/api/*</url-pattern>
 </servlet-mapping>
 
 <!-- Spring配置 -->
 <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 
 <!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
 <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:config/applicationContext-*.xml</param-value>
 </context-param>

spring-servlet.xml配置

 <!<beans xmlns="http://www.springframework.org/schema/beans"  
 xmlns:context="http://www.springframework.org/schema/context"  
 xmlns:p="http://www.springframework.org/schema/p"  
 xmlns:mvc="http://www.springframework.org/schema/mvc"  
 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-3.0.xsd  
      http://www.springframework.org/schema/context  
      http://www.springframework.org/schema/context/spring-context.xsd  
      http://www.springframework.org/schema/mvc  
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
      
       <!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射-->  
  <mvc:annotation-driven />  
  <!-- 启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean -->  
  <context:component-scan base-package="com.esb" />  
      
  <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->  
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
      
</beans>

applicationContext.xml暂时没写东西

该配置的配置完了,下面就是写第一个HelloWord

package com.dsp.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Scope("prototype")
@Controller
@RequestMapping("/products")
public class TestController{
 
 /**
  * 测试方法,HelloWord
  * @param request
  * @param response
  * @return
  * @throws Exception
  */
 @RequestMapping(value="/list",method=RequestMethod.GET)
    public String getProducts(HttpServletRequest request,HttpServletResponse response) throws Exception {
  
        request.setAttribute("name", "helloWord");
        
        return "products/list";
        
    }
}

@Scope("##") : spring默认的Scope是单列模式(singleton),顾名思义,肯定是线程不安全的.  而@Scope("prototype")

    可以保证每个请求都会创建一个新的实例,  还有几个参数: session  request

    @Scope("session")的意思就是,只要用户不退出,实例就一直存在,

    request : 就是作用域换成了request

@Controller : 不多做解释 , 标注它为Controller

@RequestMapping :是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是   以该地址作为父路径。 比如现在访问getProducts方法的地址就是 :

   http://localhost:8080/项目名/上面web.xml配置(api)/products/list

  l

暂时先介绍两个属性 value和method

具体可以参考我参考的文章 http://blog.sina.com.cn/s/blog_72827fb10101pl9i.html

value: 就是映射的实际地址,这个上面有说过,  而重要的是里面的值 , 有几个比较感兴趣的

   1. 正常的 /list                          访问地址类似 http://localhost:8080/项目名/api/products/list

   2. 带参数的 /info/{proId}          访问地址类似 http://localhost:8080/项目名/api/products/info/0001

method: 请求的method类型 GET POST PUT DELETE等

好,做个测试 JSP代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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> 你好</title>
</head>
<body>
${name }
</body>
</html>

地址栏输入 http://localhost:8080/RestFulMvc/api/products/list

得到结果

 

 

GET, POST , PUT , DELETE的各种调用

刚才写的是第一种GET, 第二种GET:

@RequestMapping(value="/info/{proId}",method=RequestMethod.GET)
    public String getProductInfo(@PathVariable String proId, HttpServletRequest request,HttpServletResponse response) throws Exception {
  
          request.setAttribute("name", proId);
          
          return "products/list";
        
    }

@PathVariable注解获取的就是大括号里的值

测试 : 输入地址 http://localhost:8080/RestFulMvc/api/products/info/00001

测试结果为

如果不用@PathVariable接收大括号里的值,也可以用bean来接收:

public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response)...

而且也可以设置多个参数

@RequestMapping(value="/info/{pid}/{pname}",method=RequestMethod.GET)

让我们看下面这段代码

@RequestMapping(value="/info/{pid}/{pname}",method=RequestMethod.GET)
    public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception {
  
  request.setAttribute("name", pro.getPid()+"___"+pro.getPname());
  
  return "products/list";
        
    }

访问地址: http://localhost:8080/RestFulMvc/api/products/info/00001/23123

得到的结果为 :

 

下面介绍POST的调用

list.jsp新增form表单如下

<body>
    ${name }
    <form action="<%=basePath%>/api/products/info" method="post">
         <input type="text" name="pid"/> 
         <input type="text" name="pname"/> 
         <input type="submit"/>
    </form>
</body>

JAVA代码

@RequestMapping(value="/info",method=RequestMethod.POST)
    public String insertProduct(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception {
  
        request.setAttribute("name", pro.getPid()+"___"+pro.getPname());
        
        return "products/list";
        
    }

form提交后结果为

执行成功.

正常的FORM提交 , 只需要用对象接就可以了

 

补上 PUT DELETE 就和表单不一样了, 因为表单只支持GET和POST

这时候就需要用到ajax,  或者nodejs调用

贴上jsp代码

<script type="text/javascript" src='<%=basePath%>/public/js/jquery-2.1.0.min.js'></script>
<script type="text/javascript">
function savepro(){
 var saveData = {"pid":"aa"}; //发送给服务器的JSON
 $.ajax({
  type : "PUT",
  url : "/RestFulMvc/api/products/info.json",
  data:JSON.stringify(saveData),
  contentType:"application/json",  //发送至服务器的类型
  dataType : "json",     //预期服务器返回类型
  success: function(data){
   alert(data);
  }
  
 })
}
</script>
</head>
<body>
<div>
 <input type="button" value="保存" onclick="savepro()"/>
</div>
</body>

 后台代码

@RequestMapping(value="/info",method=RequestMethod.PUT)
    public ModelAndView updateProduct(@RequestBody Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception {
  
  Map<String,Object> map1 = new HashMap<String,Object>();
  map1.put("pid", pro.getPid());
  
  ModelAndView mav=new ModelAndView("products/list",map1);
  
  return mav;
        
    }

和以往不一样的是, 后台接收参数的对象前面 加了个@RequestBody , 这个是用于把传来的JSON 转换成接收的对象, 如果是form提交就不需要了, 但如果前台用的是application/json类型传进来,就一定要加@RequestBody

得到的结果:

 

同一资源 多种表述

如果写完一个方法,返回request到JSP, 可同时手机端需要调接口怎么办, 如果前台的一层皮换成了以nodejs为服务的框架调用怎么办

可以每个需求再写一个方法返回JSON, 可下面这个可以同一资源,多种返回

spring-servlet.xml加入如下配置

 <!-- ContentNegotiatingViewResolver视图解析器,利用他就可以配置多种返回值 -->
 <bean  class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">   
      
   <!-- 这里是否忽略掉accept header,默认就是false -->
   <property name="ignoreAcceptHeader" value="true" />   
   
   <!-- 如果所有的mediaType都没匹配上,就会使用defaultContentType -->
   <property name="defaultContentType" value="text/html" />   
   
   <property name="mediaTypes">    
    <map>     
     <entry key="json" value="application/json" />      
     <entry key="xml" value="application/xml" />      
    </map>    
   </property>   
  <!-- 默认使用MappingJacksonJsonView生成jsonview-->
  <property name="defaultViews">    
    <list>     
     <bean  class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">        
         <property  name="extractValueFromSingleKeyModel" value="true" />     
      </bean>        
      <bean  class="org.springframework.web.servlet.view.xml.MarshallingView">      
       <property name="marshaller">        
        <bean  class="org.springframework.oxm.xstream.XStreamMarshaller" />        
      </property>      
      </bean>      
     </list>     
    </property>  
  </bean>

 

这样同一个地址,只要在后面加 .json  mediaTypes就可以把 http://localhost:8080/RestFulMvc/api/products/info/00001/23123.json 的 .json映射到application/json

值得注意的是, 如果不加 <property  name="extractValueFromSingleKeyModel" value="true" />

得出来的Product对象的JSON为

{"product":{"pid":"00001","pname":"23123"}}

如果想要的结果为

{"pid":"00001","pname":"23123"}

则不要前面的对象名称包在外面时, 请加上它

 

后台代码

@RequestMapping(value={"/info/{pid}"},method=RequestMethod.GET)
    public ModelAndView getProductInfo(@PathVariable String pid, HttpServletRequest request,HttpServletResponse response) throws Exception {
  
          Map<String,Object> map = new HashMap<String,Object>();
          
          Product pro = new Product();
          pro.setPid(pid);
          map.put("name", pid);
          map.put("pro", pro);
          
          ModelAndView mav=new ModelAndView("products/list",map);
          
          return mav;
        
    }

 

测试: 输入地址 :  http://localhost:8080/RestFulMvc/api/products/info/00001.json

 

得到的结果为

{"pro":{"pid":"00001","pname":null},"name":"00001"}

 

ModelAndView是springmvc自带的重定向方法

第一个参数是返回的地址,和以往一样,  第二个参数以后, 是传给前台的值 .

如果有第二个参数, 没有第三个参数 , 那第二个参数只能是map的

也可以第二个参数为建, 第三个参数为值的方式传给前台,  具体大家可以new一个ModelAndView看看它提供的构造方法

 

 

最后 如果是nodejs  ajax提交的数据,以application/json格式提交时,

接收参数可以在参数前加 @@RequestBody

public ModelAndView getProductInfo(@RequestBody Product pro, HttpServletRequest request .....

它可以把json转换为对象里的属性

© 著作权归作者所有

未眠
粉丝 8
博文 2
码字总数 2326
作品 0
大连
私信 提问
加载中

评论(24)

惢焱
惢焱
那啥??移动端通过form把数据传给后台服务,那后台服务返回的Json数据(我们约定的是json)不是放在form里传回给移动端么??是直接把json数据发还给移动端这边么??求指导
J
JGX
@RequestMapping(value="/info/{pid}/{pname}",method=RequestMethod.GET)
public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception {

request.setAttribute("name", pro.getPid()+"___"+pro.getPname());

return "products/list";

}
这种方法,为什么我用pro里面的值是null?是不是少配置了什么?
楼主能把Product代码贴出来吗
t
tosswang
楼主讲的不错
t
tosswang
请教作者,讲解PUT那个贴了一段jsp代码,那个访问地址应该是这几访问jsp吧,当我点击保存后,总是报:
"NetworkError: 415 Unsupported Media Type - http://localhost:8087/restFirst/api/products/info.json"
嘛毛病???
公子玄襄
put 使用ajax提交后 返回的ModelAndView mav 是个页面呀 虽然访问成功 页面执行的是error
l
lsl666
你好,你这个简单搭建用到了数据库吗?我想在SSM基础上搭建该怎么做呢
Legend1988
Legend1988
请问,这种方式写的restful服务能供其他项目调用吗?求指导啊
看日出的狼

引用来自“Evici-Ho”的评论

你好!
@RequestMapping(value="/info/{pid}/{pname}",method=RequestMethod.GET)
public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception {

request.setAttribute("name", pro.getPid()+"___"+pro.getPname());

return "products/list";

}
这种方法,为什么我用pro里面的值是null?是不是少配置了什么?
我的对象也是null,你的问题解决了么?
E
Evici-Ho
你好!
@RequestMapping(value="/info/{pid}/{pname}",method=RequestMethod.GET)
public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception {

request.setAttribute("name", pro.getPid()+"___"+pro.getPname());

return "products/list";

}
这种方法,为什么我用pro里面的值是null?是不是少配置了什么?
CoderDream
CoderDream
如果弄个Maven就更好了!
基于 Spring Boot 2.0 构建一个 RESTful WebService

REST 全称是 Representational State Transfer,中文意思是“表述性状态转移”。RESTful 是关于 Web 的现有特征和使用方式的一些准则和约束。 基于 Spring MVC 的 RestController,我们可以方...

摆码王子
2018/04/17
0
0
SpringMVC常见面试题总结【概念】

什么是Spring MVC?介绍你对SpringMVC的理解。 springmvc是一个基于java实现了mvc设计模式的轻量级web框架,通过把model,view,controller分离,将web层进行解耦,把复杂的web应用分成几部分...

薛小二
05/24
0
0
Hasor-Web v0.0.1 发布 轻量级Java Web 框架

首先引用Wiki的介绍一下Hasor: “Hasor是一款开源框架。它是为了解决企业模块化开发中复杂性而创建的。Hasor遵循简单的依赖、单一职责,在开发多模块企业项目中更加有调理。然而Hasor的用途...

哈库纳
2013/09/30
498
0
使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务

Spring,构建 Java™ 平台和 Enterprise Edition (Java EE) 应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller ,MVC)层支持具象状态传输 (REST)。RESTful web 服务根据...

IBMdW
2011/08/05
5.2K
2
【转】使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务

简介: Spring,构建 Java™ 平台和 Enterprise Edition (Java EE) 应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller ,MVC)层支持具象状态传输 (REST)。RESTful web...

老盖
2011/08/25
2.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

优雅的关闭Spring Boot

优雅的关闭Spring Boot 1、实现 TomcatConnectorCustomizer 接口拿到Tomcat的连接获取 Tomcat连接池 2、实现 ApplicationListener<ContextClosedEvent> 监听服务器关闭事件,注册JVM钩子函数...

sowhat
今天
2
0
Python3-Web开发

简介 Web开发框架 什么是Web框架? Web应用程序框架或简单的Web框架表示一组库和模块,使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。 virtualenv是一个虚拟...

wuxinshui
今天
3
0
使用技媒体实践编写发布博客

技媒体实践博客 CSDN OSChina 知乎 简书 思否 掘金 51CTO

晨猫
今天
2
0
Lucene

1、什么是全文检索 数据分类 我们生活中的数据总体分为两种:结构化数据和非结构化数据。 结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。 非结构化数据:指不定长或无固...

榴莲黑芝麻糊
昨天
5
0
python到setuptools、pip工具的安装

python安装 基础开发库   apt-get install gcc  apt-get install openssl libssl-dev 安装数据库和开发库   apt-get install mysql-server libmysqld-dev python环境   下载地址...

问题终结者
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部