最近有个需求,设计一个统一的支付接口,这个支付接口对接多个应用,,需要根据请求的支付类型处理并且返回不同结果.
需要这么一个接口
@PostMapping(value = "/pay/submit/{paymentType}")
public Object submit(@PathVariable PaymentTypeEnum paymentType, String orderId) throws Exception {
String submit = payService.submit(paymentType, orderId);
switch (paymentType) {
case banlance:
//返回视图,即html页面
case alipay:
//返回html文本数据
case alipay_wap:
//返回Json数据
case union:
//重定向
default:
break;
}
return null;
}
如果分开写类似这样
@PostMapping("/pay/submit/banlance")
public String banlance() {
return "/result";
}
@PostMapping(value = "/pay/submit/alipay", produces = "text/html; charset=UTF-8")
@ResponseBody
public String alipay() {
return "
1111";}
@PostMapping(value = "/pay/submit/alipay_wap")
@ResponseBody
public Object alipay_wap() {
return new Object();
}
@PostMapping("/pay/submit/union")
public String union() {
return "redirect:/union";
}
以下是我的解决方式
统一返回ModelAndView,并定义对应的View
使用FastJson提供的FastJsonJsonView来解析Json,注意view.setExtractValueFromSingleKeyModel(true);
定义一个处理Html文本的View
ViewConfig.java
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import java.io.PrintWriter;
@Configuration
public class ViewConfig {
/**
* 用来解析json的view
*/
@Bean
public FastJsonJsonView fastJsonJsonView() {
FastJsonJsonView view = new FastJsonJsonView();
view.setExtractValueFromSingleKeyModel(true);
return view;
}
/**
* 解析html文本格式的view
*/
@Bean
public View htmlTextView() {
return (model, request, response) -> {
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
String str = (String) (model != null ? model.get("string") : "");
try (PrintWriter out = response.getWriter()) {
out.write(str);
out.flush();
}
};
}
}
TestPayController.java
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/testPay")
public class TestPayController {
@Autowired
private PayService payService;
@Autowired
private HtmlTextView htmlTextView;
@Autowired
private FastJsonJsonView fastJsonJsonView;
@PostMapping(value = "/submit/{paymentType}")
public ModelAndView submit(@PathVariable PaymentTypeEnum paymentType, String orderId) throws Exception {
String submit = payService.submit(paymentType, orderId);
ModelAndView view = new ModelAndView();
switch (paymentType) {
case banlance:
//返回视图,即html页面
view.addObject(submit);
view.setViewName("/payResult");
break;
case alipay:
//返回html文本数据
view.addObject(HtmlTextView.MODEL_KEY, submit);
view.setView(htmlTextView);
break;
case alipay_wap:
//返回Json
view.addObject(ServerResponse.createBySuccess(submit));
view.setView(fastJsonJsonView);
break;
case union:
//重定向
view.setViewName("redirect:" + submit);
break;
default:
break;
}
return view;
}
}
这样差不多就能达到效果了,其中有几点需要注意的地方
直接在mapping方法里面使用 response.setContentType()无效,像下面这种并不能如期望的返回text/html格式的
@PostMapping(value = "/html")
@ResponseBody
public String html(HttpServletResponse response) {
response.setContentType("text/html;charset=UTF-8");
return "
1111";}
使用FastJsonJsonView或MappingJackson2JsonView要注意是否使用 ==setExtractValueFromSingleKeyModel==