spring mvc 拓展
一、乱码问题
1.post请求乱码
<!-- 解决post乱码问题 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<!-- 设置编码是UTF8 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.get请求乱码:需要修改tomcat中 server.xml配置
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"/>
二、设计模式
1.策略模式
策略模式(Strategy),就是⼀个问题有多种解决⽅案,选择其中的⼀种使⽤,这种情况下我们使⽤策略模式来实现灵活地选择,也能够⽅便地增加新的解决⽅案。⽐如做数学题,⼀个问题的解法可能有多种;再⽐如商场的打折促销活动,打折⽅案也有很多种,有些商品是不参与折扣活动要按照原价销售,有些商品打8.5折,有些打6折,有些是返现5元等。
结构:
-
策略(strategy)
定义所有⽀持算法的公共接⼝。 Context 使⽤这个接⼝来调⽤某 ConcreteStrategy 定义的算法。
-
策略实现(ConcreteStrategy)
实现了Strategy 接⼝的具体算法
-
上下文(context)
维护⼀个 Strategy 对象的引⽤
⽤⼀个 ConcreteStrategy 对象来装配
可定义⼀个接⼝⽅法让 Strategy 访问它的数据
示例:
-
非策略模式
public class Goods { private String goodsName; private double price; private double finalPrice; private String desc; public Goods(String goodsName, double price) { this.goodsName = goodsName; this.price = price; } /** * 折扣方法 * * @param discountType 折扣类型 * @return double */ public double calculate(String discountType) { if ("85%".equalsIgnoreCase(discountType)) { finalPrice = price * 0.85; desc = "该商品8.5折优惠"; } else if ("75%".equalsIgnoreCase(discountType)) { finalPrice = price * 0.75; desc = "该商品7.5折优惠"; } else if ("65%".equalsIgnoreCase(discountType)) { finalPrice = price * 0.65; desc = "该商品6.5折优惠"; } else { finalPrice = price; desc = "无折扣"; } System.out.println(MessageFormat.format("商品:{0}, 原价为:{1},{2}, 折后价格为:{3}", goodsName, price, desc, finalPrice)); return finalPrice; } } //test @Test public void test1() { Goods good1 = new Goods("苹果", 100); good1.calculate("85%"); Goods good2 = new Goods("电脑", 2000); good2.calculate("75%"); Goods good3 = new Goods("衣服", 800); good3.calculate("65%"); Goods good4 = new Goods("金条", 100000); good4.calculate("100%"); }
缺点:
- 增加方案,需要修改Goods源代码,违反 开闭原则
- 代码利用性差
- if else分支过多
-
策略模式
/** * 抽象策略类 * * @author zhaojianqiang */ public abstract class AbstractDiscount { private double finalPrice; private String desc; public AbstractDiscount(String desc) { this.desc = desc; } public abstract double discount(double price); public double getFinalPrice() { return finalPrice; } public void setFinalPrice(double finalPrice) { this.finalPrice = finalPrice; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
/** * 策略模式: 持有策略类 AbstractDiscount 的引用 * * @author zhaojianqiang */ public class GoodsForStrategy { private String goodsName; private double price; private AbstractDiscount abstractDiscount; public GoodsForStrategy(String goodsName, double price, AbstractDiscount abstractDiscount) { this.goodsName = goodsName; this.price = price; this.abstractDiscount = abstractDiscount; } /** * 折扣方法 * * @return double */ public double calculate() { double finalPrice = abstractDiscount.discount(this.price); String desc = abstractDiscount.getDesc(); System.out.println(MessageFormat.format("商品:{0}, 原价为:{1},{2}, 折后价格为:{3}", goodsName, price, desc, finalPrice)); return finalPrice; } }
/** * 策略模式: 持有策略类 AbstractDiscount 的引用 * * @author zhaojianqiang */ public class GoodsForStrategy { private String goodsName; private double price; private AbstractDiscount abstractDiscount; public GoodsForStrategy(String goodsName, double price, AbstractDiscount abstractDiscount) { this.goodsName = goodsName; this.price = price; this.abstractDiscount = abstractDiscount; } /** * 折扣方法 * * @return double */ public double calculate() { double finalPrice = abstractDiscount.discount(this.price); String desc = abstractDiscount.getDesc(); System.out.println(MessageFormat.format("商品:{0}, 原价为:{1},{2}, 折后价格为:{3}", goodsName, price, desc, finalPrice)); return finalPrice; } } //75折.....等策略,只需不断添加策略类即可
@Test public void test2() { GoodsForStrategy good1 = new GoodsForStrategy("苹果", 100, new Discount85()); good1.calculate(); GoodsForStrategy good2 = new GoodsForStrategy("电脑", 2000, new Discount75()); good2.calculate(); GoodsForStrategy good3 = new GoodsForStrategy("衣服", 800, new Discount65()); good3.calculate(); GoodsForStrategy good4 = new GoodsForStrategy("金条", 100000, new Discount0()); good4.calculate(); }
优点:
- 只需增加策略类,无需修改源码
- 代码简单,利用性强
- 去掉了大量if…else判断
2.模板方法模式
模板⽅法模式是指定义⼀个算法的⻣架,并允许⼦类为⼀个或者多个步骤提供实现。模板⽅法模式使得⼦类可以在不改变算法结构的情况下,重新定义算法的某些步骤,属于⾏为型设计模式。采⽤模板⽅法模式的核⼼思路是处理某个流程的代码已经具备,但其中某些节点的代码暂时不能确定。此时可以使⽤模板⽅法。
/**
* 模板方法类
* <p>
* 做饭
*
* @author zhaojianqiang
*/
public abstract class Cook {
private void fire() {
System.out.println("开火");
}
public abstract void cooking();
private void eat() {
System.out.println("开吃");
}
public void cook() {
this.fire();
this.cooking();
this.eat();
}
}
public class Dumpling extends Cook{
@Override
public void cooking() {
System.out.println("----今天煮饺子----");
}
}
public class HotPot extends Cook{
@Override
public void cooking() {
System.out.println("----今天涮火锅----");
}
}
@Test
public void test3() {
Dumpling dumpling = new Dumpling();
dumpling.cook();
HotPot hotPot = new HotPot();
hotPot.cook();
}
3.适配器模式
使得原本由于接⼝不兼容⽽不能⼀起⼯作、不能统⼀管理的那些类可以⼀起⼯作、可以进⾏统⼀管理
-
解决接⼝不兼容⽽不能⼀起⼯作问题,例:电源适配器
public class AC220 { public int outputAC220V() { int output = 220; System.out.println("输出交流电" + output + "V"); return output; } }
public interface DC5 { int outputDC5V(); }
public class PowerAdapter implements DC5 { private AC220 ac220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } @Override public int outputDC5V() { int adapterInput = ac220.outputAC220V(); // 变压器... int adapterOutput = adapterInput / 44; System.out.println("使⽤ PowerAdapter 输⼊AC:" + adapterInput + "V输出DC:" + adapterOutput + "V"); return adapterOutput; } }
@Test public void test4() { DC5 dc5 = new PowerAdapter(new AC220()); dc5.outputDC5V(); }
-
解决不能统⼀管理的问题
SpringMVC中处理器适配器(HandlerAdapter)机制就是解决类统⼀管理问题⾮常经典的场景
其中 HandlerAdapter接⼝是处理器适配器的顶级接⼝,它有多个⼦类,包括:
-
AbstractHandlerMethodAdapter
-
SimpleServletHandlerAdapter
-
SimpleControllerHandlerAdapter
-
HttpRequestHandlerAdapter
-
RequestMappingHandlerAdapter
-