流程:前端控制器控制/请求,也就是全部请求来了都走进前端控制器(在servlet-mapping中设置),然后用户发送/hello请求,因为属于前端控制器的范围,因此它会响应用户的请求
现在的版本中,开启注解支持,默认帮我们导入处理映射器与处理适配器,因此我们只要定义:
前端控制器
视图解析器
就能执行,这就是原因
<!--开启springmvc注解支持 RequestMapping这些就是开启才会生效的(默认自带处理映射器与处理适配器)-->
<mvc:annotation-driven/>
请求参数绑定在Spring mvc中十分简单,我们只需要将方法的名字和请求的参数的key相同即可绑定成功
请求绑定在Spring mvc中十分简单,只需要请求参数名字和方法名相同即可
如果是对象,使用表单name值和字段名相同即可 如果对象中还有对象,则使用user.uName 这样的name即可
<form action="param/testParam2" method="post">
<%--类中的属性--%>
<input name="username" placeholder="姓名"/>
<input name="password" type="password" placeholder="密码">
<input name="money" placeholder="账户金额">
<%--对象--%>
<input name="user.uName" placeholder="用户名">
<%--list--%>
<input name="list[0].uName" placeholder="第一个list字段"/>
<input name="list[1].uName" placeholder="第一个list字段"/>
<%--map--%>
<input name="map[‘one‘].uName" placeholder="第一个map字段"/>
<input name="map[‘two‘].uName" placeholder="第二个map字段"/>
<button type="submit">提交</button>
</form>
用于解决post乱码问题,我们可以使用过滤器
<!--配置过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<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>
因为date自动装配的时候,只要按照指定格式才能自动装配成功,否则报400客户端的错误,这时候就需要自定义类型转换器来实现我们的功能。
import org.springframework.core.convert.converter.Converter;
?
public class String2DateConverter implements Converter<String, Date> {
<!--类型转换器-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters" ref="string2DateConverter"/>
</bean>
<bean id="string2DateConverter" class="com.jd.nxj.utils.String2DateConverter"/>
<!--开启springmvc注解支持 RequestMapping这些就是开启才会生效的(默认自带处理映射器与处理适配器)-->
(这个注解默认处理映射器与处理适配器生效,但是类型转换器并没有默认生效,因此我们在这里配置一下)
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
<a href="param/testServlet">获取原生API只需要在方法参数中加上即可</a>
//获取原生API
说明:自动装配的名字和我参数名不同,我可以通过这个注解指定
<a href="testRequestParam?n=nxj">RequestParam</a>
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam("n") String name){
System.out.println(name);
return "success";
}
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);//user=nxj&pass=123
return "success";
}
<form action="testRequestBody" method="post">
姓名:<input name="user"/><br/>
密码:<input name="pass"/><br/>
<input type="submit" value="提交"/>
</form>
<a href="testPathVariable/nxj">PathVariable</a>
@RequestMapping("/testPathVariable/{user}")
public String testPathVariable(@PathVariable("user") String user){
System.out.println(user);
return "success";
}
(这个不用急,配置比较麻烦,以后需要用的时候百度一下就好)
用的很少(获取请求头信息)
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
System.out.println(header);
return "success";
}
<a href="testRequestHeader">RequestHeader</a>
用的很少(获取Cookie信息)
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
System.out.println(cookieValue);
return "success";
}
<a href="testCookieValue">CookieValue</a>
放在方法上,则是在调用controller之前执行这个方法(什么意思呢?就是只要你的这个请求走进了某个controller,那么这个controller下标注了@ModelAttribute注解的方法都会在调用前执行)
//Person 中只有name与date两个字段
@RequestMapping("/testModelAttribute")
public String testModelAttribute(Person person){
System.out.println("testModelAttribute执行");
System.out.println(person);
return "success";
}
@ModelAttribute
public Person testMethod(String name){//name和传进来的是一样的
System.out.println(name);
Person person=new Person();
person.setName("qwe");//原来有的不会覆盖,原来没有的则覆盖
person.setDate(new Date());
return person;
}
<form action="testModelAttribute" method="post">
姓名:<input name="name"/><br/>
<input type="submit" value="提交"/>
</form>
另一种无返回值的
@RequestMapping("/testModelAttribute")
public String testModelAttribute(Person person,@ModelAttribute(value = "abc") Person person1){
System.out.println("testModelAttribute执行");
System.out.println(person);//Person{name=‘宁新杰‘, date=null}
System.out.println("==");
System.out.println(person1);//Person{name=‘宁新杰‘, date=Fri Nov 20 20:15:32 CST 2020}
return "success";
}
@ModelAttribute
public void testMethod(String name, Map<String,Object> map){
System.out.println("这里是AnnotationController");
System.out.println(name);
Person person=new Person();
person.setName("qwe");//原来有的不会覆盖,原来没有的则覆盖
person.setDate(new Date());
map.put("abc",person);
}
(这个不要看这个注解了 , 学习中用到的是SessionAttributes,只能标注在类上)
@RequestMapping("/testSeesionAttribute")
public String testSeesionAttribute(Model model){
System.out.println("testSeesionAttribute");
//底层会存储到request域中
model.addAttribute("msg","你好啊");
//这样在success这个跳转页面使用${requestScope}取request所有信息能看到 或者直接使用${msg}获取值
return "success";
}
请求地址都一样,根据不同的请求方式(如POST,GET,PUT,DELETE等)选择不同的方法执行
//返回值类型为String
@RequestMapping("/testString")
public String testString(Model model){
User user=new User("nxj","123",23);
model.addAttribute("user",user);
return "success";
}
<h1>this is success page</h1>
<div style="color: aquamarine">
<h1>testString</h1>
${user.toString()}
</div>
//返回值类型为void
@RequestMapping("/testVoid")
public void testVoid( HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
System.out.println("void method");
//默认 按照视图解析器前缀/user/testVoid.jsp(.jsp就是后缀) 这个
//方法一:使用转发(因为转发不走视图解析器,因此我们需要自己写完整的路径)(转发是在系统资源内,系统转发,因此可以跳转到任何系统内的资源页面)
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//如果要到成功页面只能使用转发,若非WEB-INF下的页面则使用重定向
//方法二:重定向,这是发的第二次请求,因此需要带上项目名(重定向不能走进WEB-INF下的页面)
response.sendRedirect(request.getContextPath()+"/index.jsp");
//为了防止转发后面有代码继续执行,加return
return;
}
在强调一下:forward是系统内部资源转发,因此它能转发到WEB-INF下的资源,而redirect是外部重定向,因此重定向是无法直接访问WEB-INF下的资源
使用关键字进行使用的时候不会经过视图解析器,因此我们需要写全
@RequestMapping("/testForwardOrRedirect")
public String testForwardOrRedirect(){
System.out.println("testForwardOrRedirect");
return "forward:/WEB-INF/pages/success.jsp";
return "redirect:/user/testString"; //其中/user是class上requestMapping ;/testString是他下面的一个方法的requestMapping。
return "redirect:/index.jsp";// 使用关键字的时候不需要加项目名称,因此框架底层帮我们做了,但是上面那代码直接调用就需要加。
}
####
原文:https://www.cnblogs.com/ningxinjie/p/14014618.html