springMVC开发问题总结
记录坑
1.使用PUT时,后台接受不到放在body中的参数【接受到参数为null】:
在web.xml中加入如下配置:
该方案适用于处理MIME type类型为(application/x-www-form-urlencoded)的情况,更多详情见连接
关于MIME type取值的一些说明见连接
2.web.xml中,为何可以配置两个contextConfigLocation(<servlete> 的<init-param> 及<context-param>),它们有什么不一样么:
"spring框架在加载web配置文件的时候。首先加载的是context-param配置的内容,而并不会去初始化servlet。只有进行了网站的跳转,经过了DispatcherServlet的导航的时候,才会初始化servlet,从而加载init-param中的内容。init-param中的xml因为被配置在servlet的初始化过程中,所以如果不初始化servlet,那么init-param中的xml是不会被发现的" -- from:博客
为什么能够一开始就加载context-param配置的xml呢?
因为context-param的使用伴随着ContextLoaderListener监听器的运用,这歌配置Spring上下文监听器,它的作用就是在启动WEB容器时,自动装载contextConfigLocation配置的xml。
3.升级spring 4.1到4.2时,报错: Invalid property 'mediaTypes' of bean class [org.springframework.web.servlet.view.ContentNegotiatingViewResolver]: Bean property 'mediaTypes' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter:
问题复现:因为spring 4.1的版本不能使用注解@CrossOrigin 来实现跨域,所以就升级了spring。升级后就出现这个问题。
原因:spring4.2版本的ContentNegotiatingViewResolver类没有针对mediaTypes的set方法了,同样的也没有针对ignoreAcceptHeader的set方法了,所以这两个属性不可写了。
解决办法:注释掉mediaTypes,ignoreAcceptHeader相关代码。
4.前端传json对象,后台获取不到传入数据的问题:
“By default, axios serializes JavaScript objects to JSON. To send data in the application/x-www-form-urlencoded format instead, you can use one of the following options.” --from:官方说明
若前端未对传到后台的数据做额外的处理,后台通过@RequestParam获取不到数据
解决办法:
1. 用@RequestBody Map map来接收数据,就可以从请求的body中拿到数据:
举例:String name = (String) map.get("name");
2. 用URLSearchParams传递参数,此时Request URL举例: http://127.0.0.1:8181/api/user/register?name=aaaa&password=aaaa, 可以看出使用URLSearchParams后,会将传入的URLSearchParams对象,解析到url中,这样,后端就可以通过@RequestParam解析到传递的参数;
3. 利用qs.stringify()将传递的json对象转换为string。
5.@ResponseBody注解,返回的对象中如果使用了枚举类型,则不会解析枚举,只会显示定义的枚举常量。
解决办法:
网上大部分都是用的conventer转换。我这里没有这么复杂,只是在添加值时多做一次枚举到类的转换:
在返回类A的定义中,定义一个属性为类B(类B 最好作为B的 非匿名内部类), 类B的属性和你之前的枚举l中的属性一致,并在类A中添加设置类B属性的方法。这样我们在设置返回值的时候使用的时枚举,但@ResponseBody解析的时候解析的是对象。
例:
public class A {
private B b;
private Object data;
public class B {
private Integer code;
private String msg;
// 省略B类其他应该有的 getter setter方法
// 构造函数:
public B(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
// 省略A类其他应该有的 getter setter方法
// 设置 b:
public setB(XXXEnum xXXEnum) {
this.b = new B(xXXEnum.getCode, xXXEnum.getMsg());
}
}
// 枚举的定义省略。
6.设置的切面aspect不生效。
原因:未在xml中进行aop相关的配置
解决方法见:一个博客
7.执行mybatis报错was not registered for synchronization because synchronization
原因:因为手动编写的mapper.xml,所以编写有错误,可能和数据库的字段对应不起来(字段名 及 格式)导致的这个错误
解决方案:可通过在mybatis的配置文件中设置<setting name="logImpl" value="STDOUT_LOGGING" />将数据库查询语句在控制台打印出来。分析数据库查询语句,可方便定位自己的错误。