Q&A:
Q1.MatrixVariable 无法后台取值。 A1:<mvc:annotation-driven enable-matrix-variables="true"/>,默认是false。
Q2.
<mvc:resources mapping="/resources/**"
location="/public, classpath:/static/"
cache-period="31556926" />
其中的/public不能对放置在应用根目录下的public文件夹中文件生效,不知道什么原因;classpath:/static/能够使用
A2. /public的写法不对,应为/public/, 代表的应用根路径,如果项目跟路径下有image文件夹,之中有1.jpg,则访问路径为http://ip/appname/resources/image/1.jpg. location的值要以/结尾,并且不应包含*通配符。cache-period通过Last-Modified消息头来控制缓存,若资源没有在服务器端发生变动,会返回304状态码告诉浏览器资源未变动。若将Last-Modified的值设为0,则禁止浏览器端缓存。
Q3. ResponseEntity返回值存在乱码问题。
A3.
@RequestMapping("/checkUsername")
@ResponseBody
public ResponseEntity<String> checkUsername(@RequestParam String userName) {
User user = service.getUserByUserName(userName);
MediaType mediaType = new MediaType("text","html",Charset.forName("UTF-8"));
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(mediaType);
String result = "";
if (user==null) {
result = "<font color='green'>用户名可以使用</font>";
}else {
result = "<font color='red'>用户名被占用</font>";
}
return new ResponseEntity<String>(result, responseHeaders, HttpStatus.OK);
}
Note:
N1. @ResponseBody: The return value is converted through HttpMessageConverters and written to the response. 返回实体类时,会出现客户端异常406(NotAcceptable),这种返回实体类的方式应该是给non-browser端使用的。
N2. @RequestParam String name,那么如果要匹配这个变量必须参数名为变量名,即:http://localhost/springmvc/hello/sayHello5?name=aaa
N3. ResponseEntity,HttpEntity:
@RequestMapping("/something")
public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException {
String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader");
byte[] requestBody = requestEntity.getBody();
// ...
}
N4. @ModelAttribute在方法上的两种用法
// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")
@ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}
// Add multiple attributes
@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
model.addAttribute(accountManager.findAccount(number));
// add more ...
}
An @ModelAttribute on a method indicates the purpose of that method is to add one or more model attributes.
Such methods support the same argument types as @RequestMapping methods but cannot be mapped directly to requests.
Instead @ModelAttribute methods in a controller are invoked before @RequestMapping methods, within the same controller.
N5. 通过@ModelAttribute的方法在model添加一个User对象,名称即为user,当用@ModelAttribute在参数上的方法提取user时,若路径中有相应的字段则优先使用路径中的字段来创建一个User对象并用user命名,覆盖之前那个user中的属性,若部分字段找不到,则继承原user的那些属性的值。
N6. You can match Content-Type and Accept with the headers condition but it is better to use consumes and produces instead.
N7. headers 类似于:
{host=[localhost], connection=[keep-alive], upgrade-insecure-requests=[1], user-agent=[Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/55.0.2883.87 Safari/537.36], accept=[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8], accept-encoding=[gzip, deflate,sdch, br], accept-language=[zh-CN,zh;q=0.8], cookie=[JSESSIONID=F66346B0ED9D28AA54C666C258CDAB1C; CKFinder_Settings=TNNDS;CKFinder_Path=Images%3A%2F%3A1; __guid=111872281.4574645707235340300.1504704591177.7593; monitor_count=81]}
N8. servlet异步请求实在servlet3开始出现的.
N9. PropertyEditorSupport:当从字符串型数据转换为所需对象时,会先调用setValue方法,不过传入的值为空,再调用setAsText方法,在父类中的该方法会直接将传入的字符串赋值给value(取数据是通过getvalue方法,所以value一定要通过一定方法赋值),这时可通过在setAsText将字符串转变为所需对象,然后主动调用setvalue方法,删除掉super.setAsText方法,即可。
当从model中取得对象并做相应的类型转换时,并不会调用setAsText方法,而只调用setvalue方法,并且传入被转换的对象,在setvalue方法中我们将其转换为所需对象,然后调用super.setValue(user)方法,将转换后的对象存入。
N10. 自定义了webBindingInitializer,会覆盖默认的系列类型转换,建议使用@InitBinder,对于多处使用的类型转换将@InitBinder结合@ControllerAdvice使用.