pom.xml文件
一、简单控制器
创建一个index.jsp文件在src/main/resources/views下。
/**
* springmvc配置
* @author think
*/
@Configuration
@EnableWebMvc
@ComponentScan("com")
public class MyMvcConfig {
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/classes/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
}
/**
* web配置
* @author think
*/
public class WebInitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MyMvcConfig.class);
context.setServletContext(servletContext);//与配置类关联
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));//注册springmvc的DispatcherServlet
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}
/**
* 简单的一个控制器
* @author think
*/
@Controller
public class ControllerTest {
@RequestMapping("/index")//配制方法与url的映射
public String hello(){
return "index";
}
}
WebApplicationInitializer是spring提供用来配置servlet3.0的接口,从而替代web.xml,
此接口会自动SpringServletContainerInitializer(用来启动serlvet3.0容器)获取到。
二、springmvc常用注解
1、@Controller声明是一个控制器,dispatcherservlet会自动扫描此注解的类,并将web讲求映射到有@RequestMapping的方法上。
2、在声明普通bean时,使用@Component、@Service、@Repository、@Controller是等同的,但是在作为springmvc的控制器bean时,只能使用@Controller。
3、@RequestMapping用来映射web请求、处理类和方法的,支持servlet的request和response作为参数,也支持对request和response的媒体类型进行配置。
4、@ResponseBody支持将返回值放在response体内,而不是返回一个页面,在很多基于ajax的程序时,可以用此注解返回数据,而不是页面。
5、@RequestBody允许参数再request体内,而不是在地址后面
6、@PathVariable用来接收路径参数,如/news/001,可以接收001作文参数
7、@RestController是组合注解,组合了@Controller和@ResponseBody
简单使用:
/**
* 实体类
* @author think
*/
public class Obj {
private Long id;
private String name;
public Obj() {//对象转换json时候需要此空参构造
super();
}
public Obj(Long id, String name) {
super();
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Obj [id=" + id + ", name=" + name + "]";
}
}
/**
* 参数转化
* @author think
*/
@Controller
@RequestMapping("/obj")//映射此类的访问路径是/obj
public class ObjController {
@RequestMapping(produces = "text/plain;charset=UTF-8")//使用此类的访问路径,produces设置返回的response的媒体类型和字符集
public @ResponseBody String normal(HttpServletRequest request){
return "url:" + request.getRequestURL();
}
@RequestMapping(value = "/{pathVar}", produces = "text/plain;charset=UTF-8")//value接收的路径参数,结合@PathVariable获取访问路径参数
public @ResponseBody String pathVar(@PathVariable String pathVar, HttpServletRequest request){
return "url:" + request.getRequestURL() + ",路径参数:" + pathVar;
}
@RequestMapping(value = "/requestParam", produces = "text/plain;charset=UTF-8")//常规的request作为参数,获取路径后面拼接的id=xx
public @ResponseBody String requestParam(Long id, HttpServletRequest request){
return "url:" + request.getRequestURL() + ",id:" + id;
}
@RequestMapping(value = "/turn2Obj", produces = "application/json;charset=UTF-8")//对象自动转换json,返回的媒体对象为json
@ResponseBody//可以用在方法上也可以用在方法中
public Obj turn2Obj(Obj obj, HttpServletRequest request){
return new Obj(obj.getId(), obj.getName());
}
@RequestMapping(value = {"/name1", "/name2"}, produces = "text/plain;charset=UTF-8")//不同路径映射到相同的方法
public @ResponseBody String multiPath(HttpServletRequest request){
return "url:" + request.getRequestURL();
}
}
三、静态资源映射和拦截器
SpringMVC的定制配置需要我们的配置类继承一个WebMvcConfigurerAdapter类,并在此类使用@EnableWebMvc注解来开启对SpringMVC的配置支持,这个累里面有许多好用的方法,这样我们可以重写这个类的方法来完成我们的常用配置。
创建一个静态文件demo.txt在src/main/resource/assets下。
/**
* 自定义拦截器
* @author think
*/
public class Interceptor extends HandlerInterceptorAdapter{
//请求发生前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}
//请求发生后执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
Long startTime = (Long) request.getAttribute("startTime");
request.removeAttribute("startTime");
Long endTime = System.currentTimeMillis();
System.out.println("执行时间:" + (endTime - startTime));
request.setAttribute("handlingTime", endTime - startTime);
}
}
/**
* 配置
* @author think
*/
@Configuration
@EnableWebMvc//开启springmvc支持,没有此句,重写WebMvcConfigurerAdapter无效
@ComponentScan("com")
public class MyMvcConfig extends WebMvcConfigurerAdapter{
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/classes/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
@Bean//配置拦截器的bean
public Interceptor getInterceptor(){
return new Interceptor();
}
@Override//静态资源映射
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//addResourceHandler对外暴露的访问路径,addResourceLocations文件放置的目录
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
super.addResourceHandlers(registry);
}
@Override//注册拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getInterceptor());
super.addInterceptors(registry);
}
}
这样就可以访问项目目录下的静态文件资源,同时可以对请求进行拦截。
四、@ControllerAdvice
@ControllerAdvice作为一个全局配置的控制器,其组合了@Component,自动注册为spring的bean,所有配置信息都写在本类里面,注解了@Controller类的方法可以使用@ExceptionHandler,@ModelAttribute,@InitBinder,对所有注解了@RequestMapping的控制器都有效。
创建一个处理异常的页面error.jsp文件在src/main/resources/views下。
/**
* 全局配置
* @author think
*/
@ControllerAdvice
public class ExceptionHandlerAdvice {
@ExceptionHandler(value = Exception.class)//全局异常配置
public ModelAndView exception(Exception exception, WebRequest request){
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("errorMessage", exception.getMessage());
return modelAndView;
}
@ModelAttribute//自动绑定键值对到model中,所有@RequestMapping的能获得此处的值
public void addAttributes(Model model){
model.addAttribute("msg", "额外信息");
}
@InitBinder//自动绑定前端的请求参数到model中
public void initBinder(WebDataBinder binder){
binder.setDisallowedFields("id");//将request参数封装为对象的时候忽略id这个属性,正常获取id参数还是可以获取到的。
}
}
@Controller
public class AdviceController {
@RequestMapping("advice")
public String getGlobal(@ModelAttribute("msg") String msg, Obj obj, String id){
throw new IllegalArgumentException("异常,msg:" + msg + ",obj:" + obj + ",id:" + id);
}
}
发送 “springmvc4/advice?id=55&name=名字” 请求后,在error.jsp中用${errorMessage }就可以获取到:
五、其他配置
1、快捷返回页面ViewController
//简单的返回页面
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index").setViewName("/index");
super.addViewControllers(registry);
}
用上面的代码可以替代掉下面的代码,从而达到一个简化的目的,前提是这只是一个简单的页面转向,不涉及到任何的逻辑。
@Controller
public class ControllerTest {
@RequestMapping("/index")
public String hello(){
return "index";
}
}
2、路径匹配参数配置
在SpringMVC中,请求路径如果带有“.”的话,后面的值将会被忽略,例如访问“/springmvc4/obj/pathvar.33”时,是无法获取“obj/”后面的完整参数。通过重写configurePathMatch将设置为不忽略“.”后面的参数:
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
super.configurePathMatch(configurer);
}