类型转换和格式化
spring MVC框架中需要手机用户请求参数,并将请求参数传递给应用的控制器组件。
此时存在一个问题,所有的请求参数只能是字符串数据类型,但Java时强类型语言
所以spring MVC框架必须将这些字符串请求转换为相应的数据类型。
1、类型转换的意义
jsp + Servlet为例子来介绍,雷西那个转换的意义
具体看下方的代码:
addGoods.jsp
<form action="<%=request.getContextPath()%>/addGood" method="post"> 商品名称:<input type="text" name="goodname"><br> 商品价格:<input type="text" name="goodprice"><br> 商品数量:<input type="text" name="goodnumber"><br> <input type="submit" value="submit"> </form>
封装之后的pojo对象属性:
Goods.java
public class Goods { private String goodname; private Double goodprice; private int goodnumber; //..... }
AddServlet.java
public class AddServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); //设置编码 req.setCharacterEncoding("utf-8"); //获取参数值 String goodname = req.getParameter("goodname"); String goodprice = req.getParameter("goodprice"); String goodnumber = req.getParameter("goodnumber"); //类型转换 Double price = Double.parseDouble(goodprice); int number = Integer.parseInt(goodnumber); //封装成Goods对象 Goods goods = new Goods(goodname,price,number); //。。。 } }
可以看出开发者需要自己在Servlet中进行类型转换,并且将值封装成对象。
手动实现这些操作,异常繁琐。
对于Spring MVC框架来说,他必须将请求参数转换成对象类中的各属性对应的数据类型。
2、Converter
spring MVC框架的Converter<S,T>是一个将数据类型转换为另一种数据类型的接口。
S表示源类型,T表示目标类型。
1、内置的类型转换器
类型转换时在视图与控制器相互传递数据时发生的
Spring MVC框架对于的基本类型(int,long,float,double,bollean,char)等已经做好了基本类型转换。
此时可以对上述的案例进行简单的测试:
@Controller public class GoodsController { //同添加商品的页面 @RequestMapping("/toGood") public String toGoods(){ return "addGoods"; } //添加页面的按钮 @RequestMapping("/addGood") public String Goods(String goodname,Double goodprice,int goodnumber){ double a = goodnumber * goodprice; System.out.println(a ); return "main"; } }
测试数据:
后台大数据打印:
2、自定义类型转换器
当上述的内置类型转换器不能满足需求时,可以自定义类型转换器
案例:
用户前端页面输入:apple,1.4,5 自动将其床架一个Goods对象
pojo类在上面已经创建好了Goods.java
前端页面:
input.jsp
<form action="<%=request.getContextPath()%>/my/converter" method="post"> 输入格式为:apple,1.2,3<br> <input type="]'text" name="goods"><br> <input type="submit" value="submit"> </form>
showGoods.jsp
<body> 你的商品是: name:${goods.goodname}<br> price:${goods.goodprice}<br> number:${goods.goodnumber}<br> </body>
controller类:
MyConverter .java
@Controller @RequestMapping("/my") public class MyConverter { //去添加的页面 @RequestMapping("/toinput") public String toInput(){ return "input"; } @RequestMapping("/converter") public String myConverter(@RequestParam("goods")Goods goods, Model model){ System.out.println(goods); model.addAttribute("goods",goods); return "showGoods"; } }
创建自定义类型的转换器类
GoodsConverter .java
public class GoodsConverter implements Converter<String, Goods> { @Override public Goods convert(String s) {//创建一个Goods实例 Goods goods = new Goods(); //以 “,”分割 String stringValue[] = s.split(","); if (stringValue !=null && stringValue.length ==3){ goods.setGoodname(stringValue[0]); goods.setGoodprice(Double.parseDouble(stringValue[1])); goods.setGoodnumber(Integer.parseInt(stringValue[2])); return goods; }else { throw new IllegalArgumentException(String.format("类型转换失败!!",s)); } } }
在配置文件中:
<!--注册类类型转换器 --> <bean id="serviceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean" > <property name="converters"> <list> <bean class="controller.GoodsConverter"></bean> </list> </property> </bean>
<mvc:annotation-driven conversion-service="serviceFactoryBean"></mvc:annotation-driven>
有很多的配置在之前的文章中已经写过了,此时不在追加 之前的代码!!!
测试:
测试结果:
3、Formatter
Formatter<T>与Converter<S,T>一样,也是一个可以将数据类型转换为为另一种数据类型的接口。
不同的是Formatter的源数据类型必须是String类型,Converter可以是任意的类型。
1、内置的格式化转换器
2、自定义的格式化转换器
自定义格式化转换器就是编写一个实现Formatter接口的java类:
public interface Formatter<T>
这里的T表示由字符串转为的目标数据类型
该接口有两个方法parse和print两个接口方法
自定义格式化转换器类必须覆盖他们。
public T parse (String s,Java.util.Local local) publiv String ptint(T object,java.util.Local local)
parse方法的功能是利用指定的Locale将一个String类型转换成目标类型
print方法相反,用于返回目标对象的字符串表示
实例演示如下:
pojo类:
public class Good { private String goodname; private Double goodprice; private int goodnumber; private Date date;
//....
}
前台的页面:
addGood.jsp
<form action="<%=request.getContextPath()%>/my/formatter" method="post"> name:<input type="text" name="goodname"> <br> price:<input type="text" name="goodprice"> <br> num:<input type="text" name="goodnumber"> <br> date:<input type="text" name="date"> <br> <input type="submit" value="submit"> </form>
showGood.jsp
<body> 已创建的商品是:<br> name:${good.goodname}<br> price:${good.goodprice}<br> number:${good.goodnumber}<br> date:${good.date}<br> </body>
控制器类:
@Controller @RequestMapping("/my") public class FormatterController { @RequestMapping("/toformatter") public String toF(){ return "addGood"; } //处理请求 @RequestMapping("/formatter") public String myFormatter(Good good, Model model){ model.addAttribute("good",good); return "showGood"; } }
格式转化类:
public class myFormatter implements Formatter<Date> { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); @Override public Date parse(String s, Locale locale) throws ParseException { return simpleDateFormat.parse(s); } @Override public String print(Date date, Locale locale) { return simpleDateFormat.format(date); } }
配置文件中进行注册:
<!--注册Formatter --> <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="controller1.myFormatter"></bean> </set> </property> </bean> <mvc:annotation-driven conversion-service="formattingConversionService"></mvc:annotation-driven>
测试:
结果:
小结:
在实际的开发中一般都使用内置转换器,很少使用自定义的。