SpringMVC核心控制器:DispatchServlet,其实就是servlet,单例的
自定义的action可继承,可实现,也可不继承,不实现
web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- springmvc核心控制器DispatcherServlet--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定mvc去类路径下加载Spring.xml文件,不指定的时候默认是加载web-inf下面的 DispatcherServlet-servlet.xml--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <!-- 编码过滤器 --> <filter> <filter-name>encodings</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>encodings</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
|
注意:
1、只要请求符合拦截路径,所有的action都已经创建好了
映射器、适配器、视图解析器
映射器(BeanNameURLHandlerMapping):【可选】用于映射路径的,把<bean>中的路径映射给mvc,一个路径对应一个bean节点
<bean name="/add.action" class="wei.HelloAction"></bean>
<bean name="/delete.action" class="wei.HelloAction"></bean>
<!-- 默认的 把bean节点的name属性作为请求路径 处理 每个请求必须是一个bean节点-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
SimpleURLHandlerMapping :多个路径引用一个action。
<bean id="helloActionID" class="wei.HelloAction"></bean>
<!-- 简单url映射处理器 多个路径用一个bean配置 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- 这4个路径都引用了Id为helloActionID的bean -->
<prop key="/add.action">helloActionID</prop>
<prop key="/delete.action">helloActionID</prop>
<prop key="/update.action">helloActionID</prop>
<prop key="/findAll.action">helloActionID</prop>
</props>
</property>
</bean>
适配器(SimpleControllerHandlerAdapter):【可选】 告诉mvc action实现了什么接口
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
控制器 (Controller): 告诉mvc action继承了什么类。【必须配置】
ParameterizableViewController:从jsp到jsp的控制器。如:直接跳到web-inf下面的jsp
<bean name="/hello.action" class="org.springframework.web.servlet.mvc.ParameterizableViewController" >
<property name="viewName" value="/success.jsp"></property>如果路径是逻辑路径,视图解析器一定要配置
</bean>
AbstractCommandController:自动封装参数控制器
我的action类要继承该类
public AbstractCommandController(){
// 设置表单中参数对应的封装的类型。
this.setCommandClass(Emp.class);
}
/**
* obj:从构造器中传进来的类型 赋给obj 。
* error:绑定时出现异常
*
*/
@Override
protected ModelAndView handle(
HttpServletRequest request,
HttpServletResponse response,
Object obj, BindException error)throws Exception {
Emp emp = (Emp)obj;
ModelAndView modelAndView = new ModelAndView();
return modelAndView;
}
视图解析器(InternalResourceViewResolver):如果返回路径是真实路径就可以省略,如果是逻辑路径的时候,视图解析器一定要配置。
Action的开发方式有
1、实现Controller接口
2、继承AbstractCommandController类 日期转换、参数封装等....
3、注解方式,不用继承也不用实现。第二天
如果是继承或实现用ModelAndView来传递参数到页面,如果是注解方式用Model即可。
导包: Spring 的core和mvc
解决post乱码问题
Spring框架提供了一个过滤器类,专门处理post乱码问题
<!-- 编码过滤器 -->
<filter>
<filter-name>encodings</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>encodings</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SpringMVC解决接收日期类型的参数
在struts中,能默认将”2015-04-6”字符串类 型的日期转成日期类型。
在mvc中不能,必须自定义类型转换器、
方式一、action只有继承AbstractCommandController才有此方法。
@Override
public void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
/**
* 参数一:要把字符串形式的日期转换成什么类型
* 参数二:自定义转换规则,true :表示该参数可以为null。
*/
binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy年MM月dd日"),true));
}
方式二:只需要加个注解即可:@initBinder
在页面中按照指定的格式显示日期jstl:
1、在jsp中导入<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
2、使用标签格式化日期:
<!--
value:要格式化的值。
type:显示时间(time)或日期(date)或都显示(both)
dateStyle:格式。 timeStyle
short:17-1-31 下午12:07
medium:2017-1-31 12:07:39
default:2017-1-3112:07:53
long:2017年1月31日 下午12时08分26秒
full:2017年1月31日 星期二 下午12时08分42秒 CST
-->
<%
Date date = new Date();
request.setAttribute("date", date);
System.out.println("日期是:"+date);
%>
<fmt:formatDate
value="${requestScope.date }"
type="date"
dateStyle="full"
/>
Springmvc和struts的区别:
SpringMVC是Spring框架中的web模块的一个功能。
1、struts的入口是过滤器Filter StrutsPrepareAndExecuteFilter、SpringMvc的入口是servlet DispatcherServlet
2、struts是基于类开发,是通过类属性来接收参数的,action是多例的
SpringMvc是基于方法开发,是通过方法形参来接收参数的。action是单例的。
3、struts是把数据存储到值栈对象中再把值栈对象设置到request对象中传到页面的 可以用EL(不仅能取域中的值,还能计算)或ognl(只能取 域中的值)表达式取值
SpringMvc是把数据存储到ModelAndView对象中或直接放到域中,再传到页面
SpringMvc的工作流程:
如:
public class DispatchServlet{
public void service(){
1、调用映射器来解析用户请求。
2、通过适配器找到对应的action,action中把数据封装到ModelAndView
3、调用视图解析器来得到需要跳转的资源
4、转发
}
}
注解方式开发action:
1、写普通的java类
2、在类的前面加@Controller注解。在方法的前面加@RequestMapping(“/hello.acction”),可以有多个,是个value数组
3、在配置中配置扫描注解标签,需要导入context名称空间
注意:如果方法需要传递数据到页面,可以在方法中定义ui.Model类型的形参
如果方法返回值是个逻辑路径,那么一定还要配置视图解析器。。
如果@RequestMapping写在类上面类似struts中的名称空间,访问该类的方法要拼上该注解的路径。
其实是由默认是映射器来找到action的org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping[可省配置]
在action中处理参数:
方式一:方法中用普通变量来接收参数:
如:public void add(Model model ,String username,String pass){}
弊端:如果参数过多就不好了。
方式二:使用实体模型接收参数:
当页面有相同名字的时候 实体模型要封装到一个包装类中。
用法只用包装类中的引用实体.实体的属性
public void register(Bean bean , Model model){.......}
public class Bean{
private User user;
private Admin admin;
set/get....
}
jsp
<input name=”user.userName”>......
方式三:使用数组来接收参数:
在方法中定义一个int数组,只要是和形参名字一样的参数就会通通收集到数组中。
public void deleteAll(int[] ids){}//收集表单参数名为ids的参数。
方式四:使用泛型list来接收多个参数:如:List<User> userList 来接收表单中的多个User
写包装bean 把userList作为该类的成员变量,set/get..
action 中 public void addUsers(List<User> userList){}
jsp 中 <input name=”userList[0].userName”>
<input name=”userList[0].password”>.........
方法只限某种请求方式访问 (get、post......)
@RequestMapping(method = {RequestMethod.POST,RequestMethod.GET},“/hello.acction”)//只限于Post或get请求方式
在方法中使用servlet传统的对象,如:HttpServletRequest/HttpServletResponse/...
public void add(....){
}
结果的转发和重定向 :
转发:
会将参数从第一个方法传入第二个方法。
public String update(int id){
retrun “forward:/action模块名/action方法访问名”;
}
重定向:不能共享参数
public String update(int id){
retrun “redirect:/action模块名/action方法访问名”;
}
将bean转成json
步骤:
1、导包
jackson-core-asl-1.9.11.jar
jackson-mapper-asl-1.9.11.jar
2、方法的书写 @ResponseBody 要把什么转成json
public @ResponseBody Map<String,Object> map2json()throws Exception{ return map}
3、配置适配器
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
普通bean:
list集合:
map集合: