Java SpringREST服务在一个方法中使用和生成HTML表单POST和AJAX/JSON

Java SpringREST服务在一个方法中使用和生成HTML表单POST和AJAX/JSON,java,spring,rest,spring-mvc,Java,Spring,Rest,Spring Mvc,我试图通过创建一个非常简单的web应用程序来自学Spring。我有一个类来创建“Note”对象: 有趣的是,HTML表单提交仍然由create()处理,而不是createForView()处理。查看表单提交请求标题后,我看到此Accept标题: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 通过将products=“text/html”添加到createForView()上的@RequestMapping

我试图通过创建一个非常简单的web应用程序来自学Spring。我有一个类来创建“Note”对象:

有趣的是,HTML表单提交仍然由
create()
处理,而不是
createForView()
处理。查看表单提交请求标题后,我看到此Accept标题:

    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
通过将
products=“text/html”
添加到
createForView()
上的
@RequestMapping
,所有3种场景都可以工作(表单、AJAX/JSON、AJAX/XML)


这是正常的,还是我仍然缺少一些东西?

以下内容将更容易维护:

@Controller
class NoteController {
  @Autowired NoteService service;

  @RequestMapping(method = RequestMethod.POST, value = "/note")
  public ModelAndView createFromForm(@ModelAttribute @Valid Note note, BindingResult result) {
    return new ModelAndView("note", create(note));
  }

  @RequestMapping(method = RequestMethod.POST, value = "/api/note")
  @ResponseBody
  public Note createFromApi(@RequestBody Note note) {
    return create(note);
  }

  private Note create(Note note) {
    return service.create(note);
  }
}

这可以通过“内容协商”实现。需要使用“contentNegotiationManager”定义为内容协商启用SpringMVC。可以使用Java或XML配置进行设置。该配置将集中管理媒体类型映射(json、xml等)。一旦设置好了,就可以构建一个控制器类来满足JSON和View(HTML)的需要。下面是一个通用示例(未编译),应该很容易将类重构为类似的结构,以避免违反

@控制器
类报表控制器{
//1-JSON/编组类型(XML)的方法
@RequestMapping(value=“/report”,products={“application/xml”,“application/json”})
@ResponseStatus(HttpStatus.OK)
public@ResponseBody列表生成器报告(主体){
返回报告服务生成报告(委托人);
}
//2-用于查看技术(例如:JSP HTML)
@请求映射(“/report”)
公共字符串生成器报表视图(模型、主体){
model.addAttribute(generateReport(principal));
//返回用于呈现响应的视图
return–reports/main–返回;
}
}

将执行两个
@RequestMapping
方法中的哪一个?由内容协商定义确定。例如:report.xml或report.json等URL映射到第一个方法,以report.anything结尾的任何其他URL映射到第二个方法。

progress,但是
createForView()
方法不会被常规表单提交调用,而是由
create()处理
由于添加到question的request Accept头,不太确定“forView”方法是否需要
products=text/html
,因为其他方法都有明确的注释。通过将它添加到“forView”方法中,看起来您已经可以使用它了——这让我觉得这是必需的。然而,最可靠的例子似乎并没有使用它
<form:errors path="title" cssClass="errorMessage"></form:errors>
// used to handle JSON/XML
@RequestMapping(method = RequestMethod.POST, produces = {
        MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public @ResponseBody Note create(
        @Valid @ModelAttribute final Note note, final BindingResult result) {
            [...]
}

// used to handle form view
@RequestMapping(method = RequestMethod.POST)
public ModelAndView createForView(final Model model,
        @Valid @ModelAttribute final Note note, final BindingResult result) {
            [...]
}
    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
@Controller
class NoteController {
  @Autowired NoteService service;

  @RequestMapping(method = RequestMethod.POST, value = "/note")
  public ModelAndView createFromForm(@ModelAttribute @Valid Note note, BindingResult result) {
    return new ModelAndView("note", create(note));
  }

  @RequestMapping(method = RequestMethod.POST, value = "/api/note")
  @ResponseBody
  public Note createFromApi(@RequestBody Note note) {
    return create(note);
  }

  private Note create(Note note) {
    return service.create(note);
  }
}
@Controller
class ReportController{

   //1- Method for JSON/marshalling types(XML)
    @RequestMapping(value="/report", produces={"application/xml", "application/json"})
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody List<ReportPara> generateReport(Principal principal) {
        return reportService.generateReport(principal);
    }

    //2- For View technologies ( Eg:JSP HTML)
    @RequestMapping("/report")
    public String generateReportForView(Model model, Principal principal) {
        model.addAttribute( generateReport(principal) );

        // Return the view to use for rendering the response
        return ¨reports/main¨;
    }
}