我正在尝试做什么
我有一个ControllerA,需要将带有参数的请求转发或重定向(首选重定向)到ControllerB。 ControllerB处于完全不同的Web应用程序中,因此,除了重定向之外,这两个控制器都不知道另一个存在。
ControllerB以JSON或XML返回视图。我想发生的是ControllerA转发/重定向到ControllerB,并显示从ControllerB生成的视图。
我这样做是因为给我的要求指出,我应该尽量避免将ControllerB应用程序中的任何内容集成到ControllerA应用程序中。否则,我将使用RestTemplate并简单地将ControllerB的视图复制到ControllerA的应用程序中。
我到目前为止所拥有的
这是ControllerA:
@RequestMapping("/ControllerA")
public ModelAndView ControllerA(
@RequestParam(value = "A", required = true) String A,
@RequestParam(value = "B", required = false) Boolean B)
{
RedirectAttributes redirectAttributes = new RedirectAttributesModelMap();
redirectAttributes.addAttribute("A", A);
redirectAttributes.addAttribute("B", B);
String obj = "redirect:http://{host}:{port}/{appName}/ControllerB?A=A&B=B";
return new ModelAndView(obj);
}
这是ControllerB:
@RequestMapping("/ControllerB")
public ModelAndView ControllerB(
@RequestParam(value = "A") String A,
@RequestParam(value = "B", required = false) Boolean B
)
{
ControllerView cView
= serviceService.service(A, B);
return new ModelAndView("viewResolver", "object", cView);
}
我想要找回的例子
<Results A="A" B="B" numResultsReturned="1">
<line data1="ABC" />
</Results>
什么不起作用
该视图永远不会在重定向或转发时返回。 Spring报告状态为200的转发或重定向URL,然后尝试解析为JSP。我可能做错了什么?
我在SO和网络上其他地方看到的大多数问题似乎都对JSP或HTML页面使用了重定向/转发。我只是想获取XML或JSON。
我了解到我可能会在这里要求Spring做一些本不应该做的事情。如果是这样,如果我想使ControllerA和ControllerB尽可能彼此分开,我还有其他选择吗?
最佳答案
因此,我回过头来只是为了让处于相同情况的其他人也可以知道我为解决问题所做的事情。这不是最优雅的解决方案,我当然希望以其他方式完成此操作,但是它满足了我无法控制的要求
重申一下,其想法是将XML或JSON输出从一个Web应用程序中的一个控制器获取到另一个Web应用程序中的另一个控制器,而这两个应用程序/控制器都不知道另一个的存在。我最初的方法是使用重定向或转发,但是这些似乎更适合于服务JSP /其他客户端页面,而不提供XML或JSON内容。
对我有用的
@RequestMapping("/workingController")
public void workingController(
@RequestParam(value = "A", required = true) String A,
@RequestParam(value = "B", required = false) Boolean B,
@RequestParam(value = "format", required = false, defaultValue = "json") String format,
HttpServletResponse response)
throws IOException
{
String applicationType = "application/json";
if (format.equals("xml"))
{
applicationType = "text/xml";
}
String aResponse = new RestTemplate().getForObject(
"http://{host}:{port}/{appName}/controllerExternal?A={A}&B={B}&format={format}",
String.class, A, B, format);
response.setContentType(applicationType);
response.setContentLength(aResponse.length());
response.getOutputStream().write(aResponse.getBytes());
response.getOutputStream().flush();
}
说明
从上到下工作:
我将返回类型更改为
void
,因为不再需要返回视图。数据将在响应对象的主体中找到。我的应用程序配置为支持
format
参数以在XML和JSON之间切换,但是不幸的是,使用此特定解决方案时,该参数无法自动传递给外部Web应用程序。因此,我必须自己重写format参数并为其提供默认值。接下来,我定义了一个应用程序类型以供以后设置。这不是严格必要的,但是可以帮助客户使用内容。
然后,我使用RestTemplate将外部应用程序中的数据读取为String。如果您要返回视图,则无法执行此操作。您只需将XML或JSON作为字符串返回,并且其中将包含多个转义符。但是,如果您不担心视图,则可以毫无问题地执行此操作。
然后,我开始在响应上设置内容类型和长度,然后将数据写入响应。之后,我冲洗流。此时,可以从客户端查看和使用数据。
谢谢所有关注我的问题的人!