不能 return 来自 @RestController 方法的字符串
Cannot return String from @RestController method
我正在使用 Spring Boot 2.4.5、MyBatis 3.5.6 和 Java 8。当尝试 return 来自 @RestController
的字符串时, returned HttpErrorResponse
.
中出现了一个模糊的错误
该方法尝试通过 MyBatis 获取值,即 DAO 对象中充当 @Mapper
.
的方法
我的控制器方法:
@RestController
@RequestMapping("/api/myAPI")
public class MyController{
@Resource
private MyService service;
@GetMapping(value = "myString")
public String getBillingCompany() {
return this.service.getDAO().getMyString();
}
}
我的 DAO:
@Repository
@Mapper
public interface MyDAO{
String getMyString();
}
...以及 MyBatis 映射器:
<mapper namespace="com.package.MyDAO">
<select id="getMyString" resultType="String">
SELECT 'My desired result' FROM A_TABLE
</select>
...
</mapper>
HttpErrorResponse:
HttpErrorResponse: {
"headers": {
"normalizedNames": {},
"lazyUpdate": null
},
"status": 200,
"statusText": "OK",
"url": "http://localhost:4200/api/myAPI/myString",
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure during parsing for http://localhost:4200/api/myAPI/myString",
"error": {
"error": { SyntaxError: Unexpected number in JSON at position 2
at JSON.parse (<anonymous>)
at XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:18158:51)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:21266:35)
at Object.onInvokeTask (http://localhost:4200/vendor.js:74037:33)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:21265:40)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:4200/polyfills.js:21033:51)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:4200/polyfills.js:21348:38)
at invokeTask (http://localhost:4200/polyfills.js:22516:18)
at XMLHttpRequest.globalZoneAwareCallback (http://localhost:4200/polyfills.js:22553:25)
},
"text": "My desired result"
}
}
尽管如此,如果我向控制器和 DAO 方法请求 return 和 int
,一切都会完美无缺。
因此,我怀疑问题与非原始类型“命名空间”有关,所以我尝试在 MyBatis 配置中设置 typeAlias
,但无济于事:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="java.lang.String" alias="String"/>
</typeAliases>
</configuration>
无论如何,我的印象是 MyBatis 和 Spring 应该已经足够聪明,知道 String
是什么。我过去已经成功 returned 对象集合(Map
s 和 List
s)和 POJO。
关于我缺少或没有看到的东西有什么想法吗?提前致谢。
编辑:
到目前为止,唯一对我有用的东西与@emeraldjava 提出的相似。我在依赖项中的现有包装器上构建了一个包装器,在我的 Front:
中获取 data
@RestController
@RequestMapping("/api/myAPI")
public class MyController{
@Resource
private MyService service;
@GetMapping(value = "myString")
public Result<String> getBillingCompany() {
return new Result<>(this.service.getDAO().getMyString());
}
}
public class Result<T> extends ServiceResult {
public Result(T data) {
this.setData(data);
}
}
依赖项中已经存在的包装器:
public class ServiceResult {
private Object data;
...
public void setData(Object data) {
this.data = data;
}
public Object getData() {
return this.data;
}
}
我认为问题在于您正在查询的 table 有多行,因此您的查询结果将是一个字符串列表,每个元素都包含“我想要的结果”,其中列表的大小等于 table 中的行数。为了强制单个结果,只需将查询更改为:
<select id="getMyString" resultType="String">
SELECT MAX('My desired result') FROM A_TABLE
</select>
我建议您将 Controller 方法更新为包装字符串的 ResponseEntity。
@RestController
@RequestMapping("/api/myAPI")
public class MyController{
@Resource
private MyService service;
@GetMapping(value = "myString")
public ResponseEntity getBillingCompany() {
return new ResponseEntity<Object>(this.service.getDAO().getMyString(), HttpStatus.OK);
}
}
我正在使用 Spring Boot 2.4.5、MyBatis 3.5.6 和 Java 8。当尝试 return 来自 @RestController
的字符串时, returned HttpErrorResponse
.
该方法尝试通过 MyBatis 获取值,即 DAO 对象中充当 @Mapper
.
我的控制器方法:
@RestController
@RequestMapping("/api/myAPI")
public class MyController{
@Resource
private MyService service;
@GetMapping(value = "myString")
public String getBillingCompany() {
return this.service.getDAO().getMyString();
}
}
我的 DAO:
@Repository
@Mapper
public interface MyDAO{
String getMyString();
}
...以及 MyBatis 映射器:
<mapper namespace="com.package.MyDAO">
<select id="getMyString" resultType="String">
SELECT 'My desired result' FROM A_TABLE
</select>
...
</mapper>
HttpErrorResponse:
HttpErrorResponse: {
"headers": {
"normalizedNames": {},
"lazyUpdate": null
},
"status": 200,
"statusText": "OK",
"url": "http://localhost:4200/api/myAPI/myString",
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure during parsing for http://localhost:4200/api/myAPI/myString",
"error": {
"error": { SyntaxError: Unexpected number in JSON at position 2
at JSON.parse (<anonymous>)
at XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:18158:51)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:21266:35)
at Object.onInvokeTask (http://localhost:4200/vendor.js:74037:33)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:21265:40)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:4200/polyfills.js:21033:51)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:4200/polyfills.js:21348:38)
at invokeTask (http://localhost:4200/polyfills.js:22516:18)
at XMLHttpRequest.globalZoneAwareCallback (http://localhost:4200/polyfills.js:22553:25)
},
"text": "My desired result"
}
}
尽管如此,如果我向控制器和 DAO 方法请求 return 和 int
,一切都会完美无缺。
因此,我怀疑问题与非原始类型“命名空间”有关,所以我尝试在 MyBatis 配置中设置 typeAlias
,但无济于事:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="java.lang.String" alias="String"/>
</typeAliases>
</configuration>
无论如何,我的印象是 MyBatis 和 Spring 应该已经足够聪明,知道 String
是什么。我过去已经成功 returned 对象集合(Map
s 和 List
s)和 POJO。
关于我缺少或没有看到的东西有什么想法吗?提前致谢。
编辑: 到目前为止,唯一对我有用的东西与@emeraldjava 提出的相似。我在依赖项中的现有包装器上构建了一个包装器,在我的 Front:
中获取data
@RestController
@RequestMapping("/api/myAPI")
public class MyController{
@Resource
private MyService service;
@GetMapping(value = "myString")
public Result<String> getBillingCompany() {
return new Result<>(this.service.getDAO().getMyString());
}
}
public class Result<T> extends ServiceResult {
public Result(T data) {
this.setData(data);
}
}
依赖项中已经存在的包装器:
public class ServiceResult {
private Object data;
...
public void setData(Object data) {
this.data = data;
}
public Object getData() {
return this.data;
}
}
我认为问题在于您正在查询的 table 有多行,因此您的查询结果将是一个字符串列表,每个元素都包含“我想要的结果”,其中列表的大小等于 table 中的行数。为了强制单个结果,只需将查询更改为:
<select id="getMyString" resultType="String">
SELECT MAX('My desired result') FROM A_TABLE
</select>
我建议您将 Controller 方法更新为包装字符串的 ResponseEntity。
@RestController
@RequestMapping("/api/myAPI")
public class MyController{
@Resource
private MyService service;
@GetMapping(value = "myString")
public ResponseEntity getBillingCompany() {
return new ResponseEntity<Object>(this.service.getDAO().getMyString(), HttpStatus.OK);
}
}