Spring Boot 和 Swagger text/html 响应映射
Spring Boot and Swagger text/html response mapping
我有一个非常简单的 java spring boot + swagger 项目。
仅出于测试目的,我创建了两个映射 类:Names.java 和 NamesContainer.java
public class Names {
@XmlAttribute(name="ref")
@ApiModelProperty(notes = "The auto-generated version of the product...")
private String key;
@XmlValue
@ApiModelProperty(notes = "The auto-generated version of the product...")
private String name;....-> rest of the class(Default constuctor and getters and setters)
............
@XmlRootElement(name="root")
public class NamesContainer {
@XmlElement(name="listNames")
@ApiModelProperty(notes = "The auto-generated version of the product")
private List<Names> listNames;....-> rest of the class(Default constuctor and getters and setters)
对于响应,我使用一种@Get 方法:
@RequestMapping(method = RequestMethod.GET, value = "/api/javainuse")
@ApiOperation(value = "Get a scheduled process by id.",notes = "This is note ;)",response = NamesContainer.class,code = HttpURLConnection.HTTP_OK, produces="text/html")
@ApiResponses(value = {@ApiResponse(code = HttpURLConnection.HTTP_OK, message = "set in case of success. Returns the requested scheduled process", response = NamesContainer.class)})
public NamesContainer sayHello() {
Map<String, String> mapNames = new HashMap<String, String>();
mapNames.put("Name1", "Docnho");
mapNames.put("Name2", "Silvia");
mapNames.put("Name3", "Pepa");
mapNames.put("Name4", "Mima");
mapNames.put("Name5", "Mohamed");
List<Names> listNames = new ArrayList<Names>();
for(Map.Entry<String, String> entryName : mapNames.entrySet())
{
listNames.add(new Names(entryName.getKey(), entryName.getValue()));
}
NamesContainer container = new NamesContainer(listNames);
return container;
}
如果我使用 produces="application/json" 或 produces="application/xml",结果如预期:
但是如果我尝试使用 produces="text/html"
响应与预期不符:
响应正文是;
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Fri Mar 15 18:43:55 EET 2019</div><div>There was an unexpected error (type=Not Acceptable, status=406).</div><div>Could not find acceptable representation</div></body></html>
问题是是否有可能以生成 HTML 响应的方式映射我现有的对象 NamesContainer.java 以及如何做到这一点?
您的 Pojo 可能需要更明确的 mappings/annotations 才能生成 HTML。我假设您正在寻找类似
的内容
<table>
<tr>
<th>Name1</th>
<th>Name2</th>
<th>Name3</th>
<th>Name4</th>
</tr>
<tr>
<td>Peppa</td>
<td>Mima</td>
<td>Mohamed</td>
<td>Docnho</td>
</tr>
</table>
我不确定哪个注释可以提供帮助,但这就是我要开始的地方
没有办法(没有现有的方法)将 POJO 字段映射到带有注释的 html。
Instread 可以使用其他方式将 POJO(模型)绑定到 html Spring 建议开箱即用:Thymleaf temlates, Freemarker templates 和 JSP 页面。
以下是其中一种可能解决方案的示例:
- 使用 html Thymleaf 模板创建 HTML 页面。例如
table.html
视图:
<body>
<table>
<tr>
<th>Key</th>
<th>Name</th>
</tr>
<tr th:each="mapEnty: ${mapNames}">
<td th:text="${mapEnty.key}" />
<td th:text="${mapEnty.value}" />
</tr>
</table>
</body>
- 在Spring
@Controller
中为'text/html' 内容类型创建@RequestMapping,填写模型和return 'table' 视图。例如:
@GetMapping(value = "/api/javainuse", produces = MediaType.TEXT_HTML_VALUE)
public String table(Model model) {
Map<String, String> mapNames = new HashMap<String, String>();
...
model.addAttribute("mapNames", mapNames);
return "table";
}
TLDR:是的,这是可能的。为 HTML.
创建 Jackson 数据格式模块
我相信Spring Boot 正在使用 Jackson 进行数据输出,并且 Jackson 支持该格式:
- JSON
- HTML
- 微笑
- YAML
- 阿芙罗
- CSV
以及更多 (https://github.com/FasterXML/jackson),但不支持像 HTML 这样的格式(这怎么可能?)。
HTML 呈现需要模板。了解 Spring MVC https://spring.io/guides/gs/serving-web-content/。
另请阅读内容协商 (https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc)
You can use the RESTful @ResponseBody approach and HTTP message converters, typically to return data-formats like JSON or XML.
(...) views are perfectly capable of generating JSON and XML if you wish , views are normally used to generate presentation formats like HTML for a traditional web-application.
我找到了几个解决这个问题的机会,但我认为这两个是最好的:
第一个 对面向码头服务器的应用程序有意义。这是解释 - here. The major thing in produces="text/html, ..., ..." is MessageBodyWriter 界面。如果你可以定制它,你可以用它做任何事情。
第二个,我的最终解决方案是为我的 .xml 文件创建 .xsl 文件。我将我的 .xml 文件转换为 HTML,然后响应完成。
** 如果有人想用一种方法做所有事情可以使用这个:
@RequestMapping(method = RequestMethod.GET, value = "/api/javainuse")
@ApiOperation(value = "Get a scheduled process by id.",notes = "This is note ;)",response = NamesContainer.class,code = HttpURLConnection.HTTP_OK, produces="text/html" /*add produces->xml*/)
@ApiResponses(value = {@ApiResponse(code = HttpURLConnection.HTTP_OK, message = "set in case of success. Returns the requested scheduled process", response = NamesContainer.class)})
public Response sayHello(HttpServletResponse response) {
switch (request.getHeader("accept"))
{
case MediaType.APPLICATION_XML:
response = Response.ok().entity(/*yourEntity here (for me it was NamesContainer)*/).type(MediaType.APPLICATION_XML).build();
break;
case MediaType.TEXT_HTML:
response = Response.ok().entity(/*Transform xml to HTML with xsl and return it here as String*/).type(MediaType.TEXT_PLAIN).build();
break;
}
}
我有一个非常简单的 java spring boot + swagger 项目。
仅出于测试目的,我创建了两个映射 类:Names.java 和 NamesContainer.java
public class Names {
@XmlAttribute(name="ref")
@ApiModelProperty(notes = "The auto-generated version of the product...")
private String key;
@XmlValue
@ApiModelProperty(notes = "The auto-generated version of the product...")
private String name;....-> rest of the class(Default constuctor and getters and setters)
............
@XmlRootElement(name="root")
public class NamesContainer {
@XmlElement(name="listNames")
@ApiModelProperty(notes = "The auto-generated version of the product")
private List<Names> listNames;....-> rest of the class(Default constuctor and getters and setters)
对于响应,我使用一种@Get 方法:
@RequestMapping(method = RequestMethod.GET, value = "/api/javainuse")
@ApiOperation(value = "Get a scheduled process by id.",notes = "This is note ;)",response = NamesContainer.class,code = HttpURLConnection.HTTP_OK, produces="text/html")
@ApiResponses(value = {@ApiResponse(code = HttpURLConnection.HTTP_OK, message = "set in case of success. Returns the requested scheduled process", response = NamesContainer.class)})
public NamesContainer sayHello() {
Map<String, String> mapNames = new HashMap<String, String>();
mapNames.put("Name1", "Docnho");
mapNames.put("Name2", "Silvia");
mapNames.put("Name3", "Pepa");
mapNames.put("Name4", "Mima");
mapNames.put("Name5", "Mohamed");
List<Names> listNames = new ArrayList<Names>();
for(Map.Entry<String, String> entryName : mapNames.entrySet())
{
listNames.add(new Names(entryName.getKey(), entryName.getValue()));
}
NamesContainer container = new NamesContainer(listNames);
return container;
}
如果我使用 produces="application/json" 或 produces="application/xml",结果如预期:
但是如果我尝试使用 produces="text/html"
响应与预期不符:
响应正文是;
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Fri Mar 15 18:43:55 EET 2019</div><div>There was an unexpected error (type=Not Acceptable, status=406).</div><div>Could not find acceptable representation</div></body></html>
问题是是否有可能以生成 HTML 响应的方式映射我现有的对象 NamesContainer.java 以及如何做到这一点?
您的 Pojo 可能需要更明确的 mappings/annotations 才能生成 HTML。我假设您正在寻找类似
的内容<table>
<tr>
<th>Name1</th>
<th>Name2</th>
<th>Name3</th>
<th>Name4</th>
</tr>
<tr>
<td>Peppa</td>
<td>Mima</td>
<td>Mohamed</td>
<td>Docnho</td>
</tr>
</table>
我不确定哪个注释可以提供帮助,但这就是我要开始的地方
没有办法(没有现有的方法)将 POJO 字段映射到带有注释的 html。
Instread 可以使用其他方式将 POJO(模型)绑定到 html Spring 建议开箱即用:Thymleaf temlates, Freemarker templates 和 JSP 页面。
以下是其中一种可能解决方案的示例:
- 使用 html Thymleaf 模板创建 HTML 页面。例如
table.html
视图:
<body>
<table>
<tr>
<th>Key</th>
<th>Name</th>
</tr>
<tr th:each="mapEnty: ${mapNames}">
<td th:text="${mapEnty.key}" />
<td th:text="${mapEnty.value}" />
</tr>
</table>
</body>
- 在Spring
@Controller
中为'text/html' 内容类型创建@RequestMapping,填写模型和return 'table' 视图。例如:
@GetMapping(value = "/api/javainuse", produces = MediaType.TEXT_HTML_VALUE)
public String table(Model model) {
Map<String, String> mapNames = new HashMap<String, String>();
...
model.addAttribute("mapNames", mapNames);
return "table";
}
TLDR:是的,这是可能的。为 HTML.
创建 Jackson 数据格式模块我相信Spring Boot 正在使用 Jackson 进行数据输出,并且 Jackson 支持该格式:
- JSON
- HTML
- 微笑
- YAML
- 阿芙罗
- CSV
以及更多 (https://github.com/FasterXML/jackson),但不支持像 HTML 这样的格式(这怎么可能?)。
HTML 呈现需要模板。了解 Spring MVC https://spring.io/guides/gs/serving-web-content/。
另请阅读内容协商 (https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc)
You can use the RESTful @ResponseBody approach and HTTP message converters, typically to return data-formats like JSON or XML.
(...) views are perfectly capable of generating JSON and XML if you wish , views are normally used to generate presentation formats like HTML for a traditional web-application.
我找到了几个解决这个问题的机会,但我认为这两个是最好的:
第一个 对面向码头服务器的应用程序有意义。这是解释 - here. The major thing in produces="text/html, ..., ..." is MessageBodyWriter 界面。如果你可以定制它,你可以用它做任何事情。
第二个,我的最终解决方案是为我的 .xml 文件创建 .xsl 文件。我将我的 .xml 文件转换为 HTML,然后响应完成。
** 如果有人想用一种方法做所有事情可以使用这个:
@RequestMapping(method = RequestMethod.GET, value = "/api/javainuse")
@ApiOperation(value = "Get a scheduled process by id.",notes = "This is note ;)",response = NamesContainer.class,code = HttpURLConnection.HTTP_OK, produces="text/html" /*add produces->xml*/)
@ApiResponses(value = {@ApiResponse(code = HttpURLConnection.HTTP_OK, message = "set in case of success. Returns the requested scheduled process", response = NamesContainer.class)})
public Response sayHello(HttpServletResponse response) {
switch (request.getHeader("accept"))
{
case MediaType.APPLICATION_XML:
response = Response.ok().entity(/*yourEntity here (for me it was NamesContainer)*/).type(MediaType.APPLICATION_XML).build();
break;
case MediaType.TEXT_HTML:
response = Response.ok().entity(/*Transform xml to HTML with xsl and return it here as String*/).type(MediaType.TEXT_PLAIN).build();
break;
}
}