1,ContextLoaderListener
应用上下文以前是
ApplicationContext app =new ClassPathXmlApplicationContext(“applicationContext.xml”);这样获取的
加载xml配置文件创建容器
每次都会加载配置创建容器 我们想创建加载一次
用监听器放到ServletContext域中 ServletContextListener是监听ServletContext创建的
就可以从servletContext域中获取ApplicationContext对象了
这是自己实现监听器
在web.xml设置全局参数(设置应用上下文对象)配置监听器
<!--全局初始化参数-->
<!--<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>-->
<!--配置监听器-->
<!--<listener>
<listener-class>com.flatly.listener.ContextLoaderListener</listener-class>
</listener>-->
<!--配置springMVC前端控制器-->
public class ContextLoaderListener implements ServletContextListener {
//服务器启动
public void contextInitialized(ServletContextEvent sce) {
// ApplicationContext app =new ClassPathXmlApplicationContext("applicationContext.xml");
//得到servletContext域
ServletContext servletContext = sce.getServletContext();
//读取webxml全局参数
String contextConfigLocation= servletContext.getInitParameter("contextConfigLocation");
ApplicationContext app =new ClassPathXmlApplicationContext(contextConfigLocation);
//将Spring应用上下文对象存储到ServletContext域中
servletContext.setAttribute("app",app);
System.out.println("spring容器创建完毕");
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
//这是返回应用上下文对象的工具
public class WebApplicationContextUtils {
//需要一个ServletContext域得到app
public static ApplicationContext getWebApplicationContext(ServletContext servletContext){
return (ApplicationContext) servletContext.getAttribute("app");
}
}
@WebServlet(value = "/userServlet")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
// ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");这里我们不期望还用写app所以创建了Util直接直接给你返回应用上下文对象
ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
Spring提供应用上下文的工具
1.导入坐标
(**********)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
(**********)
在web.xml配置sprig监听器
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
使用
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
SpringMVC快速入门
每个servlet都有共有的行为,接数据封实体,指派实体,还有特有行为
springmvc封装了前端控制器
1,导入坐标
(**********)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
2,配置servlet配置springmvc核心控制器DispathcerServlet
(**********)
<!--配置springMVC前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!--服务器启动时加载-->
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern><!--任何servlet-->
</servlet-mapping>
3创建Controller类和视图页面
4使用注解配置Controller类中业务方法的映射地址
@Controller
@RequestMapping(value = "/user")
public class UserController {
//请求地址http://localhost:8080/user/quick
@RequestMapping("/quick")
public String save(){
return "/success.jsp";//加/相当于从当前应用找success.jsp
}
5配置springmvc核心文件spring-mvc.xml
(**********)
<context:component-scan base-package="com.flatly.controller"/>
<!--扫描包下带Controller注解的包
<context:component-scan base-package="com.flatly">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
-->
@Controller用于定义Controller类实现Controller接口,实现handleRequest方法返回ModelAndView
@RequestMapping(/xxx)用于url与方法映射
@RequestMapping(
value = “/quick”,
method = RequestMethod.GET,
params = {“username”})//必须限定有请求必须要username
一些组件配置在这里
InternalResourceViewResolver->UrlBasedViewResolver
public static final String REDIRECT_URL_PREFIX = “redirect:”;
public static final String FORWARD_URL_PREFIX = “forward:”;
默认省略forword
// return "redirect:/success.jsp";地址变
public InternalResourceViewResolver(String prefix, String suffix) {
this();
this.setPrefix(prefix);
this.setSuffix(suffix);
}可以指定跳转视图的前缀后缀
这里jsp包下有个success.jsp
//return “forword:/jsp/success.jsp”;可以写成 return “success”;//
配置了视图资源解析器
在spring-mvc.xml
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀后缀/jsp/xxx/.jsp-->
<property name="prefix" value="/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
spring-mvc数据响应
1页面调转
1)直接返回字符串
2)通过ModelAndView对象返回
2会写数据
1)直接返回字符串
2)返回对象或集合(json)
通过modelAndView直接返回字符串
/*
* Model模型 作用封装数据
*
* View 视图 作用展示数据
* */
@RequestMapping("/quick2")
public ModelAndView save2(){
ModelAndView modelAndView = new ModelAndView();
//设置模型数据
//放到了request域中setAttibute
modelAndView.addObject("username","flatly");
//设置视图
modelAndView.setViewName("success");
return modelAndView;
}
注入参数ModelAndView 来返回参数不用自己new创建对象
@RequestMapping("/quick3")
public ModelAndView save3( ModelAndView modelAndView){
modelAndView.addObject("username","flatly2");
//设置视图
modelAndView.setViewName("success");
return modelAndView;
}
视图解析器+Model模型
@RequestMapping("/quick4")
public String save4(Model model){
model.addAttribute("username","flatly3");
return "success";
}
注入原始request(不常用)
@RequestMapping("/quick5")
public String save5(HttpServletRequest request){
request.setAttribute("username","flatly4");
return "success";
}
回写数据原始注入response(不常用)
//response.getWriter().print("aaaa")回写
@RequestMapping("/quick6")
public void save6(HttpServletResponse response) throws IOException {
response.getWriter().print("xxx");
}
直接return字符串使用@ResponseBody注解告知不要跳转页面回写
@RequestMapping("/quick7")
@ResponseBody//告诉spring不要页面调转
public String save7(){
return "hello flatly";
}
自己拼接json返回
@RequestMapping("/quick8")
@ResponseBody//告诉spring不要页面调转
public String save8(){
return "{\"username\":\"zhangsan\",\"age\":18}";//{"username":"zhangsan","age":18}json字符串
}
借助json工具装换
添加配置坐标jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
@RequestMapping("/quick9")
@ResponseBody//告诉spring不要页面调转
public String save9() throws IOException {
User user = new User("lisi",18);
//使用json的转换工具
ObjectMapper objectMapper =new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
return json;
}
spring自己可以自动封装json格式
配置spring-mvc.xml
(**********)
<!--配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
或者直接用这个 不用配处理器映射器
(**********)
<!--mvc注解驱动需要引入mvc命名空间-->
<mvc:annotation-driven"/>
直接return对象或集合
@RequestMapping("/quick10")
@ResponseBody//告诉spring不要页面调转
//期望SpringMVC自动将User转换成json字符串
public User save10() throws IOException {
User user = new User("lisi",18);
return user;
}
获得请求参数数据
获得普通类型参数
没有会报错
//获得普通类型参数
@RequestMapping("/quick11")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save11(String username,int age) throws IOException {
System.out.println(username);//http://localhost:8080/user/quick11?username=zhangsan&age=12
System.out.println(age);
}
根据请求自动封装实体
//SpringMVC自动封装POJO对象
@RequestMapping("/quick12")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save12(User user) throws IOException {
System.out.println(user);//User{username='zhangsan', age=12}
}
获得类似爱好多个 数组类型参数
//获得数组类型参数
@RequestMapping("/quick13")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save13(String[] strs) throws IOException {
System.out.println(Arrays.asList(strs));//http://localhost:8080/user/quick13?strs=aaa&strs=bbb&strs=ccc
//数组会打印地址list集合重写了toString方法 [aaa, bbb, ccc]
}
封装集合List list
直接封装不行 得创建VO对象封装
public class VO {
private List<User> userList;
public VO() {
}
...
前端
<form action="${pageContext.request.contextPath}/user/quick14" method="post">
<%--表明第几个User对象的username--%>
<input type="text" name="userList[0].username"><br>
<input type="text" name="userList[0].age"><br>
<input type="text" name="userList[1].username"><br>
<input type="text" name="userList[1].age"><br>
<input type="submit">
</form>
//获得集合类型参数
@RequestMapping(value = "/quick14")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save14(VO vo) throws IOException {
System.out.println(vo);
//VO{userList=[User{username='zhangsan', age=12}, User{username='lisi', age=14}]}
}
当前端发送的是ajax请求json格式时可以直接封装集合
这里用到jquery但是静态资源得有访问权限
在spring-mvc.xml中加入
<!--开放资源的访问-->
<mvc:resources mapping="/js/**" location="/js/"/>
var userList =new Array();
userList.push({username:"zhangsan",age:18});
userList.push({username:"lisi",age:18});
$.ajax(
{
type:"POST",
url:"${pageContext.request.contextPath}/user/quick15",
data:JSON.stringify(userList),
contentType:"application/json;charset=utf-8"
}
)
@RequestMapping(value = "/quick15")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save15(@RequestBody List<User> userList) throws IOException {
System.out.println(userList);
}
如果从前端控制器中找不到则从原始的tomcat中找静态资源
(**********)
<mvc:default-servlet-handler/>
request.setCharacterEncoding->
post请求乱码get方式tomcat8会处理
解决编码配置全局filter过滤器
在web.xml中配置
(**********)
<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>
参数绑定
@RequestMapping("/quick16")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
/*
* value与请求参数匹配名称与形参不一样也可以
* required默认true必须携带参数不然报错false可以不携带
* defaultValue没有指定参数是则使用默认值
* */
public void save16(@RequestParam(value = "name",required = false,defaultValue = "zhangsan") String username) throws IOException {
System.out.println(username);
}
解析url地址一部分的参数@PathVrlable占位符
//licalhost:8080/user/quick17/zhangsan
@RequestMapping(value = "/quick17/{username}")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
/*
*restful风格
* get获取,post新建put更新delete删除
* */
public void save17( @PathVariable(value = "username") String username) throws IOException {
System.out.println(username);
}
自定义类型转换器
1,定义转换器实现Converter接口
2,在配置文件中声明转换器
3,在<annotation-driven中引用转换器
public void save18(Date date) throws IOException {
System.out.println(date);
}
date=2014/12/21默认
经常用2022-12-12
//将String转换成Date
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String dataStr) {
SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = format.parse(dataStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
在spring-mvc.xml中加入
<mvc:annotation-driven conversion-service="conversionService"/>
<!--声明装换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.flatly.converter.DateConverter"></bean>
</list>
</property>
</bean>
springmvc获取请求数据
@RequestHeader
相当于request.getHeader(xx)
@RequestMapping(value = "/quick19")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save19(@RequestHeader(value = "User-Agent",required = false)String user_agent) throws IOException {
System.out.println(user_agent);
}
@CookieValue拿到CookieValue
//直接拿到CookieValue
@RequestMapping(value = "/quick20")
@ResponseBody //不进行页面跳转不进行数据回写响应体为空
public void save20(@CookieValue(value = "JSESSIONID")String jsessionId) throws IOException {
System.out.println(jsessionId);
}
用到的注解
@Controller
@RequestMapping
@ResponseBody
@RequestHeader
@RequestParam
@PathVariable
@CookieValue