You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/12/04 01:20:44 UTC

[servicecomb-java-chassis] branch master updated (19533e8 -> 147802f)

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git.


    from 19533e8  [SCB-1048]Provide a way to configure bootstrap information in Cloud Native enviroment
     new ea5e6ae  [SCB-925] Springmvc, when have defaultValue, required should be false,when param not exist,should check isRequired
     new cf54932  [SCB-925] add cookies,query and header integration-tests
     new 147802f  [SCB-925] delete containerType is null

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../servicecomb/common/rest/codec/RestCodec.java   |  3 +-
 .../rest/codec/param/AbstractParamProcessor.java   |  9 ++-
 .../rest/codec/param/CookieProcessorCreator.java   | 37 ++++++----
 .../rest/codec/param/FormProcessorCreator.java     | 29 +++++---
 .../rest/codec/param/HeaderProcessorCreator.java   | 25 ++++---
 .../rest/codec/param/PathProcessorCreator.java     |  6 +-
 .../rest/codec/param/QueryProcessorCreator.java    | 27 ++++++--
 .../rest/codec/param/TestCookieProcessor.java      | 62 ++++++++++++++++-
 .../common/rest/codec/param/TestFormProcessor.java | 31 +++++++--
 .../rest/codec/param/TestHeaderProcessor.java      | 45 ++++++++++--
 .../common/rest/codec/param/TestPathProcessor.java |  2 +-
 .../rest/codec/param/TestQueryProcessor.java       | 40 ++++++++++-
 .../main/resources/microservices/pojo/server.yaml  |  2 +-
 .../springmvc/server/SpringMvcDefaultValues.java   |  2 +-
 .../it/testcase/TestAnnotatedAttribute.java        | 79 ++++++++++++++++++++++
 .../servicecomb/it/testcase/TestDefaultValue.java  | 34 ++++++++++
 .../schema/AnnotatedAttributeSpringmvcSchema.java  | 12 ++++
 .../it/schema/DefaultValueSpringmvcSchema.java     | 24 +++++--
 .../tests/SpringMvcIntegrationTestBase.java        | 14 ++--
 .../parameter/AbstractParameterProcessor.java      |  5 +-
 .../annotation/CookieValueAnnotationProcessor.java |  6 ++
 .../RequestHeaderAnnotationProcessor.java          |  9 ++-
 .../RequestParamAnnotationProcessor.java           | 10 ++-
 23 files changed, 438 insertions(+), 75 deletions(-)


[servicecomb-java-chassis] 02/03: [SCB-925] add cookies, query and header integration-tests

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit cf54932515627d5a681e00d6b894559984a19576
Author: weichao666 <we...@huawei.com>
AuthorDate: Fri Nov 23 16:26:03 2018 +0800

    [SCB-925] add cookies,query and header integration-tests
---
 .../servicecomb/common/rest/codec/RestCodec.java   |  3 +-
 .../rest/codec/param/CookieProcessorCreator.java   | 14 ++--
 .../rest/codec/param/FormProcessorCreator.java     | 16 ++---
 .../rest/codec/param/HeaderProcessorCreator.java   | 14 ++--
 .../rest/codec/param/QueryProcessorCreator.java    | 10 +--
 .../rest/codec/param/TestCookieProcessor.java      |  6 +-
 .../common/rest/codec/param/TestFormProcessor.java |  4 +-
 .../rest/codec/param/TestHeaderProcessor.java      |  4 +-
 .../rest/codec/param/TestQueryProcessor.java       |  2 +-
 .../it/testcase/TestAnnotatedAttribute.java        | 79 ++++++++++++++++++++++
 .../servicecomb/it/testcase/TestDefaultValue.java  | 25 +++++++
 .../schema/AnnotatedAttributeSpringmvcSchema.java  | 12 ++++
 .../it/schema/DefaultValueSpringmvcSchema.java     | 10 +++
 13 files changed, 157 insertions(+), 42 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java
index 5642642..ac65d61 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java
@@ -24,6 +24,7 @@ import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.common.rest.definition.RestParam;
+import org.apache.servicecomb.foundation.common.utils.ExceptionUtils;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,7 +67,7 @@ public final class RestCodec {
     } catch (Exception e) {
       LOG.error("Parameter is not valid for operation {}. ",
           restOperation.getOperationMeta().getMicroserviceQualifiedName(),
-          e);
+          ExceptionUtils.getExceptionMessageWithoutTrace(e));
       // give standard http error code for invalid parameter
       throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid.");
     }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
index 894a379..80f1231 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
@@ -47,7 +47,7 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
       Cookie[] cookies = request.getCookies();
       Object value = null;
       if (cookies == null || cookies.length == 0) {
-        value = checkRequiredAndDefaultValue(value);
+        value = checkRequiredAndDefaultValue();
         return convertValue(value, targetType);
       }
 
@@ -57,20 +57,16 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
         }
       }
       if (value == null) {
-        value = checkRequiredAndDefaultValue(value);
+        value = checkRequiredAndDefaultValue();
       }
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue(Object value) {
+    private Object checkRequiredAndDefaultValue() throws Exception {
       if (isRequired()) {
-        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
-      Object defaultValue = getDefaultValue();
-      if (defaultValue != null) {
-        return defaultValue;
-      }
-      return value;
+      return getDefaultValue();
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
index 7e4f448..bbb70d2 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
@@ -44,7 +44,7 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
     }
 
     @Override
-    public Object getValue(HttpServletRequest request) {
+    public Object getValue(HttpServletRequest request) throws Exception {
       @SuppressWarnings("unchecked")
       Map<String, Object> forms = (Map<String, Object>) request.getAttribute(RestConst.FORM_PARAMETERS);
       if (forms != null && !forms.isEmpty()) {
@@ -55,28 +55,24 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
         Object values = request.getParameterValues(paramPath);
         //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
         if (values == null) {
-          values = checkRequiredAndDefaultValue(values);
+          values = checkRequiredAndDefaultValue();
         }
         return convertValue(values, targetType);
       }
 
       Object value = request.getParameter(paramPath);
       if (value == null) {
-        value = checkRequiredAndDefaultValue(value);
+        value = checkRequiredAndDefaultValue();
       }
 
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue(Object values) {
+    private Object checkRequiredAndDefaultValue() throws Exception {
       if (isRequired()) {
-        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
-      }
-      Object defaultValue = getDefaultValue();
-      if (defaultValue != null) {
-        return defaultValue;
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
-      return values;
+      return getDefaultValue();
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
index d946afd..726e637 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
@@ -53,7 +53,7 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
         Enumeration<?> headerValues = request.getHeaders(paramPath);
         //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
         if (headerValues == null) {
-          Object obj = checkRequiredAndDefaultValue(headerValues);
+          Object obj = checkRequiredAndDefaultValue();
           if (obj instanceof Enumeration) {
             headerValues = (Enumeration<?>) obj;
           }
@@ -64,22 +64,18 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
       } else {
         value = request.getHeader(paramPath);
         if (value == null) {
-          value = checkRequiredAndDefaultValue(value);
+          value = checkRequiredAndDefaultValue();
         }
       }
 
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue(Object headerValue) {
+    private Object checkRequiredAndDefaultValue() throws Exception {
       if (isRequired()) {
-        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
-      Object defaultValue = getDefaultValue();
-      if (defaultValue != null) {
-        return defaultValue;
-      }
-      return headerValue;
+      return getDefaultValue();
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
index b449ae2..2cff361 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
@@ -64,7 +64,7 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
         value = request.getParameterValues(paramPath);
         //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
         if (value == null) {
-          value = checkRequiredAndDefaultValue(value);
+          value = checkRequiredAndDefaultValue();
         }
       } else {
         value = request.getParameter(paramPath);
@@ -75,7 +75,7 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
           }
         }
         if (value == null) {
-          value = checkRequiredAndDefaultValue(value);
+          value = checkRequiredAndDefaultValue();
         }
         if (null != collectionFormat) {
           value = collectionFormat.splitParam((String) value);
@@ -85,15 +85,15 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue(Object value) {
+    private Object checkRequiredAndDefaultValue() throws Exception {
       if (isRequired()) {
-        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
       Object defaultValue = getDefaultValue();
       if (!ignoreDefaultValue && defaultValue != null) {
         return defaultValue;
       }
-      return value;
+      return null;
     }
 
     @Override
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
index 4628b58..ecb347e 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
@@ -75,7 +75,7 @@ public class TestCookieProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
@@ -94,7 +94,7 @@ public class TestCookieProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
@@ -128,7 +128,7 @@ public class TestCookieProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
index 35f869d..b91b18a 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
@@ -122,7 +122,7 @@ public class TestFormProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
@@ -140,7 +140,7 @@ public class TestFormProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
index 70b605b..37ddc56 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
@@ -111,7 +111,7 @@ public class TestHeaderProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
@@ -129,7 +129,7 @@ public class TestHeaderProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java
index c7e6d5b..4a3e6d7 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java
@@ -105,7 +105,7 @@ public class TestQueryProcessor {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
     }
   }
 
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestAnnotatedAttribute.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestAnnotatedAttribute.java
index 732f62c..232c1a1 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestAnnotatedAttribute.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestAnnotatedAttribute.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.servicecomb.it.Consumers;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.junit.Test;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
@@ -54,6 +55,16 @@ public class TestAnnotatedAttribute {
   }
 
   @Test
+  public void fromCookieRequired_springmvc_rt() {
+    fromCookieRequired_rt(consumersSpringmvc);
+  }
+
+  @Test
+  public void fromCookieDefaultValue_springmvc_rt() {
+    fromCookieDefaultValue_rt(consumersSpringmvc);
+  }
+
+  @Test
   public void fromPath_springmvc_rt() {
     fromPath_rt(consumersSpringmvc);
   }
@@ -109,6 +120,74 @@ public class TestAnnotatedAttribute {
     assertEquals("default,fromValue,fromName", result.getBody());
   }
 
+  protected void fromCookieRequired_rt(Consumers<AnnotatedAttributeIntf> consumers) {
+    HttpHeaders headers = new HttpHeaders();
+    HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+    try {
+      consumers.getSCBRestTemplate()
+          .exchange("/fromCookieRequired",
+              HttpMethod.GET,
+              requestEntity,
+              String.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (InvocationException e) {
+      assertEquals(400, e.getStatusCode());
+      assertEquals("InvocationException: code=400;msg=CommonExceptionData [message=Parameter is not valid.]",
+          e.getMessage());
+    }
+    headers.add(HttpHeaders.COOKIE, "input1=default1");
+    requestEntity = new HttpEntity<>(headers);
+    try {
+      consumers.getSCBRestTemplate()
+          .exchange("/fromCookieRequired",
+              HttpMethod.GET,
+              requestEntity,
+              String.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (InvocationException e) {
+      assertEquals(400, e.getStatusCode());
+      assertEquals("InvocationException: code=400;msg=CommonExceptionData [message=Parameter is not valid.]",
+          e.getMessage());
+    }
+    headers.add(HttpHeaders.COOKIE, "input=joker");
+    requestEntity = new HttpEntity<>(headers);
+    ResponseEntity<String> result = consumers.getSCBRestTemplate()
+        .exchange("/fromCookieRequired",
+            HttpMethod.GET,
+            requestEntity,
+            String.class);
+    assertEquals("joker", result.getBody());
+  }
+
+  protected void fromCookieDefaultValue_rt(Consumers<AnnotatedAttributeIntf> consumers) {
+    HttpHeaders headers = new HttpHeaders();
+    HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+    ResponseEntity<String> result = consumers.getSCBRestTemplate()
+        .exchange("/fromCookieDefaultValue",
+            HttpMethod.GET,
+            requestEntity,
+            String.class);
+    assertEquals("default", result.getBody());
+
+    headers.add(HttpHeaders.COOKIE, "input1=jokers");
+    requestEntity = new HttpEntity<>(headers);
+    result = consumers.getSCBRestTemplate()
+        .exchange("/fromCookieDefaultValue",
+            HttpMethod.GET,
+            requestEntity,
+            String.class);
+    assertEquals("default", result.getBody());
+
+    headers.add(HttpHeaders.COOKIE, "input=joker");
+    requestEntity = new HttpEntity<>(headers);
+    result = consumers.getSCBRestTemplate()
+        .exchange("/fromCookieDefaultValue",
+            HttpMethod.GET,
+            requestEntity,
+            String.class);
+    assertEquals("joker", result.getBody());
+  }
+
   protected void fromPath_rt(Consumers<AnnotatedAttributeIntf> consumers) {
     String result = consumers.getSCBRestTemplate()
         .getForObject("/fromPath/{1}/{2}/{3}",
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
index 1c172ee..8062ca1 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.it.testcase;
 import static org.junit.Assert.assertEquals;
 
 import org.apache.servicecomb.it.Consumers;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.junit.Test;
 
 public class TestDefaultValue {
@@ -217,6 +218,18 @@ public class TestDefaultValue {
   }
 
   @Test
+  public void stringQueryTrue_springmvc_rt() {
+    try {
+      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringQueryTrue", String.class);
+      assertEquals("required is true, throw exception", "not throw exception");
+    } catch (InvocationException e) {
+      assertEquals(400, e.getStatusCode());
+      assertEquals("InvocationException: code=400;msg=CommonExceptionData [message=Parameter is not valid.]",
+          e.getMessage());
+    }
+  }
+
+  @Test
   public void intHeader_springmvc_intf() {
     assertEquals(defaultInt, consumersSpringmvc.getIntf().intHeader(null));
   }
@@ -249,6 +262,18 @@ public class TestDefaultValue {
   }
 
   @Test
+  public void stringHeaderTrue_springmvc_rt() {
+    try {
+      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringHeaderTrue", String.class);
+      assertEquals("required is true, throw exception", "not throw exception");
+    } catch (InvocationException e) {
+      assertEquals(400, e.getStatusCode());
+      assertEquals("InvocationException: code=400;msg=CommonExceptionData [message=Parameter is not valid.]",
+          e.getMessage());
+    }
+  }
+
+  @Test
   public void intForm_springmvc_intf() {
     assertEquals(defaultInt, consumersSpringmvc.getIntf().intForm(null));
   }
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/AnnotatedAttributeSpringmvcSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/AnnotatedAttributeSpringmvcSchema.java
index 6b8691d..9439eeb 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/AnnotatedAttributeSpringmvcSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/AnnotatedAttributeSpringmvcSchema.java
@@ -49,6 +49,18 @@ public class AnnotatedAttributeSpringmvcSchema {
     return inputs + "," + inputs2 + "," + inputs3;
   }
 
+  @GetMapping("fromCookieRequired")
+  public String fromCookieRequired(
+      @CookieValue(name = "input", required = true) String input) {
+    return input;
+  }
+
+  @GetMapping("fromCookieDefaultValue")
+  public String fromCookieDefaultValue(
+      @CookieValue(name = "input", required = true, defaultValue = "default") String input) {
+    return input;
+  }
+
   @GetMapping("fromPath/{input}/{input2}/{input3}")
   public String fromPath(@PathVariable("input") String inputs, @PathVariable(value = "input2") String inputs2,
       @PathVariable(name = "input3") String inputs3) {
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java
index 9ed160c..0685858 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java
@@ -71,11 +71,21 @@ public class DefaultValueSpringmvcSchema {
     return input;
   }
 
+  @GetMapping("stringQueryTrue")
+  public String stringQueryTrue(@RequestParam(value = "input") String input) {
+    return input;
+  }
+
   @GetMapping("stringHeader")
   public String stringHeader(@RequestHeader(value = "input", defaultValue = "string") String input) {
     return input;
   }
 
+  @GetMapping("stringHeaderTrue")
+  public String stringHeaderTrue(@RequestHeader(value = "input") String input) {
+    return input;
+  }
+
   @ApiImplicitParams({
       @ApiImplicitParam(name = "input", dataType = "string", paramType = "form", value = "", defaultValue = "string", required = false)})
   @PostMapping(path = "stringForm")


[servicecomb-java-chassis] 01/03: [SCB-925] Springmvc, when have defaultValue, required should be false,when param not exist,should check isRequired

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit ea5e6ae676fe810e52c767b8e5a964d7874b60f1
Author: weichao666 <we...@huawei.com>
AuthorDate: Fri Nov 23 14:25:50 2018 +0800

    [SCB-925] Springmvc, when have defaultValue, required should be false,when param not exist,should check isRequired
---
 .../rest/codec/param/AbstractParamProcessor.java   |  9 +++-
 .../rest/codec/param/CookieProcessorCreator.java   | 38 +++++++++-----
 .../rest/codec/param/FormProcessorCreator.java     | 39 ++++++++++----
 .../rest/codec/param/HeaderProcessorCreator.java   | 38 ++++++++++----
 .../rest/codec/param/PathProcessorCreator.java     |  6 +--
 .../rest/codec/param/QueryProcessorCreator.java    | 28 +++++++---
 .../rest/codec/param/TestCookieProcessor.java      | 56 ++++++++++++++++++--
 .../common/rest/codec/param/TestFormProcessor.java | 33 ++++++++++--
 .../rest/codec/param/TestHeaderProcessor.java      | 50 ++++++++++++++++--
 .../common/rest/codec/param/TestPathProcessor.java |  2 +-
 .../rest/codec/param/TestQueryProcessor.java       | 40 ++++++++++++++-
 .../main/resources/microservices/pojo/server.yaml  |  2 +-
 .../springmvc/server/SpringMvcDefaultValues.java   |  2 +-
 .../servicecomb/it/testcase/TestDefaultValue.java  | 60 +++++++++++++++++-----
 .../tests/SpringMvcIntegrationTestBase.java        | 14 +++--
 .../parameter/AbstractParameterProcessor.java      |  5 +-
 .../annotation/CookieValueAnnotationProcessor.java |  6 +++
 .../RequestHeaderAnnotationProcessor.java          |  9 +++-
 .../RequestParamAnnotationProcessor.java           | 10 +++-
 19 files changed, 360 insertions(+), 87 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/AbstractParamProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/AbstractParamProcessor.java
index 509e03e..147aa0a 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/AbstractParamProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/AbstractParamProcessor.java
@@ -26,17 +26,24 @@ public abstract class AbstractParamProcessor implements ParamValueProcessor {
 
   protected Object defaultValue;
 
+  protected boolean required = false;
+
   public Object getDefaultValue() {
     return defaultValue;
   }
 
-  public AbstractParamProcessor(String paramPath, JavaType targetType, Object defaultValue) {
+  public AbstractParamProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {
     this.paramPath = paramPath;
     this.targetType = targetType;
     this.defaultValue = defaultValue;
+    this.required = required;
   }
 
   public String getParameterPath() {
     return paramPath;
   }
+
+  public boolean isRequired() {
+    return required;
+  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
index 659637e..894a379 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
@@ -21,9 +21,12 @@ import java.lang.reflect.Type;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.common.rest.codec.RestClientRequest;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.util.ObjectUtils;
 
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -35,33 +38,41 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
   public static final String PARAMTYPE = "cookie";
 
   public static class CookieProcessor extends AbstractParamProcessor {
-    public CookieProcessor(String paramPath, JavaType targetType, Object defaultValue) {
-      super(paramPath, targetType, defaultValue);
+    public CookieProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {
+      super(paramPath, targetType, defaultValue, required);
     }
 
     @Override
     public Object getValue(HttpServletRequest request) throws Exception {
       Cookie[] cookies = request.getCookies();
-      if (cookies == null) {
-        return null;
+      Object value = null;
+      if (cookies == null || cookies.length == 0) {
+        value = checkRequiredAndDefaultValue(value);
+        return convertValue(value, targetType);
       }
 
-      String value = null;
       for (Cookie cookie : cookies) {
         if (paramPath.equals(cookie.getName())) {
           value = cookie.getValue();
-          if (value == null) {
-            Object defaultValue = getDefaultValue();
-            if (defaultValue != null) {
-              value = defaultValue.toString();
-            }
-          }
         }
       }
-
+      if (value == null) {
+        value = checkRequiredAndDefaultValue(value);
+      }
       return convertValue(value, targetType);
     }
 
+    private Object checkRequiredAndDefaultValue(Object value) {
+      if (isRequired()) {
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+      }
+      Object defaultValue = getDefaultValue();
+      if (defaultValue != null) {
+        return defaultValue;
+      }
+      return value;
+    }
+
     @Override
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
       clientRequest.addCookie(paramPath,
@@ -81,6 +92,7 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
   @Override
   public ParamValueProcessor create(Parameter parameter, Type genericParamType) {
     JavaType targetType = TypeFactory.defaultInstance().constructType(genericParamType);
-    return new CookieProcessor(parameter.getName(), targetType, ((CookieParameter) parameter).getDefaultValue());
+    return new CookieProcessor(parameter.getName(), targetType, ((CookieParameter) parameter).getDefaultValue(),
+        parameter.getRequired());
   }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
index 81cf912..7e4f448 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
@@ -22,9 +22,11 @@ import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.Part;
+import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.common.rest.RestConst;
 import org.apache.servicecomb.common.rest.codec.RestClientRequest;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -37,8 +39,8 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
   public static final String PARAMTYPE = "formData";
 
   public static class FormProcessor extends AbstractParamProcessor {
-    public FormProcessor(String paramPath, JavaType targetType, Object defaultValue) {
-      super(paramPath, targetType, defaultValue);
+    public FormProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {
+      super(paramPath, targetType, defaultValue, required);
     }
 
     @Override
@@ -50,20 +52,33 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
       }
 
       if (targetType.isContainerType()) {
-        return convertValue(request.getParameterValues(paramPath), targetType);
+        Object values = request.getParameterValues(paramPath);
+        //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
+        if (values == null) {
+          values = checkRequiredAndDefaultValue(values);
+        }
+        return convertValue(values, targetType);
       }
 
       Object value = request.getParameter(paramPath);
       if (value == null) {
-        Object defaultValue = getDefaultValue();
-        if (defaultValue != null) {
-          value = defaultValue;
-        }
+        value = checkRequiredAndDefaultValue(value);
       }
 
       return convertValue(value, targetType);
     }
 
+    private Object checkRequiredAndDefaultValue(Object values) {
+      if (isRequired()) {
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+      }
+      Object defaultValue = getDefaultValue();
+      if (defaultValue != null) {
+        return defaultValue;
+      }
+      return values;
+    }
+
     @Override
     public void setValue(RestClientRequest clientRequest, Object arg) {
       clientRequest.addForm(paramPath, arg);
@@ -84,9 +99,11 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
     JavaType targetType = TypeFactory.defaultInstance().constructType(genericParamType);
 
     if (isPart(parameter)) {
-      return new PartProcessor(parameter.getName(), targetType, ((FormParameter) parameter).getDefaultValue());
+      return new PartProcessor(parameter.getName(), targetType, ((FormParameter) parameter).getDefaultValue(),
+          parameter.getRequired());
     }
-    return new FormProcessor(parameter.getName(), targetType, ((FormParameter) parameter).getDefaultValue());
+    return new FormProcessor(parameter.getName(), targetType, ((FormParameter) parameter).getDefaultValue(),
+        parameter.getRequired());
   }
 
   private boolean isPart(Parameter parameter) {
@@ -94,8 +111,8 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
   }
 
   private static class PartProcessor extends AbstractParamProcessor {
-    PartProcessor(String paramPath, JavaType targetType, Object defaultValue) {
-      super(paramPath, targetType, defaultValue);
+    PartProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {
+      super(paramPath, targetType, defaultValue, required);
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
index 810e018..d946afd 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
@@ -22,9 +22,11 @@ import java.util.Collections;
 import java.util.Enumeration;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.common.rest.codec.RestClientRequest;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -40,33 +42,46 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
   public static final String PARAMTYPE = "header";
 
   public static class HeaderProcessor extends AbstractParamProcessor {
-    public HeaderProcessor(String paramPath, JavaType targetType, Object defaultValue) {
-      super(paramPath, targetType, defaultValue);
+    public HeaderProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {
+      super(paramPath, targetType, defaultValue, required);
     }
 
     @Override
     public Object getValue(HttpServletRequest request) throws Exception {
       Object value = null;
       if (targetType.isContainerType()) {
-        Enumeration<String> headerValues = request.getHeaders(paramPath);
+        Enumeration<?> headerValues = request.getHeaders(paramPath);
+        //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
         if (headerValues == null) {
-          return null;
+          Object obj = checkRequiredAndDefaultValue(headerValues);
+          if (obj instanceof Enumeration) {
+            headerValues = (Enumeration<?>) obj;
+          }
+        }
+        if (headerValues != null) {
+          value = Collections.list(headerValues);
         }
-
-        value = Collections.list(headerValues);
       } else {
         value = request.getHeader(paramPath);
         if (value == null) {
-          Object defaultValue = getDefaultValue();
-          if (defaultValue != null) {
-            value = defaultValue;
-          }
+          value = checkRequiredAndDefaultValue(value);
         }
       }
 
       return convertValue(value, targetType);
     }
 
+    private Object checkRequiredAndDefaultValue(Object headerValue) {
+      if (isRequired()) {
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+      }
+      Object defaultValue = getDefaultValue();
+      if (defaultValue != null) {
+        return defaultValue;
+      }
+      return headerValue;
+    }
+
     @Override
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
       if (null == arg) {
@@ -91,6 +106,7 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
   @Override
   public ParamValueProcessor create(Parameter parameter, Type genericParamType) {
     JavaType targetType = TypeFactory.defaultInstance().constructType(genericParamType);
-    return new HeaderProcessor(parameter.getName(), targetType, ((HeaderParameter) parameter).getDefaultValue());
+    return new HeaderProcessor(parameter.getName(), targetType, ((HeaderParameter) parameter).getDefaultValue(),
+        parameter.getRequired());
   }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/PathProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/PathProcessorCreator.java
index dbf459c..6f5f3fd 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/PathProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/PathProcessorCreator.java
@@ -36,8 +36,8 @@ public class PathProcessorCreator implements ParamValueProcessorCreator {
   public static final String PARAMTYPE = "path";
 
   public static class PathProcessor extends AbstractParamProcessor {
-    public PathProcessor(String paramPath, JavaType targetType, Object defaultValue) {
-      super(paramPath, targetType, defaultValue);
+    public PathProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {
+      super(paramPath, targetType, defaultValue, required);
     }
 
     @Override
@@ -73,6 +73,6 @@ public class PathProcessorCreator implements ParamValueProcessorCreator {
   @Override
   public ParamValueProcessor create(Parameter parameter, Type genericParamType) {
     JavaType targetType = TypeFactory.defaultInstance().constructType(genericParamType);
-    return new PathProcessor(parameter.getName(), targetType, ((PathParameter) parameter).getDefaultValue());
+    return new PathProcessor(parameter.getName(), targetType, ((PathParameter) parameter).getDefaultValue(), true);
   }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
index 952c649..b449ae2 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
@@ -20,10 +20,12 @@ package org.apache.servicecomb.common.rest.codec.param;
 import java.lang.reflect.Type;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response.Status;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.common.rest.codec.RestClientRequest;
 import org.apache.servicecomb.swagger.converter.property.SwaggerParamCollectionFormat;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -46,8 +48,9 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
 
     private SwaggerParamCollectionFormat collectionFormat;
 
-    public QueryProcessor(String paramPath, JavaType targetType, Object defaultValue, String collectionFormat) {
-      super(paramPath, targetType, defaultValue);
+    public QueryProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required,
+        String collectionFormat) {
+      super(paramPath, targetType, defaultValue, required);
       if (StringUtils.isNoneEmpty(collectionFormat)) {
         this.collectionFormat = SwaggerParamCollectionFormat.valueOf(collectionFormat.toUpperCase());
       }
@@ -59,6 +62,10 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
       if (targetType.isContainerType()
           && SwaggerParamCollectionFormat.MULTI.equals(collectionFormat)) {
         value = request.getParameterValues(paramPath);
+        //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
+        if (value == null) {
+          value = checkRequiredAndDefaultValue(value);
+        }
       } else {
         value = request.getParameter(paramPath);
         // make some old systems happy
@@ -68,10 +75,7 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
           }
         }
         if (value == null) {
-          Object defaultValue = getDefaultValue();
-          if (!ignoreDefaultValue && defaultValue != null) {
-            value = defaultValue;
-          }
+          value = checkRequiredAndDefaultValue(value);
         }
         if (null != collectionFormat) {
           value = collectionFormat.splitParam((String) value);
@@ -81,6 +85,17 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
       return convertValue(value, targetType);
     }
 
+    private Object checkRequiredAndDefaultValue(Object value) {
+      if (isRequired()) {
+        throw new InvocationException(Status.BAD_REQUEST, "Parameter is not valid, required is true");
+      }
+      Object defaultValue = getDefaultValue();
+      if (!ignoreDefaultValue && defaultValue != null) {
+        return defaultValue;
+      }
+      return value;
+    }
+
     @Override
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
       // query不需要set
@@ -105,6 +120,7 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
     QueryParameter queryParameter = (QueryParameter) parameter;
     JavaType targetType = TypeFactory.defaultInstance().constructType(genericParamType);
     return new QueryProcessor(parameter.getName(), targetType, queryParameter.getDefaultValue(),
+        parameter.getRequired(),
         queryParameter.getCollectionFormat());
   }
 }
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
index 3705434..4628b58 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
@@ -45,7 +45,11 @@ public class TestCookieProcessor {
   RestClientRequest clientRequest;
 
   private CookieProcessor createProcessor(String name, Class<?> type) {
-    return new CookieProcessor(name, TypeFactory.defaultInstance().constructType(type), null);
+    return new CookieProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);
+  }
+
+  private CookieProcessor createProcessor(String name, Class<?> type, String defaultValue, boolean required) {
+    return new CookieProcessor(name, TypeFactory.defaultInstance().constructType(type), defaultValue, required);
   }
 
   private void createClientRequest() {
@@ -67,8 +71,12 @@ public class TestCookieProcessor {
     };
 
     CookieProcessor processor = createProcessor("c1", String.class);
-    Object value = processor.getValue(request);
-    Assert.assertNull(value);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
   }
 
   @Test
@@ -82,8 +90,12 @@ public class TestCookieProcessor {
     };
 
     CookieProcessor processor = createProcessor("c2", String.class);
-    Object value = processor.getValue(request);
-    Assert.assertNull(value);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
   }
 
   @Test
@@ -101,6 +113,40 @@ public class TestCookieProcessor {
     Assert.assertEquals("c1v", value);
   }
 
+  @Test
+  public void testGetValueRequiredTrue() throws Exception {
+    Cookie[] cookies = new Cookie[] {new Cookie("c1", null)};
+    new Expectations() {
+      {
+        request.getCookies();
+        result = cookies;
+      }
+    };
+
+    CookieProcessor processor = createProcessor("c1", String.class);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
+  }
+
+  @Test
+  public void testGetValueRequiredFalse() throws Exception {
+    Cookie[] cookies = new Cookie[] {new Cookie("c1", null)};
+    new Expectations() {
+      {
+        request.getCookies();
+        result = cookies;
+      }
+    };
+
+    CookieProcessor processor = createProcessor("c1", String.class, "test", false);
+    Object result = processor.getValue(request);
+    Assert.assertEquals("test", result);
+  }
+
   @SuppressWarnings("deprecation")
   @Test
   public void testGetValueCookiesDate() throws Exception {
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
index a756940..35f869d 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
@@ -48,7 +48,7 @@ public class TestFormProcessor {
   RestClientRequest clientRequest;
 
   private FormProcessor createProcessor(String name, Class<?> type) {
-    return new FormProcessor(name, TypeFactory.defaultInstance().constructType(type), null);
+    return new FormProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);
   }
 
   private void createClientRequest() {
@@ -118,8 +118,30 @@ public class TestFormProcessor {
     };
 
     ParamValueProcessor processor = createProcessor("name", String[].class);
-    String[] value = (String[]) processor.getValue(request);
-    Assert.assertNull(value);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
+  }
+
+  @Test
+  public void testGetValueNull() throws Exception {
+    new Expectations() {
+      {
+        request.getParameter("name");
+        result = null;
+      }
+    };
+
+    ParamValueProcessor processor = createProcessor("name", String.class);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
   }
 
   @Test
@@ -148,7 +170,7 @@ public class TestFormProcessor {
 
     ParamValueProcessor processor =
         new FormProcessor("name", TypeFactory.defaultInstance().constructCollectionType(List.class, String.class),
-            null);
+            null, true);
     Object value = processor.getValue(request);
     Assert.assertThat((List<String>) value, Matchers.contains("value"));
   }
@@ -164,7 +186,8 @@ public class TestFormProcessor {
     };
 
     ParamValueProcessor processor =
-        new FormProcessor("name", TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null);
+        new FormProcessor("name", TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null,
+            true);
     Object value = processor.getValue(request);
     Assert.assertThat((Set<String>) value, Matchers.contains("value"));
   }
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
index 667e53b..70b605b 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
@@ -49,7 +49,11 @@ public class TestHeaderProcessor {
   RestClientRequest clientRequest;
 
   private HeaderProcessor createProcessor(String name, Class<?> type) {
-    return new HeaderProcessor(name, TypeFactory.defaultInstance().constructType(type), null);
+    return new HeaderProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);
+  }
+
+  private HeaderProcessor createProcessor(String name, Class<?> type, String defaultValue, boolean required) {
+    return new HeaderProcessor(name, TypeFactory.defaultInstance().constructType(type), defaultValue, required);
   }
 
   private void createClientRequest() {
@@ -103,8 +107,44 @@ public class TestHeaderProcessor {
     };
 
     HeaderProcessor processor = createProcessor("h1", String[].class);
-    String[] value = (String[]) processor.getValue(request);
-    Assert.assertNull(value);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
+  }
+
+  @Test
+  public void testGetValueRequiredTrue() throws Exception {
+    new Expectations() {
+      {
+        request.getHeader("h1");
+        result = null;
+      }
+    };
+
+    HeaderProcessor processor = createProcessor("h1", String.class);
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
+  }
+
+  @Test
+  public void testGetValueRequiredFalse() throws Exception {
+    new Expectations() {
+      {
+        request.getHeader("h1");
+        result = null;
+      }
+    };
+
+    HeaderProcessor processor = createProcessor("h1", String.class, "test", false);
+    Object value = processor.getValue(request);
+    Assert.assertEquals("test", value);
   }
 
   @Test
@@ -133,7 +173,7 @@ public class TestHeaderProcessor {
 
     HeaderProcessor processor =
         new HeaderProcessor("h1", TypeFactory.defaultInstance().constructCollectionType(List.class, String.class),
-            null);
+            null, true);
     Object value = processor.getValue(request);
     Assert.assertThat((List<String>) value, Matchers.contains("h1v"));
   }
@@ -149,7 +189,7 @@ public class TestHeaderProcessor {
     };
 
     HeaderProcessor processor =
-        new HeaderProcessor("h1", TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null);
+        new HeaderProcessor("h1", TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null, true);
     Object value = processor.getValue(request);
     Assert.assertThat((Set<String>) value, Matchers.contains("h1v"));
   }
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestPathProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestPathProcessor.java
index 19cd51f..19cca94 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestPathProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestPathProcessor.java
@@ -41,7 +41,7 @@ public class TestPathProcessor {
   ParamValueProcessor processor;
 
   private void createProcessor(String name, Class<?> type) {
-    processor = new PathProcessor(name, TypeFactory.defaultInstance().constructType(type), null);
+    processor = new PathProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);
   }
 
   private void prepareGetValue(String name, Class<?> type) {
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java
index ec896a2..c7e6d5b 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java
@@ -34,7 +34,13 @@ public class TestQueryProcessor {
   HttpServletRequest request;
 
   private ParamValueProcessor createProcessor(String name, Class<?> type, String collectionFormat) {
-    return new QueryProcessor(name, TypeFactory.defaultInstance().constructType(type), null, collectionFormat);
+    return new QueryProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true, collectionFormat);
+  }
+
+  private ParamValueProcessor createProcessor(String name, Class<?> type, String defaultValue, boolean required,
+      String collectionFormat) {
+    return new QueryProcessor(name, TypeFactory.defaultInstance().constructType(type), defaultValue, required,
+        collectionFormat);
   }
 
   @Test
@@ -84,4 +90,36 @@ public class TestQueryProcessor {
     ParamValueProcessor processor = createProcessor("name", String.class, "multi");
     Assert.assertEquals("query", processor.getProcessorType());
   }
+
+  @Test
+  public void testGetValueRequiredTrue() throws Exception {
+    new Expectations() {
+      {
+        request.getParameter("name");
+        result = null;
+      }
+    };
+
+    ParamValueProcessor processor = createProcessor("name", String.class, "multi");
+    try {
+      processor.getValue(request);
+      Assert.assertEquals("required is true, throw exception", "not throw exception");
+    } catch (Exception e) {
+      Assert.assertTrue(e.getMessage().contains("Parameter is not valid, required is true"));
+    }
+  }
+
+  @Test
+  public void testGetValueRequiredFalse() throws Exception {
+    new Expectations() {
+      {
+        request.getParameter("name");
+        result = null;
+      }
+    };
+
+    ParamValueProcessor processor = createProcessor("name", String.class, "test", false, "multi");
+    Object result = processor.getValue(request);
+    Assert.assertEquals("test", result);
+  }
 }
diff --git a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
index 985fcb7..15b1d82 100644
--- a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
+++ b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
@@ -57,7 +57,7 @@ paths:
       parameters:
         - name: code
           in: query
-          required: true
+          required: false
           type: string
       responses:
         200:
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
index d6b33eb..3e91509 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
@@ -61,7 +61,7 @@ public class SpringMvcDefaultValues {
   }
 
   @GetMapping("/query3")
-  public String query3(@RequestParam("a") @Min(value = 20) int a, @RequestParam("b") String b) {
+  public String query3(@RequestParam("a") @Min(value = 20) int a, @RequestParam(name = "b", required = false) String b) {
     return "Hello " + a + b;
   }
 
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
index d4ad947..1c172ee 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
@@ -349,35 +349,62 @@ public class TestDefaultValue {
 
   @Test
   public void intForm_require_springmvc_intf() {
-    assertEquals(defaultInt, consumersSpringmvc.getIntf().intFormRequire(null));
+    try {
+      consumersSpringmvc.getIntf().intFormRequire(null);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   @Test
   public void doubleForm_require_springmvc_intf() {
-    assertEquals(defaultDouble, consumersSpringmvc.getIntf().doubleFormRequire(null), 0.0);
+    try {
+      consumersSpringmvc.getIntf().doubleFormRequire(null);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   @Test
   public void stringForm_require_springmvc_intf() {
-    assertEquals(defaultStr, consumersSpringmvc.getIntf().stringFormRequire(null));
+    try {
+      consumersSpringmvc.getIntf().stringFormRequire(null);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   @Test
   public void intForm_require_springmvc_rt() {
-    assertEquals(defaultInt,
-        (int) consumersSpringmvc.getSCBRestTemplate().postForObject("/intFormRequire", null, int.class));
+    try {
+      consumersSpringmvc.getSCBRestTemplate().postForObject("/intFormRequire", null, int.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   @Test
   public void doubleForm_require_springmvc_rt() {
-    assertEquals(defaultDouble,
-        consumersSpringmvc.getSCBRestTemplate().postForObject("/doubleFormRequire", null, double.class), 0.0);
+    try {
+      consumersSpringmvc.getSCBRestTemplate().postForObject("/doubleFormRequire", null, double.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   @Test
   public void stringForm_require_springmvc_rt() {
-    assertEquals(defaultStr,
-        consumersSpringmvc.getSCBRestTemplate().postForObject("/stringFormRequire", null, String.class));
+    try {
+      consumersSpringmvc.getSCBRestTemplate().postForObject("/stringFormRequire", null, String.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   //float
@@ -472,12 +499,21 @@ public class TestDefaultValue {
 
   @Test
   public void floatForm_require_springmvc_intf() {
-    assertEquals(defaultFloat, consumersSpringmvc.getIntf().floatFormRequire(null), 0.0f);
+    try {
+      consumersSpringmvc.getIntf().floatFormRequire(null);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 
   @Test
   public void floatForm_require_springmvc_rt() {
-    assertEquals(defaultFloat,
-        consumersSpringmvc.getSCBRestTemplate().postForObject("/floatFormRequire", null, float.class), 0.0f);
+    try {
+      consumersSpringmvc.getSCBRestTemplate().postForObject("/floatFormRequire", null, float.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (Exception e) {
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
   }
 }
diff --git a/integration-tests/springmvc-tests/springmvc-tests-common/src/test/java/org/apache/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java b/integration-tests/springmvc-tests/springmvc-tests-common/src/test/java/org/apache/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java
index c153a5a..c84ef3e 100644
--- a/integration-tests/springmvc-tests/springmvc-tests-common/src/test/java/org/apache/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java
+++ b/integration-tests/springmvc-tests/springmvc-tests-common/src/test/java/org/apache/servicecomb/demo/springmvc/tests/SpringMvcIntegrationTestBase.java
@@ -48,6 +48,7 @@ import org.apache.servicecomb.demo.compute.Person;
 import org.apache.servicecomb.demo.server.User;
 import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
 import org.apache.servicecomb.provider.springmvc.reference.async.CseAsyncRestTemplate;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.junit.ClassRule;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -66,6 +67,7 @@ import org.springframework.util.MultiValueMap;
 import org.springframework.util.concurrent.ListenableFuture;
 import org.springframework.util.concurrent.ListenableFutureCallback;
 import org.springframework.web.client.AsyncRestTemplate;
+import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
 
 @Ignore
@@ -321,10 +323,14 @@ public class SpringMvcIntegrationTestBase {
     HttpHeaders headers = new HttpHeaders();
     headers.setContentType(MediaType.MULTIPART_FORM_DATA);
 
-    ResponseEntity<String> response = restTemplate
-        .postForEntity(codeFirstUrl + "uploadWithoutAnnotation", new HttpEntity<>(map, headers), String.class);
-    assertThat(response.getStatusCodeValue(), is(590));
-    assertThat(response.getBody(), is("CommonExceptionData [message=Cse Internal Server Error]"));
+    ResponseEntity<String> response = null;
+    try {
+      response = restTemplate
+          .postForEntity(codeFirstUrl + "uploadWithoutAnnotation", new HttpEntity<>(map, headers), String.class);
+      assertEquals("required is true, throw exception", "but not throw exception");
+    } catch (RestClientException e) {
+      assertEquals("400 Bad Request",e.getMessage());
+    }
   }
 
   @Test
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/AbstractParameterProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/AbstractParameterProcessor.java
index 04d992c..54ec775 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/AbstractParameterProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/AbstractParameterProcessor.java
@@ -59,10 +59,9 @@ public abstract class AbstractParameterProcessor<T extends AbstractSerializableP
 
   protected void setParameterDefaultValue(Object annotation, T parameter) {
     String defaultValue = getAnnotationParameterDefaultValue(annotation);
-      if (StringUtils.isNotEmpty(defaultValue)) {
-        parameter.setDefaultValue(defaultValue);
+    if (StringUtils.isNotEmpty(defaultValue)) {
+      parameter.setDefaultValue(defaultValue);
     }
-
   }
 
   protected String getAnnotationParameterDefaultValue(Object annotation) {
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/CookieValueAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/CookieValueAnnotationProcessor.java
index f96802d..7fb4d91 100644
--- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/CookieValueAnnotationProcessor.java
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/CookieValueAnnotationProcessor.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;
 
 import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
 import org.apache.servicecomb.swagger.generator.core.processor.parameter.AbstractParameterProcessor;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.CookieValue;
 import org.springframework.web.bind.annotation.ValueConstants;
 
@@ -44,6 +45,11 @@ public class CookieValueAnnotationProcessor extends AbstractParameterProcessor<C
       CookieParameter parameter) {
     super.fillParameter(annotation, operationGenerator, paramIdx, parameter);
 
+    Object defaultValue = parameter.getDefaultValue();
+    if (!ObjectUtils.isEmpty(defaultValue)) {
+      parameter.setRequired(false);
+      return;
+    }
     CookieValue cookie = (CookieValue) annotation;
     parameter.setRequired(cookie.required());
   }
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestHeaderAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestHeaderAnnotationProcessor.java
index d34c296..63be305 100644
--- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestHeaderAnnotationProcessor.java
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestHeaderAnnotationProcessor.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;
 
 import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
 import org.apache.servicecomb.swagger.generator.core.processor.parameter.AbstractParameterProcessor;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.ValueConstants;
 
@@ -44,10 +45,15 @@ public class RequestHeaderAnnotationProcessor extends AbstractParameterProcessor
       HeaderParameter parameter) {
     super.fillParameter(annotation, operationGenerator, paramIdx, parameter);
 
+    Object defaultValue = parameter.getDefaultValue();
+    if (!ObjectUtils.isEmpty(defaultValue)) {
+      parameter.setRequired(false);
+      return;
+    }
     RequestHeader requestHeader = (RequestHeader) annotation;
     parameter.setRequired(requestHeader.required());
   }
-  
+
   @Override
   protected String getAnnotationParameterDefaultValue(Object annotation) {
     String defaultValue = ((RequestHeader) annotation).defaultValue();
@@ -56,5 +62,4 @@ public class RequestHeaderAnnotationProcessor extends AbstractParameterProcessor
     }
     return defaultValue;
   }
-  
 }
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestParamAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestParamAnnotationProcessor.java
index 8ad9a4b..828a782 100644
--- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestParamAnnotationProcessor.java
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestParamAnnotationProcessor.java
@@ -17,13 +17,14 @@
 
 package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;
 
+import io.swagger.models.parameters.QueryParameter;
+
 import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
 import org.apache.servicecomb.swagger.generator.core.processor.parameter.AbstractParameterProcessor;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ValueConstants;
 
-import io.swagger.models.parameters.QueryParameter;
-
 public class RequestParamAnnotationProcessor extends AbstractParameterProcessor<QueryParameter> {
   @Override
   public QueryParameter createParameter() {
@@ -44,6 +45,11 @@ public class RequestParamAnnotationProcessor extends AbstractParameterProcessor<
       QueryParameter parameter) {
     super.fillParameter(annotation, operationGenerator, paramIdx, parameter);
 
+    Object defaultValue = parameter.getDefaultValue();
+    if (!ObjectUtils.isEmpty(defaultValue)) {
+      parameter.setRequired(false);
+      return;
+    }
     RequestParam requestParam = (RequestParam) annotation;
     parameter.setRequired(requestParam.required());
   }


[servicecomb-java-chassis] 03/03: [SCB-925] delete containerType is null

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit 147802f8d14335cc103f0576f920e9363743b338
Author: weichao666 <we...@huawei.com>
AuthorDate: Wed Nov 28 16:09:00 2018 +0800

    [SCB-925] delete containerType is null
---
 .../rest/codec/param/CookieProcessorCreator.java   |  5 +-
 .../rest/codec/param/FormProcessorCreator.java     | 12 +--
 .../rest/codec/param/HeaderProcessorCreator.java   | 17 ++---
 .../rest/codec/param/QueryProcessorCreator.java    |  9 +--
 .../rest/codec/param/TestCookieProcessor.java      | 28 ++++---
 .../common/rest/codec/param/TestFormProcessor.java | 16 ++--
 .../rest/codec/param/TestHeaderProcessor.java      | 13 ++--
 .../servicecomb/it/testcase/TestDefaultValue.java  | 85 ++++++++--------------
 .../it/schema/DefaultValueSpringmvcSchema.java     | 22 ++++--
 9 files changed, 91 insertions(+), 116 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
index 80f1231..90f3946 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
@@ -43,7 +43,7 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
     }
 
     @Override
-    public Object getValue(HttpServletRequest request) throws Exception {
+    public Object getValue(HttpServletRequest request) {
       Cookie[] cookies = request.getCookies();
       Object value = null;
       if (cookies == null || cookies.length == 0) {
@@ -54,6 +54,7 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
       for (Cookie cookie : cookies) {
         if (paramPath.equals(cookie.getName())) {
           value = cookie.getValue();
+          break;
         }
       }
       if (value == null) {
@@ -62,7 +63,7 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue() throws Exception {
+    private Object checkRequiredAndDefaultValue() {
       if (isRequired()) {
         throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
index bbb70d2..04ea5bf 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java
@@ -44,7 +44,7 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
     }
 
     @Override
-    public Object getValue(HttpServletRequest request) throws Exception {
+    public Object getValue(HttpServletRequest request) {
       @SuppressWarnings("unchecked")
       Map<String, Object> forms = (Map<String, Object>) request.getAttribute(RestConst.FORM_PARAMETERS);
       if (forms != null && !forms.isEmpty()) {
@@ -52,12 +52,8 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
       }
 
       if (targetType.isContainerType()) {
-        Object values = request.getParameterValues(paramPath);
-        //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
-        if (values == null) {
-          values = checkRequiredAndDefaultValue();
-        }
-        return convertValue(values, targetType);
+        //Even if the paramPath does not exist, it won't be null at now
+        return convertValue(request.getParameterValues(paramPath), targetType);
       }
 
       Object value = request.getParameter(paramPath);
@@ -68,7 +64,7 @@ public class FormProcessorCreator implements ParamValueProcessorCreator {
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue() throws Exception {
+    private Object checkRequiredAndDefaultValue() {
       if (isRequired()) {
         throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
index 726e637..4d91261 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
@@ -47,20 +47,15 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
     }
 
     @Override
-    public Object getValue(HttpServletRequest request) throws Exception {
+    public Object getValue(HttpServletRequest request) {
       Object value = null;
       if (targetType.isContainerType()) {
-        Enumeration<?> headerValues = request.getHeaders(paramPath);
-        //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
+        Enumeration<String> headerValues = request.getHeaders(paramPath);
         if (headerValues == null) {
-          Object obj = checkRequiredAndDefaultValue();
-          if (obj instanceof Enumeration) {
-            headerValues = (Enumeration<?>) obj;
-          }
-        }
-        if (headerValues != null) {
-          value = Collections.list(headerValues);
+          //Even if the paramPath does not exist, headerValues won't be null at now
+          return null;
         }
+        value = Collections.list(headerValues);
       } else {
         value = request.getHeader(paramPath);
         if (value == null) {
@@ -71,7 +66,7 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue() throws Exception {
+    private Object checkRequiredAndDefaultValue() {
       if (isRequired()) {
         throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
index 2cff361..e226730 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
@@ -57,15 +57,12 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
     }
 
     @Override
-    public Object getValue(HttpServletRequest request) throws Exception {
+    public Object getValue(HttpServletRequest request) {
       Object value = null;
       if (targetType.isContainerType()
           && SwaggerParamCollectionFormat.MULTI.equals(collectionFormat)) {
         value = request.getParameterValues(paramPath);
-        //Even if the paramPath does not exist, it won't be null at now, may be optimized in the future
-        if (value == null) {
-          value = checkRequiredAndDefaultValue();
-        }
+        //Even if the paramPath does not exist, value won't be null at now
       } else {
         value = request.getParameter(paramPath);
         // make some old systems happy
@@ -85,7 +82,7 @@ public class QueryProcessorCreator implements ParamValueProcessorCreator {
       return convertValue(value, targetType);
     }
 
-    private Object checkRequiredAndDefaultValue() throws Exception {
+    private Object checkRequiredAndDefaultValue() {
       if (isRequired()) {
         throw new InvocationException(Status.BAD_REQUEST, "Parameter is required.");
       }
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
index ecb347e..63364c4 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java
@@ -70,7 +70,21 @@ public class TestCookieProcessor {
       }
     };
 
-    CookieProcessor processor = createProcessor("c1", String.class);
+    CookieProcessor processor = createProcessor("c1", String.class, null, false);
+    Object value = processor.getValue(request);
+    Assert.assertNull(value);
+  }
+
+  @Test
+  public void testNoCookieAndRequired() throws Exception {
+    new Expectations() {
+      {
+        request.getCookies();
+        result = null;
+      }
+    };
+
+    CookieProcessor processor = createProcessor("c1", String.class, null, true);
     try {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
@@ -89,13 +103,9 @@ public class TestCookieProcessor {
       }
     };
 
-    CookieProcessor processor = createProcessor("c2", String.class);
-    try {
-      processor.getValue(request);
-      Assert.assertEquals("required is true, throw exception", "not throw exception");
-    } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
-    }
+    CookieProcessor processor = createProcessor("c2", String.class, null, false);
+    Object value = processor.getValue(request);
+    Assert.assertNull(value);
   }
 
   @Test
@@ -123,7 +133,7 @@ public class TestCookieProcessor {
       }
     };
 
-    CookieProcessor processor = createProcessor("c1", String.class);
+    CookieProcessor processor = createProcessor("c1", String.class, null, true);
     try {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
index b91b18a..c14403e 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java
@@ -51,6 +51,10 @@ public class TestFormProcessor {
     return new FormProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);
   }
 
+  private FormProcessor createProcessor(String name, Class<?> type, String defaultValue, boolean required) {
+    return new FormProcessor(name, TypeFactory.defaultInstance().constructType(type), defaultValue, required);
+  }
+
   private void createClientRequest() {
     clientRequest = new MockUp<RestClientRequest>() {
       @Mock
@@ -117,13 +121,9 @@ public class TestFormProcessor {
       }
     };
 
-    ParamValueProcessor processor = createProcessor("name", String[].class);
-    try {
-      processor.getValue(request);
-      Assert.assertEquals("required is true, throw exception", "not throw exception");
-    } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
-    }
+    ParamValueProcessor processor = createProcessor("name", String[].class, null, false);
+    String[] value = (String[]) processor.getValue(request);
+    Assert.assertNull(value);
   }
 
   @Test
@@ -135,7 +135,7 @@ public class TestFormProcessor {
       }
     };
 
-    ParamValueProcessor processor = createProcessor("name", String.class);
+    ParamValueProcessor processor = createProcessor("name", String.class, null, true);
     try {
       processor.getValue(request);
       Assert.assertEquals("required is true, throw exception", "not throw exception");
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
index 37ddc56..a205336 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java
@@ -106,13 +106,9 @@ public class TestHeaderProcessor {
       }
     };
 
-    HeaderProcessor processor = createProcessor("h1", String[].class);
-    try {
-      processor.getValue(request);
-      Assert.assertEquals("required is true, throw exception", "not throw exception");
-    } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("Parameter is required."));
-    }
+    HeaderProcessor processor = createProcessor("h1", String[].class, null, false);
+    String[] value = (String[]) processor.getValue(request);
+    Assert.assertNull(value);
   }
 
   @Test
@@ -189,7 +185,8 @@ public class TestHeaderProcessor {
     };
 
     HeaderProcessor processor =
-        new HeaderProcessor("h1", TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null, true);
+        new HeaderProcessor("h1", TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null,
+            true);
     Object value = processor.getValue(request);
     Assert.assertThat((Set<String>) value, Matchers.contains("h1v"));
   }
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
index 8062ca1..d0b8039 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultValue.java
@@ -218,14 +218,13 @@ public class TestDefaultValue {
   }
 
   @Test
-  public void stringQueryTrue_springmvc_rt() {
+  public void stringQueryRequiredTrue_springmvc_rt() {
     try {
-      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringQueryTrue", String.class);
+      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringQueryRequiredTrue", String.class);
       assertEquals("required is true, throw exception", "not throw exception");
     } catch (InvocationException e) {
       assertEquals(400, e.getStatusCode());
-      assertEquals("InvocationException: code=400;msg=CommonExceptionData [message=Parameter is not valid.]",
-          e.getMessage());
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
     }
   }
 
@@ -262,14 +261,13 @@ public class TestDefaultValue {
   }
 
   @Test
-  public void stringHeaderTrue_springmvc_rt() {
+  public void stringHeaderRequiredTrue_springmvc_rt() {
     try {
-      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringHeaderTrue", String.class);
+      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringHeaderRequiredTrue", String.class);
       assertEquals("required is true, throw exception", "not throw exception");
     } catch (InvocationException e) {
       assertEquals(400, e.getStatusCode());
-      assertEquals("InvocationException: code=400;msg=CommonExceptionData [message=Parameter is not valid.]",
-          e.getMessage());
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
     }
   }
 
@@ -307,6 +305,17 @@ public class TestDefaultValue {
   }
 
   @Test
+  public void stringFormRequiredTrue_springmvc_rt() {
+    try {
+      consumersSpringmvc.getSCBRestTemplate().getForObject("/stringFormRequiredTrue", String.class);
+      assertEquals("required is true, throw exception", "not throw exception");
+    } catch (InvocationException e) {
+      assertEquals(400, e.getStatusCode());
+      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
+    }
+  }
+
+  @Test
   public void intQuery_require_springmvc_intf() {
     assertEquals(defaultInt, consumersSpringmvc.getIntf().intQueryRequire(null));
   }
@@ -374,62 +383,35 @@ public class TestDefaultValue {
 
   @Test
   public void intForm_require_springmvc_intf() {
-    try {
-      consumersSpringmvc.getIntf().intFormRequire(null);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultInt, consumersSpringmvc.getIntf().intFormRequire(null));
   }
 
   @Test
   public void doubleForm_require_springmvc_intf() {
-    try {
-      consumersSpringmvc.getIntf().doubleFormRequire(null);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultDouble, consumersSpringmvc.getIntf().doubleFormRequire(null), 0.0);
   }
 
   @Test
   public void stringForm_require_springmvc_intf() {
-    try {
-      consumersSpringmvc.getIntf().stringFormRequire(null);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultStr, consumersSpringmvc.getIntf().stringFormRequire(null));
   }
 
   @Test
   public void intForm_require_springmvc_rt() {
-    try {
-      consumersSpringmvc.getSCBRestTemplate().postForObject("/intFormRequire", null, int.class);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultInt,
+        (int) consumersSpringmvc.getSCBRestTemplate().postForObject("/intFormRequire", null, int.class));
   }
 
   @Test
   public void doubleForm_require_springmvc_rt() {
-    try {
-      consumersSpringmvc.getSCBRestTemplate().postForObject("/doubleFormRequire", null, double.class);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultDouble,
+        consumersSpringmvc.getSCBRestTemplate().postForObject("/doubleFormRequire", null, double.class), 0.0);
   }
 
   @Test
   public void stringForm_require_springmvc_rt() {
-    try {
-      consumersSpringmvc.getSCBRestTemplate().postForObject("/stringFormRequire", null, String.class);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultStr,
+        consumersSpringmvc.getSCBRestTemplate().postForObject("/stringFormRequire", null, String.class));
   }
 
   //float
@@ -524,21 +506,12 @@ public class TestDefaultValue {
 
   @Test
   public void floatForm_require_springmvc_intf() {
-    try {
-      consumersSpringmvc.getIntf().floatFormRequire(null);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultFloat, consumersSpringmvc.getIntf().floatFormRequire(null), 0.0f);
   }
 
   @Test
   public void floatForm_require_springmvc_rt() {
-    try {
-      consumersSpringmvc.getSCBRestTemplate().postForObject("/floatFormRequire", null, float.class);
-      assertEquals("required is true, throw exception", "but not throw exception");
-    } catch (Exception e) {
-      assertEquals(true, e.getMessage().contains("Parameter is not valid"));
-    }
+    assertEquals(defaultFloat,
+        consumersSpringmvc.getSCBRestTemplate().postForObject("/floatFormRequire", null, float.class), 0.0f);
   }
 }
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java
index 0685858..f0501d2 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultValueSpringmvcSchema.java
@@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
 
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -59,7 +60,7 @@ public class DefaultValueSpringmvcSchema {
   }
 
   @ApiImplicitParams({
-      @ApiImplicitParam(name = "input", dataType = "integer", format = "int32", paramType = "form", value = "a required form param", required = true, defaultValue = "13")})
+      @ApiImplicitParam(name = "input", dataType = "integer", format = "int32", paramType = "form", value = "a defaultValue form param", required = false, defaultValue = "13")})
   @PostMapping(path = "intFormRequire")
   public int intFormRequire(int input) {
     return input;
@@ -71,8 +72,8 @@ public class DefaultValueSpringmvcSchema {
     return input;
   }
 
-  @GetMapping("stringQueryTrue")
-  public String stringQueryTrue(@RequestParam(value = "input") String input) {
+  @GetMapping("stringQueryRequiredTrue")
+  public String stringQueryRequiredTrue(@RequestParam(value = "input") String input) {
     return input;
   }
 
@@ -81,8 +82,8 @@ public class DefaultValueSpringmvcSchema {
     return input;
   }
 
-  @GetMapping("stringHeaderTrue")
-  public String stringHeaderTrue(@RequestHeader(value = "input") String input) {
+  @GetMapping("stringHeaderRequiredTrue")
+  public String stringHeaderRequiredTrue(@RequestHeader(value = "input") String input) {
     return input;
   }
 
@@ -93,6 +94,11 @@ public class DefaultValueSpringmvcSchema {
     return input;
   }
 
+  @GetMapping("stringFormRequiredTrue")
+  public String stringFormRequiredTrue(@RequestPart(value = "input") String input) {
+    return input;
+  }
+
   // springmvc rule: required should be false because defaultValue have value
   @GetMapping(path = "stringQueryRequire")
   public String stringQueryRequire(
@@ -108,7 +114,7 @@ public class DefaultValueSpringmvcSchema {
   }
 
   @ApiImplicitParams({
-      @ApiImplicitParam(name = "input", dataType = "string", paramType = "form", value = "a required form param", required = true, defaultValue = "string")})
+      @ApiImplicitParam(name = "input", dataType = "string", paramType = "form", value = "a defalutValue form param", required = false, defaultValue = "string")})
   @PostMapping(path = "stringFormRequire")
   public String stringFormRequire(String input) {
     return input;
@@ -147,7 +153,7 @@ public class DefaultValueSpringmvcSchema {
   }
 
   @ApiImplicitParams({
-      @ApiImplicitParam(name = "input", dataType = "number", format = "double", paramType = "form", value = "a required form param", required = true, defaultValue = "10.2")})
+      @ApiImplicitParam(name = "input", dataType = "number", format = "double", paramType = "form", value = "a defaultValue form param", required = false, defaultValue = "10.2")})
   @PostMapping(path = "doubleFormRequire")
   public double doubleFormRequire(double input) {
     return input;
@@ -185,7 +191,7 @@ public class DefaultValueSpringmvcSchema {
   }
 
   @ApiImplicitParams({
-      @ApiImplicitParam(name = "input", dataType = "number", format = "float", paramType = "form", value = "a required form param", required = true, defaultValue = "10.2")})
+      @ApiImplicitParam(name = "input", dataType = "number", format = "float", paramType = "form", value = "a defaultValue form param", required = false, defaultValue = "10.2")})
   @PostMapping(path = "floatFormRequire")
   public float floatFormRequire(float input) {
     return input;