SpringMVC常用注解(三)

一、@Controller 、@RestController 和 @ControllerAdvice

1. @Controller

@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。
使用@Controller 注解,在对应的方法上,视图解析器可以解析return 的jsp,html页面,并且跳转到相应页面;
若返回json等内容到页面,则需要加@ResponseBody注解。

2. @RestController

@RestController注解相当于@ResponseBody + @Controller合在一起的作用。

返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面,返回的内容就是return 里的内容。

若使用@RestController,又想返回页面,则需要使用ModelAndView:

public ModelAndView login(){
        ModelAndView mv = new ModelAndView("index");
        return mv;
   }

3. @ControllerAdvice

@ControllerAdvice,是Spring3.2后提供的新注解,从名字上可以看出大体意思是控制器增强。

ControllerAdvice拆分开来就是Controller Advice,关于Advice,其是用于封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ContrllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行“切面”环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的(@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的,而是Spring内置对其各个逻辑的织入方式进行了内置支持)。@ControllerAdvice是在类上声明的注解,其用法主要有三点:

(1) 全局异常处理,结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的

@ControllerAdvice(basePackages = "mvc")
public class SpringControllerAdvice {
  @ExceptionHandler(RuntimeException.class)
  public ModelAndView runtimeException(RuntimeException e) {
    e.printStackTrace();
    return new ModelAndView("error");
  }
}

在该接口中抛出了RuntimeException,那么理论上,这里的异常捕获器就会捕获该异常,然后返回默认的error视图。以下是UserController的代码:

@RequestMapping(value = "/detail", method = RequestMethod.GET)
public ModelAndView detail(@RequestParam("id") long id) {
    ModelAndView view = new ModelAndView("user");
    User user = userService.detail(id);
    view.addObject("user", user);
    throw new RuntimeException("mock user detail exception.");
}

在UserController中抛出的异常能够被SpringControllerAdvice捕获。

这里需要注意的是,统一处理异常的controller需要放在和普通controller同级的包下,或者在ComponentScan的包下。在处理异常的时候可以使用System.out的方式,也可以使用logger.info,或者可以入到数据库中。

(2) 全局数据绑定,结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的;

对于@InitBinder,该注解的主要作用是绑定一些自定义的参数。一般情况下我们使用的参数通过@RequestParam,@RequestBody或者@ModelAttribute等注解就可以进行绑定了,但对于一些特殊类型参数,比如Date,它们的绑定Spring是没有提供直接的支持的,我们只能为其声明一个转换器,将request中字符串类型的参数通过转换器转换为Date类型的参数,从而供给@RequestMapping标注的方法使用。

@ControllerAdvice(basePackages = "mvc")
public class SpringControllerAdvice {
  @InitBinder
  public void globalInitBinder(WebDataBinder binder) {
    binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
  }
}

@InitBinder标注的方法注册的Formatter在每次request请求进行参数转换时都会调用,用于判断指定的参数是否为其可以转换的参数。以下是UserController的代码:

@RequestMapping(value = "/detail", method = RequestMethod.GET)
public ModelAndView detail(@RequestParam("id") long id, Date date) {
    System.out.println(date);
    ModelAndView view = new ModelAndView("user");
    User user = userService.detail(id);
    view.addObject("user", user);
    return view;
}

(3) 全局数据预处理,结合方法型注解@ModelAttribute,表示其标注的方法将会在目标Controller方法执行之前执行。

使用@ModelAttribute,如果声明在方法上,并且结合@ControllerAdvice,该方法将会在@ControllerAdvice所指定的范围内的所有接口方法执行之前执行,并且@ModelAttribute标注的方法的返回值还可以供给后续会调用的接口方法使用。

@ControllerAdvice(basePackages = "mvc")
public class SpringControllerAdvice {
  @ModelAttribute(value = "message")
  public String globalModelAttribute() {
    System.out.println("global model attribute.");
    return "this is from model attribute";
  }
}

这里需要注意的是,该方法提供了一个String类型的返回值,而@ModelAttribute中指定了该属性名称为message,这样在Controller层就可以接收该参数了,如下是UserController(普通的@Controller):

@RequestMapping(value = "/detail", method = RequestMethod.GET)
public ModelAndView detail(@RequestParam("id") long id, 
       @ModelAttribute("message") String message) {
    System.out.println(message);
    ModelAndView view = new ModelAndView("user");
    User user = userService.detail(id);
    view.addObject("user", user);
    return view;
}

@ModelAttribute标注的方法的执行是在所有拦截器的preHandle()方法执行之后才会执行。

4. @ControllerAdvice和@RestControllerAdvice的区别

//@ControllerAdvice和@RestControllerAdvice都可以指向控制器的一个子集
// 指向所有带有注解@RestController的控制器
@ControllerAdvice(annotations = RestController.class)
public class AnnotationAdvice {}
// 指向所有指定包中的控制器
@ControllerAdvice("org.example.controllers")
public class BasePackageAdvice {}
// 指向所有带有指定签名的控制器
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class AssignableTypesAdvice {}

@ControllerAdvice和@RestControllerAdvice的区别 类似于 @RestController 与 @Controller的区别。

二、@RequestBody 和 @ResponseBody

1. @RequestBody

@RequestBody是作用在形参列表上,用于将前台发送过来固定格式的数据【xml 格式或者 json等】封装为对应的 JavaBean 对象,封装时使用到的一个对象是系统默认配置的 HttpMessageConverter进行解析,然后封装到形参上。

public Object login(@RequestBody User loginUuser, HttpSession session)

2. @ResponseBody

@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

@ResponseBody
public Object login(String name, String password, HttpSession session) 

三、@ModelAttribute 和 @SessionAttributes

1. @ModelAttribute

@ModelAttribute注释方法,被@ModelAttribute注释的方法会在此controller每个方法执行前被执行,因此对于一个controller映射多个URL的用法来说,要谨慎使用。

(1) @ModelAttribute注释void返回值的方法

@Controller
public class HelloWorldController {

    @ModelAttribute
    public void populateModel(@RequestParam String abc, Model model) {
       model.addAttribute("attributeName", abc);
    }

    @RequestMapping(value = "/helloWorld")
    public String helloWorld() {
       return "helloWorld";
    }
}

(2) @ModelAttribute注释返回具体类的方法 

@ModelAttribute
public Account addAccount(@RequestParam String number) {
   return accountManager.findAccount(number);
}

这种情况,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回Account类型,那么这个model属性的名称是account。
这个例子中model属性名称由返回对象类型隐含表示,model属性对象就是方法的返回值。它无须要特定的参数。

(3) @ModelAttribute(value="")注释返回具体类的方法 

@Controller
public class HelloWorldController {

    @ModelAttribute("attributeName")
    public String addAccount(@RequestParam String abc) {
       return abc;
    }

    @RequestMapping(value = "/helloWorld")
    public String helloWorld() {
       return "helloWorld";
    }
}

这个例子中使用@ModelAttribute注释的value属性,来指定model属性的名称。model属性对象就是方法的返回值。它无须要特定的参数。

(4) @ModelAttribute和@RequestMapping同时注释一个方法 

@Controller
public class HelloWorldController {

    @RequestMapping(value = "/helloWorld.do")
    @ModelAttribute("attributeName")
    public String helloWorld() {
       return "hi";
    }
}

这时这个方法的返回值并不是表示一个视图名称,而是model属性的值,视图名称由RequestToViewNameTranslator根据请求"/helloWorld.do"转换为逻辑视图helloWorld。
Model属性名称由@ModelAttribute(value=””)指定,相当于在request中封装了key=attributeName,value=hi。

@ModelAttribute注释一个方法的参数

(1) 从model中获取

@Controller
public class HelloWorldController {

    @ModelAttribute("user")
    public User addAccount() {
       return new User("jz","123");
    }

    @RequestMapping(value = "/helloWorld")
    public String helloWorld(@ModelAttribute("user") User user) {
       user.setUserName("jizhou");
       return "helloWorld";
    }
}

在这个例子里,@ModelAttribute("user") User user注释方法参数,参数user的值来源于addAccount()方法中的model属性。
此时如果方法体没有标注@SessionAttributes("user"),那么scope为request,如果标注了,那么scope为session。

(2) 从Form表单或URL参数中获取(实际上,不做此注释也能拿到user对象) 

@Controller
public class HelloWorldController {

    @RequestMapping(value = "/helloWorld")
    public String helloWorld(@ModelAttribute User user) {
       return "helloWorld";
    }
}

注意这时候这个User类一定要有没有参数的构造函数。

@ModelAttribute注解作用在方法上或者方法的参数上,表示将被注解的方法的返回值或者是被注解的参数作为Model的属性加入到Model中,然后Spring框架自会将这个Model传递给ViewResolver。Model的生命周期只有一个http请求的处理过程,请求处理完后,Model就销毁了。

如果想让参数在多个请求间共享,那么可以用到要说到的@SessionAttribute注解。

2. @SessionAttributes

@SessionAttributes作用于处理器类上,用于在多个请求之间传递参数,类似于Session的Attribute,但不完全一样,一般来说@SessionAttribute设置的参数只用于暂时的传递,而不是长期的保存,长期保存的数据还是要放到Session中。

通过@SessionAttributes注解设置的参数有3类用法:

  • 在视图中通过request.getAttribute或session.getAttribute获取
  • 在后面请求返回的视图中通过session.getAttribute或者从model中获取
  • 自动将参数设置到后面请求所对应处理器的Model类型参数或者有@ModelAttribute注释的参数里面。

将一个参数设置到SessionAttribute中需要满足两个条件:

  • 在@SessionAttribute注解中设置了参数的名字或者类型
  • 在处理器中将参数设置到了model中。
@Controller
@RequestMapping("sc")
@SessionAttributes("name")
public class SessionController {
    @RequestMapping("session")
    public String sessions(Model model,HttpSession session){
        model.addAttribute("name", "winclpt");
        session.setAttribute("myName", "chke");
        return "session";
}

上面的代码将Model中的name参数保存到了session中(如果Model中没有name参数,而session中存在一个name参数,那么SessionAttribute会这个参数塞进Model中)

SessionAttributes有两个参数:
String[] value:要保存到session中的参数名称
Class[] typtes:要保存的参数的类型,和value中顺序要对应上
所以可以这样写:@SessionAttributes(types = {User.class,Dept.class},value={“attr1”,”attr2”})

原理理解:它的做法大概可以理解为将Model中的被注解的attrName属性保存在一个SessionAttributesHandler中,在每个RequestMapping的方法执行后,这个SessionAttributesHandler都会将它自己管理的“属性”从Model中写入到真正的HttpSession;同样,在每个RequestMapping的方法执行前,SessionAttributesHandler会将HttpSession中的被@SessionAttributes注解的属性写入到新的Model中。

如果想删除session中共享的参数,可以通过SessionStatus.setComplete(),这句只会删除通过@SessionAttributes保存到session中的参数

四、 @Autowired

首先要知道另一个东西,default-autowire,它是在xml文件中进行配置的,可以设置为byName、byType、constructor和autodetect;比如byName,不用显式的在bean中写出依赖的对象,它会自动的匹配其它bean中id名与本bean的set**相同的,并自动装载。
@Autowired是用在JavaBean中的注解,通过byType形式,用来给指定的字段或方法注入所需的外部资源。

  • no:默认不使用autowiring。 必须显示的使用”“标签明确地指定bean。
  • byName:根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。
  • byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则什么事都不发生,属性也不会被设置。如果你不希望这样,那么可以通过设置 dependency-check=”objects”让Spring抛出异常。
  • constructor:与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
  • autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。

在属性中使用该注解,不用再写setXXX方法。

五、@Value、 @Required、@Validated

1. @Validated

@Valid是javax.validation里的。
@Validated是@Valid 的一次封装,是Spring提供的校验机制使用。@Valid不提供分组功能。

(1) 分组

当一个实体类需要多种验证方式时,例:对于一个实体类的id来说,新增的时候是不需要的,对于更新时是必须的。
可以通过groups对验证进行分组。

//分组接口类(通过向groups分配不同类的class对象,达到分组目的):
public interface First {
 
}
//在bean定义的时候:
//在First分组时,判断不能为空
@NotEmpty(groups={First.class})
private String id;
//控制类:
//不需验证ID
public String addPeople(@Validated People p,BindingResult result)
//验证ID
public String updatePeople(@Validated({First.class}) People p,BindingResult result)

注意:

  • 不分配groups,默认每次都要进行验证
  • 对一个参数需要多种验证方式时,也可通过分配不同的组达到目的

(2) 组序列

默认情况下,不同组别的约束验证是无序的,然而在某些情况下,约束验证的顺序却很重要。

//分组接口类
public interface First {
 
}

public interface Second {
 
}
//通过@GroupSequence注解对组进行排序
@GroupSequence({First.class,Second.class})
public interface Group {
 
}
//验证ID
public String addPeople(@Validated({Group.class}) People p,BindingResult result)

2. @Value

为了简化读取properties文件中的配置值,spring支持@value注解的方式来获取,这种方式大大简化了项目配置,提高业务中的灵活性。

两种使用方式:

  • @Value("#{configProperties['key']}")
  • @Value("${key}")

(1)  @Value("#{configProperties['key']}")

配置方法一:

<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:value.properties</value>
        </list>
    </property>
</bean>

配置方法二:

<util:properties id="configProperties" location="classpath:value.properties"></util:properties>

注:方法一和方法二是等价的,这种方法需要util标签,要引入util的xsd:

http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"
value.properties
key=1

ValueDemo.java
@Component
public class ValueDemo {
    @Value("#{configProperties['key']}")
    private String value;
 
    public String getValue() {
        return value;
    }
}

(2) @Value("${key}")

<!--在上面的配置基础上加上:-->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
    <property name="properties" ref="configProperties"/>
</bean>
<!--或直接完整指定:-->
<bean id="appProperty"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <array>
            <value>classpath:value.properties</value>
        </array>
    </property>
</bean>
@Component
public class ValueDemo {
    @Value("${key}")
    private String value;
 
    public String getValue() {
        return value;
    }
}

3. @Required

@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。

<bean id="resultMessage" class="com.jake.ResultMessage">
   <property name="code" value="001" /><!--设置属性-->
</bean>

使用<context:annotation-config/>会隐式地注册RequiredAnnotationBeanPostProcessor,使@Required注解生效,如果没有就必须在xml文件中配置RequiredAnnotationBeanPostProcessor bean。

注意:@Required只能设置在setter方法上

六、@ExceptionHandler、@ResponseStatus

@ExceptionHandler只有一个参数,可以是一个数组,表示要捕获的异常。
@ResponseStatus
  注解中有两个参数,value属性设置异常的状态码,reaseon是异常的描述。
  状态码定义在HttpStatus上。

七、@RequestMapping

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

@RequestMapping 除了修饰方法, 还可来修饰类 :

  • 类定义处: 提供初步的请求映射信息。相对于 WEB 应用的根目录;
  • 方法处: 提供进一步的细分映射信息。 相对于类定义处的 URL。
  • 若类定义处未标注 @RequestMapping,则方法处标记的 URL相对于 WEB 应用的根目录
  • 返回ModelAndView时的url会根据你的 @RequestMapping实际情况组成。
  • 对应项目jsp位置则是一级路径对应一级文件目录:如url为/default/index对应项目中webapp/default/index.jsp
  • 如果类上没有映射,那么url直接就是方法的映射;否则url为类上+方法上映射路径组合。

RequestMapping注解有六个属性,下面我们把它分成三类进行说明:

  • value:指定请求的实际地址,指定的地址可以是URI Template 模式;
  • method: 指定请求的method类型, GET、POST、PUT、DELETE等,在RequestMethod定义;
  • consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
  • produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
  • params: 指定request中必须包含某些参数值时,才让该方法处理;
  • headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求;

八、@InitBinder

从字面意思可以看出这个的作用是给Binder做初始化的,被此注解的方法可以对WebDataBinder初始化。WebDataBinder是用于表单到方法的数据绑定的!
@InitBinder只在@Controller中注解方法来为这个控制器注册一个绑定器初始化方法,方法只对本控制器有效。

1. 对数据绑定进行设置

 WebDataBinder中有很多方法可以对数据绑定进行具体的设置:比如我们设置name属性为非绑定属性(也可以设置绑定值setAllowedFields):

@InitBinder
public void initBinder(WebDataBinder binder) {
        //setDisallowedFields表示禁止接收的参数
        binder.setDisallowedFields("name");
}

2. 注册已有的编辑器

WebDataBinder是用来绑定请求参数到指定的属性编辑器.由于前台传到controller里的值是String类型的,当往Model里Set这个值的时候,如果set的这个属性是个对象,Spring就会去找到对应的editor进行转换,然后再set进去!Spring自己提供了大量的实现类(在org.springframwork.beans.propertyEditors下的所有editor),诸如CustomDateEditor ,CustomBooleanEditor,CustomNumberEditor等许多,基本上够用。  在平时使用SpringMVC时,会碰到javabean中有Date类型参数,表单中传来代表日期的字符串转化为日期类型,SpringMVC默认不支持这种类型的转换。我们就需要手动设置时间格式并在webDateBinder上注册这个编辑器!

//这里我们在@RequestMapping参数上就可以直接使用Date类型的参数。
CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true);
binder.registerCustomEditor(Date.class, editor);

3.  注册自定义编辑器

用自定义编辑器就是在第二个的基础上添加个自定义编辑器就行了,自定义的编辑器类需要继承org.springframework.beans.propertyeditors.PropertiesEditor;,并重写setAsText和getAsText两个方法就行了!
比如下面这个DoubleEditor:

public class DoubleEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (text == null || text.equals("")) {
            text = "0";
        }
        setValue(Double.parseDouble(text));
    }
 
    @Override
    public String getAsText() {
        return getValue().toString();
    }
}

4. 设置属性的前缀可以实现参数绑定

form表单:

<form action="/testBean" method="post">
    name: <input type="text" name="u.name"> <br>
    age: <input type="text" name="u.age"> <br>
    name: <input type="text" name="s.name"> <br>
    age: <input type="text" name="s.age"> <br>
    <input type="submit">
</form>

Controller:

@InitBinder("user")
public void init1(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("u.");
}

@InitBinder("stu")
public void init2(WebDataBinder binder) {
    binder.setFieldDefaultPrefix("s.");
}

@RequestMapping("/testBean")
public ModelAndView testBean(User user, @ModelAttribute("stu") Student stu) {
    System.out.println(stu);
    System.out.println(user);
    String viewName = "success";
    ModelAndView modelAndView = new ModelAndView(viewName);
    modelAndView.addObject("user", user);
    modelAndView.addObject("student", stu);
    return modelAndView;

}

九、@PathVariable

@PathVariable 映射 URL 绑定的占位符:

  • 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
  • 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。

如:

<a href="springmvc/testPathVariable/1">testPathVariable</a>
//@PathVariable可以用来映射URL中的占位符到目标方法的参数中
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
    System.out.println("testPathVariable:"+id);
    return SUCCESS;
}

REST的支持

- /order/1 HTTP GET :得到 id = 1 的 order
- /order/1 HTTP DELETE:删除 id = 1的 order
- /order/1 HTTP PUT:更新id = 1的 order
- /order HTTP POST:新增 order

HiddenHttpMethodFilter:浏览器 form 表单只支持 GET与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与DELETE 请求。

<!--
 配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求转换成DELETE或者POST请求
  -->

<filter>
  <filter-name>HiddenHttpMethodFilter</filter-name>
  <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>   

<filter-mapping>
  <filter-name>HiddenHttpMethodFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

十、@RequestHeader、@RequestParam、@CookieValue

1. @RequestHeader

@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。
这是一个Request 的header部分:

  • Host localhost:8080
  • Accept text/html,application/xhtml+xml,application/xml;q=0.9
  • Accept-Language fr,en-gb;q=0.7,en;q=0.3
  • Accept-Encoding gzip,deflate
  • Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
  • Keep-Alive 300

2. @RequestParam 

在SpringMvc后台进行获取数据,一般是两种。 

  • request.getParameter(“参数名”)
  • 用@RequestParam注解获取

@RequestParam 有三个属性:

(1) value:请求参数名(必须配置)

(2) required:是否必需,默认为 true,即 请求中必须包含该参数,如果没有包含,将会抛出异常(可选配置)

(3) defaultValue:默认值,如果设置了该值,required 将自动设为 false,无论你是否配置了required,配置了什么值,都是 false(可选配置)

值得注意的是:如果方法上的@RequestMapping 配置了 params 属性,则请求中也必须包含该参数。

//可以对传入参数指定参数名:
// 下面的对传入参数指定为aa,如果前端不传aa参数名,会报错  
@RequestParam(value="aa") String inputStr  

//可以通过required=false或者true来要求@RequestParam配置的前端参数是否一定要传 
// required=false表示不传的话,会给参数赋值为null,required=true就是必须要有  
@RequestMapping("testRequestParam")    
public String filesUpload(@RequestParam(value="aa", required=true) String inputStr, HttpServletRequest request) 

/**如果@requestParam注解的参数是int类型,并且required=false,此时如果不传参数的话,会报错。原因是,required=false时,不传参数的话,会给参数赋值null,这样就会把null赋值给了int,因此会报错。*/
// required=false表示不传的话,会给参数赋值为null,required=true就是必须要有  
@RequestMapping("testRequestParam")    
public String filesUpload(@RequestParam(value="aa", required=false) int inputStr, HttpServletRequest request) 
//若是前端页面不传参的话,此处就会报错。当然可以用Integer代替int

 

posted @ 2019-09-22 15:41  codedot  阅读(868)  评论(0编辑  收藏  举报