提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、请求参数的封装
1.1通过input标签可以构造请求
1.2非json数据的封装
1.2.1通过request(并不建议)
/**
* 通过request封装请求参数
*/
@RequestMapping("request/parameter")//request/parameter?username=songge&password=niupi
@ResponseBody
public BaseResponseVo requestParameteter(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
return BaseResponseVo.ok(username + " : " + password);
}
1.2.2handler方法中直接接收
1.2.2.1字符串、基本类型包装类
/**
* 直接在handler方法上接收请求参数 → 请求参数名和handler方法的形参名一致
* directParameter方法中的形参与input标签中的name属性一一对应,进行参数的接收
*/
@RequestMapping("direct/parameter")//direct/parameter?username=songge&password=niupi
@ResponseBody
public BaseResponseVo directParameteter(String username,String password,Integer age,boolean married){
return BaseResponseVo.ok(username + " : " + password);
}
<h1>形参直接接收请求参数</h1>
<form action="/direct/parameter" method="get">
用户:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
婚配:<input type="text" name="married"><br>
<input type="submit">
</form><hr>
1.2.2.2日期格式的接收
/**
*springmvc没有提供一个直接将字符串转换为日期格式的转换器 → 需要加注解指定格式
*/
@RequestMapping("birthday")
@ResponseBody
public BaseResponseVo birthday(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
return BaseResponseVo.ok(birthday);
}
<h1>接收日期格式数据</h1>
<form action="/birthday" method="get">
生日:<input type="text" name="birthday"><br>
<input type="submit">
</form><hr>
1.2.2.3文件
文件上传 → 注解组件multipartResolver → commons-io/fileupload
@RequestMapping("file/upload")
@ResponseBody
public BaseResponseVo fileUpload(MultipartFile myfile){ //参数myfile与input标签中的name属性相对应
String originalFilename = myfile.getOriginalFilename();
File file = new File("D:\\spring", originalFilename); //用来接收上传的文件
try {
myfile.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
return BaseResponseVo.ok();
}
<h1>接收文件格式数据 → 文件上传</h1>
<form action="/file/upload" enctype="multipart/form-data" method="post">
文件:<input type="file" name="myfile"><br>
<input type="submit">
</form>
可以上传多个文件
依然要求请求参数名和handler方法的形参名一致,但是要用MultipartFile[]数组接收
1.2.2.4数组
@RequestMapping("array")
@ResponseBody
public BaseRespVo array(String[] hobbys){
return BaseRespVo.ok(hobbys);
}
<h1>数组</h1>
<form action="array" method="post">
爱好1:<input type="text" name="hobbys">
爱好2:<input type="text" name="hobbys">
爱好3:<input type="text" name="hobbys">
爱好4:<input type="text" name="hobbys">
<input type="submit">
</form><hr>
1.2.3Conventer
conventer转换器,用于不能直接接收的类型
做的事情就是string格式→xxx格式
举个例子:
Date不能直接接收→使用@DateTimeFormat进行转换
除了使用注解,可以提供一个通用的转换器,自定义转换器
String→Date
(1)定义converter组件
@Component //注册为组件
public class String2DateConverter implements Converter<String, Date> { //String转换成Date
@Override
public Date convert(String s) {//在convert方法中写转换逻辑
Date parse = null;
try {
parse = new SimpleDateFormat("yyyy-MM-dd").parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
Converter接口
(2)注册conversionService
<bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="string2DateConverter"/>
</set>
</property>
</bean>
(3)告知springmvc
<mvc:annotation-driven conversion-service="formattingConversionService"/>
(4)使用
1.2.4通过javabean接收
上面的例子中数据是在handler方法中以形参的形式接收,还可以将数据封装成javabean的形式进行接收,把这些形参定义为成员变量,要求请求参数名和javabean的成员变量名一致。
1.2.4.1 嵌套javabean
1.2.4.2 javabean中List
1.2.5解决post请求的中文乱码问题
在web.xml中配置filter。
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.3 json数据的封装
@RequestMapping("json/receive")
@ResponseBody//返回json数据
public BaseRespVo jsonReceive(@RequestBody User user){//加上@RequestBody,接收json数据
return BaseRespVo.ok(user);
}
@RequestMapping("json/receive2")
@ResponseBody
public BaseRespVo jsonReceive(@RequestBody Map userMap){//也可以以Map数据格式接收
Object username = userMap.get("username");
return BaseRespVo.ok(userMap);
}
tip:
二、其他参数的封装
2.1直接放入request和response
这个在返回类型为void和通过request获得请求参数的过程使用过了。
2.2Model
返回值为String类型,使用Model作为形参。
2.3Cookie和session
2.3.1Cookie需要通过request
@RequestMapping("get/cookie")
@ResponseBody
public BaseRespVo getCookie(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + " : " + cookie.getValue());
}
return BaseRespVo.ok();
}
2.3.2Session
2.3.2.1通过request获得
@RequestMapping("put/session")
@ResponseBody
public BaseRespVo getSession(HttpServletRequest request,String username){
HttpSession session = request.getSession();
session.setAttribute("username",username);
return BaseRespVo.ok();
}
@RequestMapping("get/session")
@ResponseBody
public BaseRespVo getSession(HttpServletRequest request){
HttpSession session = request.getSession();
Object username = session.getAttribute("username");
return BaseRespVo.ok(username);
}
2.3.2.2直接将HttpSession写在形参上
@RequestMapping("get/session2")
@ResponseBody
public BaseRespVo getSession(HttpSession session){
Object username = session.getAttribute("username");
return BaseRespVo.ok(username);
}
三、Restful风格请求
rest → 表述性状态传递 → 代码风格 → 响应结果用json
3.1@PathVariable(url)
使用请求url的一部分提供请求参数
username/article/details/articleId等价于article/details?username=xxxx&articleId=xxx
//请求参数作为url的一部分
@RequestMapping("{usernamea}/article/details/{articleIdb}")
public BaseRespVo articleDetails(@PathVariable("usernamea") String username,
@PathVariable("articleIdb") String articleId){
return BaseRespVo.ok(username + ":" + articleId);
}
3.2@RequestParam(请求参数)
请求参数和@RequestParam注解的属性值一致
@RequestMapping("admin/login")//?usernamea=xxx&passwordb=xxx
public BaseRespVo login(@RequestParam("usernamea") String username,
@RequestParam("passwordb") String password){
return BaseRespVo.ok();
}
3.3@RequestHeader(请求头)
@RequestMapping("get/header")//也可以以数组的形式接收,通过逗号,分割开的
public BaseRespVo getHeader(@RequestHeader("Accept") String[] accept,
@RequestHeader("Host") String host){
return BaseRespVo.ok();
}
3.4@CookieValue
之前cookie是通过request.getCookies方法获得的cookie数组
@CookieValue是取出 cookie的name为某个值的对应的cookie Value
@RequestMapping("cookie/value")
public BaseRespVo cookieValue(@CookieValue("xiaoming") String value,
@CookieValue("xiaohong")String value2){
return BaseRespVo.ok();
}
3.5@SessionAttribute
@RequestMapping("put/session/{username}")
public BaseRespVo getSession(HttpSession session, @PathVariable("username") String username){
session.setAttribute("username",username);
return BaseRespVo.ok();
}
@RequestMapping("session/attribute")
public BaseRespVo getSessionAttribute(@SessionAttribute("username") String username){
return BaseRespVo.ok(username);
}
四、静态资源访问
4.1默认的servlet
配置web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
4.2默认的servlet的handler
<mvc:default-servlet-handler/>
4.3静态资源映射(推荐)
请求url和文件建立联系
<!--mapping:请求url-->
<!--location:文件路径
1、classpath路径
2、web根路径
3、文件路径
-->
<!--mapping中的值 + 相对于location的值-->
<!--以第一个为例:输入的url→"/pic1/图片相对location的相对路径"
<mvc:resources mapping="/pic1/**" location="classpath:/img/"/><!--1、classpath路径-->
<mvc:resources mapping="/pic2/**" location="/WEB-INF/img/"/><!--2、web根路径-->
<mvc:resources mapping="/pic3/**" location="file:D:/spring/"/><!--3、文件路径-->
五、SpringMVC的异常处理
SpringMVC的异常:异常都向上抛出,最后抛给dispatcher处理。
5.1HandlerExceptionResolver
@Data
public class CustomException extends Exception{
String username;
public CustomException(String message, String username) {
super(message);
this.username = username;
}
}
@Controller
public class HelloController {
@RequestMapping("hello")
public String hello() throws CustomException {
//int i = 1/0;
if (true){
throw new CustomException("异常了", "lala");//message = 第一个参数 username=第二个参数
}
return "/WEB-INF/jsp/hello.jsp";
}
}
@Component//只要发生异常都进来
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object handler, Exception e) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/WEB-INF/jsp/exception.jsp");
//如果是除零异常code就为502
//如果是其他异常则为500
if (e instanceof ArithmeticException){//可以根据不同的异常类型,做个性化的处理
modelAndView.addObject("code", 502);
}else if(e instanceof CustomException){//如果是自定义异常类型
CustomException customException = (CustomException) e;//通过Exception类型的参数e获取信息
String message = customException.getMessage();
String username = customException.getUsername();
modelAndView.setViewName("/WEB-INF/jsp/custom.jsp");
modelAndView.addObject("usernamez", username);
}
else {
modelAndView.addObject("code", 500);
}
String message = e.getMessage();
modelAndView.addObject("message", message);
return modelAndView;
}
}
5.2ExceptionHandler
可以处理视图,也可以处理json,按照异常类型映射到handler方法上处理。
//@ControllerAdvice
//@ResponseBody//写在类上,意味着当前类的全部handler方法返回的都是json
@RestControllerAdvice//等价于上面的两个注解
public class ExceptionControllerAdvice {
@ExceptionHandler({CustomException.class})
public String customException(CustomException e){
String username = e.getUsername();
String message = e.getMessage();
return "/WEB-INF/jsp/custom.jsp";
}
@ExceptionHandler({CustomException2.class})
//@ResponseBody
public BaseRespVo customException2(CustomException2 e){
return BaseRespVo.fail("lalala");
}
}