-
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>7.0.64</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.9</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>4.0.0.RELEASE</version> </dependency>查看全部
-
initBinder.registerCustomerEditor(Date.class,new CustomerDateEditor(new SimpleDateFormat('yyyy-MM-dd'),true))查看全部
-
老师的方式,请求参数为item[n]:name=xx&item[m]:name=xxx,也可以传递json字符串
一、封装list的类
import lombok.Data; import java.util.List; @Data public class FromAdminList { List<Admin> admins; }
二、使用封装了list的类接受
/** * [ { "username": "John", "password": "Doe", "age":"11" }, { "username": "Anna", "password": "Smith", "age":"11" }, { "username": "Peter", "password": "Jones", "age":"11" } ] * @param admins */ @PostMapping("admins") public void listTypeObj(FromAdminList admins){ System.out.println(admins); }
另一种方式,使用@RequestBody,请求参数为json字符串格式,前提是有json的转换器
一、向list类型参数加上注解@RequestBody
/** [ { "username": "John", "password": "Doe", "age":"11" }, { "username": "Anna", "password": "Smith", "age":"11" }, { "username": "Peter", "password": "Jones", "age":"11" } ] * @param admins */ @PostMapping("adminlist") public void listTypeObj(@RequestBody List<Admin> admins){ System.out.println(admins); }
对于基本类型,string都有效
/** * [ "adb", "xixi", "多久啊送到家" ] * @param info */ @PostMapping("strs") public void listTypeStr(@RequestBody List<String> info){ System.out.println(info); } /** [ 1, 2, 3 ] * @param info */ @PostMapping("Ints") public void listTypeBase(@RequestBody List<Integer> info){ }
查看全部 -
在SpringMVC中绑定Set数据类型,接口的参数形式和绑定list是类似的,都是通过索引。但是不同的在于,Set必须初始化,如图必须先包含了初始化对象,也即是说必须提前手动分配好空间,才能进行赋值,而使用List则没有这个要求。
另外的一个坑在于,初始化Set时需要留意对象的equals方法,假如我们在提前分配两个对象空间时,两个对象通过equals方法判断为相同,则我们期望的Set的size为2,最后实际因为去重变成了1,导致在数据绑定时很容易出现数组越界的异常。
Set我们一般用来排重 使用Set的时候需要先进行初始化 要使用Set的排重功能必须在对象中覆写hashcode和equals方法。 SpringMVC对Set支持并不太好,初始化进行排重时会导致size变小,致使无法接受更多的数据而抛出异常,所以我们开发一般优先使用List。
查看全部 -
java从入门到放弃!查看全部
-
本章主要介绍SpringMVC提供的PropertyEditor和自定义Formatter、Converter的使用场景、解决的实际的问题以及Formatter和Converter的简单对比和选型依据
知识点1:
【a】PropertyEditor:属性编辑器,一般用于类型转换,它是一个接口,有很多实现类,常用直接下级实现类是PropertyEditorSupport,该类常用方法有。
setValue(Object value):一般自定义类型转换器调用并传入一个实体类对象。
getValue():一般通过自定义类型转换器对象调用该方法就可以获得实体类对象。
setAsText(String text):通常传入一个字符串,并对该字符串进行解析,然后对实体类属性进行赋值。
实现PropertyEdito接口时,通常不直接实现接口PropertyEditor,而是继承PropertyEditorSupport类进行扩展。
案例:创建一个名为MyPropertyEditor的自定义类型转换器,并继承PropertyEditorSupport,这样就可以使用接口PropertyEditor提供的方法,实现setAsText(String text)方法,该方法里创建User对象,并对传进来的字符串用逗号分隔成字符串数组,把字符串数组第0个元素赋值给User对象的name,字符串数组的第1个元素赋值给User对象的age,再通过setValue(Object obj),把User对象传入,这样做的目的,就可以和前端约定,第一个字符在逗号前面的传名字,第二个字符在逗号后面的传年龄,这样通过自定义的Editor就可以使用User对象进行接收。
扩展:getValue()方法源码实现——它会返回一个Object对象,源码中返回的是一个value属性,而这个value就是PropertyEditorSupport的Object类型的属性
【b】Formatter:格式化器,它是一个接口Formatter<T>,它继承Printer<T>和Parser<T>,他有很多实现类(AbstractNumberFormatter、CurrencyFormatter货币转换器、DateFormatter日期的转换、InstanceFormatter、NumberFormatter、PercentFormatter百分比转换器等),这里拿CurrencyFormatter讲解(货币转换器)(DateFormatter是做日期的格式化转换器,PercentFormatter是做百分比的格式化转换器)。
案例:创建自定义格式化类型转化器FormatterTest
test1()方法中,创建CurrencyFormatter对象,该对象调用setFractionDigits(2),该方法是用来保留小数点后几位的,该对象再调用setRoundingMode(RoundingMode.CEILING),该方法是用作舍入操作,celling表示四舍五入,接着通过Assert类的assertEquals()断言方法,拿123.13和123.125进行断言。
案例2:将BigDecimal("123")格式化为字符串"$123.00"展示,CurrencyFormatter的parse方法返回值是BigDecimal,print方法返回值是String。
【c】Converter:格式化器,它也是接口,该接口有两个泛型Converter<S,T>(其中<S>是source的类型,<T>是target的类型),它的实现类很多,例如NumberToCharacterConverter,把数字转换为字符,这里使用StringToBooleanConverter进行讲解,它实现了Converter<String,Boolean>接口,而且修饰的类使用的是final修饰符而不是public,原因是防止该类被修改、被继承,Converter接口不让实现类进行扩展,而Formatter不一样,它可以使用CurrentFormatter继承Formatter接口的实现类AbstractNumberFormatter,可以进行扩展。
案例:首先在dispatcher-servlet.xml中把StringToBooleanConverter注入,然后再配置<mvc:annotation-driven conversion-service="stringToBooleanConverter"/>
总结:内置的CustomDateEditor(它继承了PropertyEditorSupport),内置的CurrencyFormatter(它继承了AbstractNumberFormatter),内置的StringToBooleanConverter(它实现了Converter<String,Boolean>),就扩展性来说,这里所说扩展性都是Spring内置扩展性,Converter不可扩展,PropertyEditor一般局部使用配合webdatabinder使用,Formatter全局局部都可以,全局是通过Spring注入的方式,局部就像单元测试那样,new一个Formatter,然后调用它的方法,Converter全局和局部都可以,全局也是通过Spring注入的方式,局部也是自己实现Converter接口,写一个实现,然后new这个实现类。
查看全部 -
SpringMVC数据绑定——基本类型、包装类型、数组类型绑定
例如:age属性可以使用int和Integer进行修饰。
【a】使用基本类型int修饰age属性:key是必须传的(并且必须传入value),并且age的value范围和类型必须是int类型范围,如果传入的参数是字符串则会报400错误异常,如果没有传age,则会报500错误。
【b】使用包装类型Integer修饰age属性:可以不用传入key,Integer类型的age可以为null,所以开发过程中对于可能为空的数据设置为包装类型,当然也需要@RequestParam注解对其进行配置。
使用数组进行数据绑定:一次可以传多个,可以是基本类型、包装类型、String的对象类型。
查看全部 -
自定义一个converter
/** * A converter converts a source object of type {@code String} to a target of type {@code Date}. */ public class MyConverter implements Converter<String,Date>{ @Override public Date convert(String s) { try { return DateUtil.S_DAY_DATEFORMAT.parse(s); } catch (ParseException e) { e.printStackTrace(); } return null; } }
配置自定义converter
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { // @Bean // public Formatter<Date> myDateFormatter(){ // return new MyDateFormatter(); // } // // @Override // public void addFormatters(FormatterRegistry registry) { // registry.addFormatter(myDateFormatter()); // super.addFormatters(registry); // } @Bean public Converter myConverter(){ return new MyConverter(); } }
使用
/** *date:2018-05-24 * @param date */ @PostMapping("date") public void dateType(Date date){ System.out.println(date); }
查看全部 -
定义一个日期格式化工具类
public class DateUtil { public static SimpleDateFormat S_STANDARD_DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static SimpleDateFormat S_DAY_DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd");
自定义Formatter
public class MyDateFormatter implements Formatter<Date>{ @Override public Date parse(String text, Locale locale) throws ParseException { return DateUtil.S_DAY_DATEFORMAT.parse(text); } @Override public String print(Date object, Locale locale) { return DateUtil.S_DAY_DATEFORMAT.format(object); } }
注册自定义的formatter
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Bean public Formatter<Date> myDateFormatter(){ return new MyDateFormatter(); } @Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(myDateFormatter()); super.addFormatters(registry); } }
测试使用
/** *date:2018-05-24 * @param date */ @PostMapping("date") public void dateType(Date date){ System.out.println(date); } /** *date2:2018-05-24 * @param date2 */ @PostMapping("date2") public void dateType2(Date date2){ System.out.println(date2); } // /** // * InitBinder注解的value为指定requestParam的name // * 此注解的作用范围在自身所在controller内 // * @param binder // */ // @InitBinder({"date"}) // public void initDate(WebDataBinder binder){ // //指定处理类型,自定义数据处理器,处理器允许requestParam值为空 // binder.registerCustomEditor(Date.class,new CustomDateEditor(DateUtil.S_DAY_DATEFORMAT,true)); // }
查看全部 -
/** *date:2018-05-24 * @param date */ @PostMapping("date") public void dateType(Date date){ System.out.println(date); } /** *date:2018-05-24 * @param date2 */ @PostMapping("date2") public void dateType2(@RequestParam("date") Date date2){ System.out.println(date2); } /** * InitBinder注解的value为指定requestParam的name * 此注解的作用范围在自身所在controller内 * @param binder */ @InitBinder({"date"}) public void initDate(WebDataBinder binder){ //指定处理类型,自定义日期数据处理器,处理器允许requestParam值为空 binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true)); }
查看全部 -
SpringMVC接受http中body的json格式内容为参数,在方法的形参前加上注解 @RequestBody,用以调用解析器进行转换,值得注意的是:
1.在参数中加注解@RequestBody( @RequestBody User user)。@RequestBody是把传过来的Json数据反序列化绑定到控制器参数上
2.chrome DHC插件,构建post包等
3.json依赖的包:
<groupId>org.codehuas.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
4.需要在dispatcher-servelt.xml中<mvc:annotation-driven />,相当于默认配置了部分HandlerMapping和HandlerAdapter,如此处需要的RequestMappingHandlerAdapter
查看全部 -
使用PropertyEditor实现绑定时的类型转换:(数据类型转换器) 请求参数string到参数类型(也可能是任意类型)的类型转换,都是使用PropertyEditor类实现的string到任意参数的转换的。但是PropertyEditor不能实现任意对象到任意对象之间的转换,比如我们常见的Long时间戳到Date类型的转换时办不到的。
1、PropertyEditor:在类中进行局部使用
2、Formatter:全局,或者使用new Formatter的方式进行局部使用,只能转换String到其他类型;
3、Converter:全局或局部,和Formatter类似,但Converter的源对象不仅仅是String,而可以自行进行定义
查看全部 -
Controll中List参数不能直接传值,需要一个包裹类,类中有需要传的List作为属性和对应的get,set方法。 传值时用users[0].name = Tom users[1].name = Luce 一定不要跳跃传值,如users[0].name = Tom&users[20].name = Lucy 这样中间的1~19也会占用资源属性值为空。
查看全部 -
@controller 注解使类生效
@RequestMapping(value="",meithod = RequestMethod.GET) 指定请求和方法
@RequestParam(value="",required = true)value参数别名 required 是否必传默认为true
@RequestParam("xage")int age,xage是别名,别名是xage,客户端传上来的也要是xage,名称要一致
查看全部 -
有点蒙了啊啊啊啊啊啊啊啊
查看全部
举报