GVKun编程网logo

golang http request 读两次body(golang conn.read)

5

在本文中,我们将给您介绍关于golanghttprequest读两次body的详细内容,并且为您解答golangconn.read的相关问题,此外,我们还将为您提供关于@RequestBody和@Re

在本文中,我们将给您介绍关于golang http request 读两次body的详细内容,并且为您解答golang conn.read的相关问题,此外,我们还将为您提供关于@RequestBody 和 @ResponseBody 的使用情形以及 RestTemplate 的 http 报文转换、@RequestBody对象为空,异常Required request body is missing错误解决、@RequestMapping @ResponseBody 和 @RequestBody 注解的用法与区别、@RequestMapping @ResponseBody 和 @RequestBody 用法与区别的知识。

本文目录一览:

golang http request 读两次body(golang conn.read)

golang http request 读两次body(golang conn.read)

方法是body重新赋值,

bodyBytes,_ := IoUtil.ReadAll(req.Body)
req.Body.Close()  // must close
req.Body = IoUtil.nopCloser(bytes.NewBuffer(bodyBytes))

看了三个网页,都是这样做的:
https://stackoverflow.com/questions/46948050/how-to-read-response-body-twice-in-golang-middleware
https://medium.com/@xoen/golang-read-from-an-io-readwriter-without-loosing-its-content-2c6911805361
http://blog.manugarri.com/how-to-reuse-http-response-body-in-golang/

@RequestBody 和 @ResponseBody 的使用情形以及 RestTemplate 的 http 报文转换

@RequestBody 和 @ResponseBody 的使用情形以及 RestTemplate 的 http 报文转换

@RequestBody 和 @ResponseBody 两个注解,分别完成请求报文到对象和对象到响应报文的转换。

@RequestBody

1、@requestBody 注解常用来处理 content-type 不是默认的 application/x-www-form-urlcoded 编码的内容,

比如说:application/json 或者是 application/xml 等。一般情况下来说常用其来处理 application/json 类型。

作用:

  • 注解用于将 Controller 的方法参数,根据 HTTP Request Header 的 content-Type 的内容,通过适当的 HttpMessageConverter 转换为 JAVA 类
  • 再把 HttpMessageConverter 返回的对象数据绑定到 controller 中方法的参数上。

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

 

2、通过 @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 ! ");
        }
    });

    @requestMapping("/login")
    public void login(@requestBody String userName,@requestBody String pwd){
      System.out.println(userName+""+pwd);
    }

这种情况是将 JSON 字符串中的两个变量的值分别赋予了两个字符串,但是呢假如我有一个 User 类,拥有如下字段:
 String userName;
 String pwd;
那么上述参数可以改为以下形式:@requestBody User user 这种形式会将 JSON 字符串中的值赋予 user 中对应的属性上
需要注意的是,JSON 字符串中的 key 必须对应 user 中的属性名,否则是请求不过去的。

另外这里要注意其实 @RequestBody 接收的是一个 Json 对象的字符串,而不是一个 Json 对象。

Json 对象和 Json 字符串的区别就是有没有定义的时候有没有单引号的。。。

如果 ajax 请求传的是 Json 对象,后来用 JSON.stringify (data) 的方式就能将对象变成字符串。

同时 ajax 请求的时候也要指定 dataType: "json",contentType:"application/json" 这样就可以轻易的将一个对象或者 List 传到 Java 端,使用 @RequestBody 即可绑定对象或者 List.。

<script type="text/javascript">  
    $(document).ready(function(){  
        var saveDataAry=[];  
        var data1={"userName":"test","address":"gz"};  
        var data2={"userName":"ququ","address":"gr"};  
        saveDataAry.push(data1);  
        saveDataAry.push(data2);         
        $.ajax({ 
            type:"POST", 
            url:"user/saveUser", 
            dataType:"json",      
            contentType:"application/json",               
            data:JSON.stringify(saveData), 
            success:function(data){ 
                                       
            } 
         }); 
    });  
</script>

参考博客:json 对象、json 字符串的区别和相互转换

 

@ResponseBody

该注解用于将 Controller 的方法返回的对象,根据 HTTP Request Header 的 Accept 的内容,

通过适当的 HttpMessageConverter 转换为指定格式后,写入到 Response 对象的 body 数据区。

通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP 响应正文中。 

 

HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信。但是,使用 Spring,controller 类中的方法返回纯 ‘String’ 类型和域模型(或其他 Java 内建对象)。

如何将对象序列化 / 反序列化为原始文本?这由 HttpMessageConverter 处理。

Http 请求和响应报文本质上都是一串字符串,当请求报文来到 java 世界,它会被封装成为一个 ServletInputStream 的输入流,供我们读取报文。响应报文则是通过一个 ServletOutputStream 的输出流,来输出响应报文。

我们从流中,只能读取到原始的字符串报文,同样,我们往输出流中,也只能写原始的字符。

而在 java 世界中,处理业务逻辑,都是以一个个有业务意义的对象为处理维度的,那么在报文到达 SpringMVC 和从 SpringMVC 出去,都存在一个字符串到 java 对象的阻抗问题。

这一过程,不可能由开发者手工转换。我们知道,在 Struts2 中,采用了 OGNL 来应对这个问题,而在 SpringMVC 中,它是 HttpMessageConverter 机制。

请看:

SpringMVC 源码剖析(五)- 消息转换器 HttpMessageConverter

HttpMessageConverter(消息转换器 )和 @responsebody 使用

 

RestTemplate 中 http 报文转换处理

在 RestTemplate 中,

我们知道,调用 reseful 接口传递的数据内容是 json 格式的字符串,返回的响应也是 json 格式的字符串。

然而 restTemplate.postForObject 方法的请求参数 RequestBean 和返回参数 ResponseBean 却都是 java 类。是 RestTemplate 通过 HttpMessageConverter 自动帮我们做了转换的操作。

默认情况下 RestTemplate 自动帮我们注册了一组 HttpMessageConverter 用来处理一些不同的 contentType 的请求。

StringHttpMessageConverter 来处理 text/plain;MappingJackson2HttpMessageConverter 来处理 application/json;MappingJackson2XmlHttpMessageConverter 来处理 application/xml

你可以在 org.springframework.http.converter 包下找到所有 spring 帮我们实现好的转换器。

如果现有的转换器不能满足你的需求,你还可以自己实现。

请看:如何使用 RestTemplate 访问 restful 服务

注意:

StringHttpMessageConverter 默认使用的字符集是 ISO-8859-1,在遇到中文的时候会有乱码,所以需要移除 RestTemplate 默认的 StringHttpMessageConverter 修改字符字符集后重新设置。

spring 的 json 转换器默认使用的是 Jackson,json 字符串和对应的 Entity 如果有字段对不上就会报错,这个有点不符合国情,而 FastJson 则不会报错,所以很多时候都会用 FastJSON 替换默认的 Jackson。

配置示例:

@Configuration
public class RestAutoConfig {

    public static class RestTemplateConfig {

        @Bean//负载均衡的restTemplate
        @LoadBalanced //spring 对restTemplate bean进行定制,加入loadbalance拦截器进行ip:port的替换
                    //"http://user/getusername,就能解析成http://127.0.0.1:8083//getusername
        RestTemplate lbRestTemplate(HttpClient httpclient) {
            RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpclient));
            template.getMessageConverters().add(0,new StringHttpMessageConverter(Charset.forName("utf-8")));
            template.getMessageConverters().add(1,new FastJsonHttpMessageConvert5());
            return template;
        }
        
        @Bean //直连的restTemplat,这时只能使用http://127.0.0.1:8083//getusername地址,不能解析http://user/getusername
        RestTemplate directRestTemplate(HttpClient httpclient) {
            RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpclient));
            template.getMessageConverters().add(0,new StringHttpMessageConverter(Charset.forName("utf-8")));
            template.getMessageConverters().add(1,new FastJsonHttpMessageConvert5());
            return template;
        }
        
        // FastJsonHttpMessageConvert4有一个bug,它是默认支持MediaType.ALL,spring在处理MediaType.ALL的时候会识别成字节流,而不是json,这里就对他进行改造和处理
         public static class FastJsonHttpMessageConvert5 extends FastJsonHttpMessageConverter4{
              
              static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
              
                  public FastJsonHttpMessageConvert5(){
                setDefaultCharset(DEFAULT_CHARSET);
                setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON,new MediaType("application","*+json")));
              }

            }
    }

}
View Code

HTTPclient Bean 获取类:

@Configuration
@ConditionalOnClass({HttpClient.class})
@EnableConfigurationProperties(HttpClientProperties.class)
public class HttpClientAutoConfiguration {

    private final HttpClientProperties properties;
    
    
    public HttpClientAutoConfiguration(HttpClientProperties properties){
        this.properties = properties;
    }
    
    /**
     * httpclient bean 的定义
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(HttpClient.class)
    public HttpClient httpClient() {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(properties.getConnectTimeOut())
                .setSocketTimeout(properties.getSocketTimeOut()).build();// 构建requestConfig
        HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
                .setUserAgent(properties.getAgent())
                .setMaxConnPerRoute(properties.getMaxConnPerRoute())
                .setMaxConnTotal(properties.getMaxConnTotaol())
                .build();
        return client;
    }
}
View Code

HTTPClient 参数类:

@ConfigurationProperties(prefix="spring.httpclient")
public class HttpClientProperties {
    
    private Integer connectTimeOut = 1000;
    
    private Integer socketTimeOut = 1000000;

    private String agent = "agent";
    private Integer maxConnPerRoute = 10;
    private Integer maxConnTotaol   = 50;
    public Integer getConnectTimeOut() {
        return connectTimeOut;
    }
    public void setConnectTimeOut(Integer connectTimeOut) {
        this.connectTimeOut = connectTimeOut;
    }
    public Integer getSocketTimeOut() {
        return socketTimeOut;
    }
    public void setSocketTimeOut(Integer socketTimeOut) {
        this.socketTimeOut = socketTimeOut;
    }
    public String getAgent() {
        return agent;
    }
    public void setAgent(String agent) {
        this.agent = agent;
    }
    public Integer getMaxConnPerRoute() {
        return maxConnPerRoute;
    }
    public void setMaxConnPerRoute(Integer maxConnPerRoute) {
        this.maxConnPerRoute = maxConnPerRoute;
    }
    public Integer getMaxConnTotaol() {
        return maxConnTotaol;
    }
    public void setMaxConnTotaol(Integer maxConnTotaol) {
        this.maxConnTotaol = maxConnTotaol;
    }
    
    
    
}
View Code

 



 

@RequestBody对象为空,异常Required request body is missing错误解决

@RequestBody对象为空,异常Required request body is missing错误解决

<divid="content_views"> <h2><a name="t0"></a><strong>1.异常</strong></h2><p><span><strong>org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing</strong></span><br></p><h1><a name="t1"></a><span><strong><span>情况一、</span></strong></span></h1><h2><a name="t2"></a><span><strong><span>2.问题展示</span></strong></span></h2><p></p><pre><code><ol><li><div><divdata-line-number="1"></div></div><div><div><span>@RequestMapping(value = <span>"/somewhere"</span>, method = POST)</span></div></div></li><li><div><divdata-line-number="2"></div></div><div><div><span>public</span> SomeResponse someHandler(<span>@RequestBody</span> XXXDTO xxxDTO) { ... }</div></div></li><li><div><divdata-line-number="3"></div></div><div><div> </div></div></li><li><div><divdata-line-number="4"></div></div><div><div>当入参DTO对象为空时,</div></div></li></ol></code><divdata-title="登录后复制" onclick="hljs.signin(event)"></div></pre><pre><code><span>@RequestBody</span></code>对应http请求body,<span>当请求body为空时,异常!</span> <span>org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing:</span> public com.rpc.common.Result&lt;com.rpc.common.dto.PageDto&lt;com.order.dto.OrderListDTO&gt;&gt; com.gateway.controller.OrderController.listOrder(com.*.*.order.dto.ListOrderPageDTO) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:154) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:128) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) <divdata-title="登录后复制" onclick="hljs.signin(event)"></div></pre><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)</p><p></p><div><pre><span> 1</span> <span>@Override </span><span> 2</span> <span>protected</span> &lt;T&gt;<span> Object <span>readWithMessageConverters</span>(NativeWebRequest webRequest, MethodParameter parameter, </span><span> 3</span> Type paramType) <span>throws</span><span> IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException { </span><span> 4</span> <span> 5</span> HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.<span>class</span><span>); </span><span> 6</span> ServletServerHttpRequest inputMessage = <span>new</span><span> ServletServerHttpRequest(servletRequest); </span><span> 7</span> <span> 8</span> Object arg =<span> readWithMessageConverters(inputMessage, parameter, paramType); </span><span> 9</span> <span>if</span> (arg == <span>null</span><span>) { </span><span>10</span> <span>if</span><span> (<span>checkRequired</span>(parameter)) { </span><span>11</span> <span>throw</span> <span>new</span> HttpMessageNotReadableException("<span>Required request body is missing:</span> " + <span>12</span> <span> parameter.getMethod().toGenericString()); </span><span>13</span> <span> } </span><span>14</span> <span> } </span><span>15</span> <span>return</span><span> arg; </span><span>16</span> <span> } </span><span>17</span> <span>18</span> <span>protected</span> <span>boolean</span><span><span> checkRequired</span>(MethodParameter parameter) { </span><span>19</span> <span>return</span> (parameter.getParameterAnnotation(RequestBody.<span>class</span>).<span>required</span>() &amp;&amp; !<span>parameter.isOptional()); </span><span>20</span> }</pre><div><span><a title="复制代码"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div><p>看上图,最终是RequestBody注解的<span>required</span>属性。!parameter.isOptional()代表是否支持null,如果参数类型支持null,则是false,最终不用校验required.</p><div><div><span><a title="复制代码"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div><pre><span> 1</span> <span>public</span> @<span>interface</span><span> RequestBody { </span><span> 2</span> <span> 3</span> <span>/**</span> <span> 4</span> <span> * Whether body content is required. </span><span> 5</span> <span> * &lt;p&gt;Default is {</span><span>@code</span><span> true}, leading to an exception thrown in case </span><span> 6</span> <span> * there is no body content. Switch this to {</span><span>@code</span><span> false} if you prefer </span><span> 7</span> <span> * {</span><span>@code</span><span> null} to be passed when the body content is {</span><span>@code</span><span> null}. </span><span> 8</span> <span> * </span><span>@since</span><span> 3.2 </span><span> 9</span> <span>*/</span> <span>10</span> <span>boolean</span> required() <span>default</span> <span>true</span><span>; </span><span>11</span> <span>12</span> }</pre><div><span><a title="复制代码"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div><p>看上图,默认是true.我们只需要@RequestBody&nbsp;(required=false)</p><h2><a name="t3"></a><strong>3.解决办法</strong></h2><p></p><p><strong><span>1)@RequestBody (required=false)</span></strong></p><p><span>&nbsp;</span></p><p><span><strong>2) 不要让DTO对象为空</strong></span></p><p><span><strong><br></strong></span></p><h1><a name="t4"></a><strong><span>情况二、</span></strong></h1><p></p><p><span>springMvc的新注解:GetMapping 不支持@RequestBody ,使用PostMapping后面我改成以下代码就没有报错了</span></p><p><span>@PostMapping</span><span>(value=</span><span>"/schedules/findUserSchedule"</span><span>,produces = MediaType.APPLICATION_JSON_VALUE) </span></p><p><span>public</span><span> List&lt;xxxxxx&gt; </span><span>findUser</span><span>(@RequestBody xxxxxx xxxxx) {</span></p><p><span> log.debug(</span><span>"查询用户日程"</span><span>, xxxxxx); </span></p><p><span> }</span></p><p><span><span><strong>或者是使用了get提交方式</strong></span></span></p><h1><a name="t5"></a><span><span>情况三:</span></span></h1><p><span><strong>如果不是因为上面的两种情况,</strong></span></p><p><span><strong>请看这里:</strong></span></p><p><strong><span></span></strong></p><pre><span>我们在传输json数据的时候,假如json数据为空,那么就会报一个错误,就是Required request body is missing 这个的意思就是我们这个接口必须要传输json格式的数据,假如没有数据,就会报错返回错误的信息。</span></pre> 原文地址:https://blog.csdn.net/q1035331653/article/details/80370818 </div>

@RequestMapping @ResponseBody 和 @RequestBody 注解的用法与区别

@RequestMapping @ResponseBody 和 @RequestBody 注解的用法与区别

1.@RequestMapping

国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法,此处需注意@RequestMapping用在类上可以没用,但是用在方法上必须有。

@RequestMapping("/verifyCode")
    public void verifyCode(HttpServletResponse response, HttpSession session){
        response.setDateHeader("Expires", -1);
        response.setHeader("Cache-Control", "no-cache");

        VerifyCode vc = new VerifyCode();
        try {
            vc.drawImage(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        String code = vc.getCode();
        session.setAttribute("code", code);
        System.out.println(code);

    }

 

2.@ResponseBody

@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。 
作用: 
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。 
使用时机: 
返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;


@ResponseBody
public void activeUser(String userId, String activecode, HttpServletResponse response){
userInfoService.activeUser(userId, activecode);
// 定时刷新
response.setContentType("text/html;charset=utf-8");
try {
response.getWriter().write("激活成功,3秒之后回到登录界面进行登录...");
response.setHeader("refresh", "3;url=/login");

} catch (IOException e) {
e.printStackTrace();
}
}

3.@RequestBody

@RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

作用:

1) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上; 
2) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

@RequestMapping @ResponseBody 和 @RequestBody 用法与区别

@RequestMapping @ResponseBody 和 @RequestBody 用法与区别

1.@RequestMapping

国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法,此处需注意@RequestMapping用在类上可以没用,但是用在方法上必须有

例如:

@Controller
//设置想要跳转的父路径
@RequestMapping(value = "/Controllers")
public class StatisticUserCtrl {
    //如需注入,则写入需要注入的类
    //@Autowired

            // 设置方法下的子路经
            @RequestMapping(value = "/method")
            public String helloworld() {

                return "helloWorld";

            }
}

原理也非常好了解,其对应的 action 就是“ (父路径) controller/(父路径下方法路经)method ”。因此,在本地服务器上访问方法 http://localhost:8080/controller/method 就会返回(跳转)到“ helloWorld.jsp ”页面。

说到这了,顺便说一下 @PathVariable 注解,其用来获取请求路径(url )中的动态参数。

页面发出请求:

function login() {
    var url = "${pageContext.request.contextPath}/person/login/";
    var query = $(''#id'').val() + ''/'' + $(''#name'').val() + ''/'' + $(''#status'').val();
    url += query;
    $.get(url, function(data) {
        alert("id: " + data.id + "name: " + data.name + "status: "
                + data.status);
    });
}

如:

/**
* @RequestMapping(value = "user/login/{id}/{name}/{status}") 中的 {id}/{name}/{status}
* 与 @PathVariable int id、@PathVariable String name、@PathVariable boolean status
* 一一对应,按名匹配。
*/

@RequestMapping(value = "user/login/{id}/{name}/{status}")
@ResponseBody
//@PathVariable注解下的数据类型均可用
public User login(@PathVariable int id, @PathVariable String name, @PathVariable boolean status) {
//返回一个User对象响应ajax的请求
    return new User(id, name, status);
}

ResponseBody

@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。 
作用: 
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。 
使用时机: 
返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

当页面发出异步请求:

function login() {
    var datas = ''{"username":"'' + $(''#username'').val() + ''","userid":"'' + $(''#userid'').val() + ''","status":"'' + $(''#status'').val() + ''"}'';
    $.ajax({
        type : ''POST'',
        contentType : ''application/json'',
        url : "${pageContext.request.contextPath}/user/login",
        processData : false,
        dataType : ''json'',
        data : datas,
        success : function(data) {
            alert("userid: " + data.userid + "username: " + data.username + "status: "+ data.status);
        },
        error : function(XMLHttpRequest, textStatus, errorThrown) {
            alert("出现异常,异常信息:"+textStatus,"error");
        }
    });
};

如:

@RequestMapping(value = "user/login")
@ResponseBody
// 将ajax(datas)发出的请求写入 User 对象中,返回json对象响应回去
public User login(User user) {   
    User user = new User();
    user .setUserid(1);
    user .setUsername("MrF");
    user .setStatus("1");
    return user ;
}

步获取 json 数据,加上 @Responsebody 注解后,就会直接返回 json 数据。

@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指定;

例如:

@RequestMapping(value = "user/login")
@ResponseBody
// 将ajax(datas)发出的请求写入 User 对象中
public User login(@RequestBody User user) {   
// 这样就不会再被解析为跳转路径,而是直接将user对象写入 HTTP 响应正文中
    return user;    
}

我们今天的关于golang http request 读两次bodygolang conn.read的分享已经告一段落,感谢您的关注,如果您想了解更多关于@RequestBody 和 @ResponseBody 的使用情形以及 RestTemplate 的 http 报文转换、@RequestBody对象为空,异常Required request body is missing错误解决、@RequestMapping @ResponseBody 和 @RequestBody 注解的用法与区别、@RequestMapping @ResponseBody 和 @RequestBody 用法与区别的相关信息,请在本站查询。

本文标签: