springMVC入门

文章目录

  • helloword示例
  • @RequestMapping注解
  • @PathVariable
  • HiddenHttpMethodFilter
    • 示例
    • 总结步骤
  • @RequestParam
  • RequestHeader
  • @CookieValue
  • POJO自动匹配赋值
    • 示例
  • 将servlet API作为方法入参传入
  • 处理模型数据输出
    • 使用ModelAndView对象
    • map
    • @sessionAttributes
    • @ModelAttribute
  • 直接转发页面
  • 配置自定义解析视图
  • 重定向与转发
  • 中间跳过一些格式化内容
  • springmvc的流程

helloword示例

  1. 在web.xml中配置DispatchServlet
    
        dispatcherServlet
        
            org.springframework.web.servlet.DispatcherServlet
        
        
            contextConfigLocation
            classpath:spring-mvc.xml
        
        1
    
    
        dispatcherServlet
        /
    
  1. 在spring-mvc.xml中配置注解扫描跟视图解析器
	
	
	
	
	
		
		
	
  1. 编写控制器,使用Controller注解
@Controller
public class HelloWorld {

	@RequestMapping("/helloWorld")
	public String hello() {
		System.out.println("hello world");
		return "success";
	}
}
  1. 然后三步即简单实现hello world,首先页面上请求helloWorld,这时候会请求http://127.0.0.1:8080/springmvc-01/helloWorld,这个地址被web.xml中的DispatcherServlet拦截然后根据spring-mvc.xml中的扫描配置去寻找到有对应mapping的controller,这时候找到helloworld中的hello方法(注意:请求的mapping是springmvc-01/helloWorld,但是hello方法只需要写helloWorld即可,为什么这样需要参考源码),执行完成之后返回success然后加上前后缀找到相应的物理页面;

@RequestMapping注解

  1. 该注解作用于类名:提供初步的请求映射信息,对于web应用根目录;
  2. 该注解作用于方法:提供进一步细分映射信息
  3. 该标签中属性:
    1. value:跟注解括号中直接加字符串相同作用,表示请求的路径
    2. method:表示请求的方式,get,post等;
    3. params:数组,类似params = {"username","age!=10"}表示必须包含username跟age参数并且age不等于10,规则是
      1. param1:表示请求的参数必须包含param1
      2. !param1:表示请求的参数必须不包含param1
      3. param1!= value:表示请求的参数不等于value
      4. {“param1=value1”,“param2”}:表示请求的参数必须包含param1跟param2并且param1必须为value1
    4. headers跟第三点中params类似;
    5. ant风格地址匹配:
      1. ?:表示文件名中一个字符
      2. *:表示匹配文件名中多个任意字符
      3. **:表示匹配多层路径

@PathVariable

  1. name:绑定的变量名称
  2. value:变量名称的别名
  3. required:是否必须

示例:下面表示使用PathVariable注解中name属性绑定路径中{id},并将其作为值传入方法hello的参数id中;

@RequestMapping(value = "/helloWorld/{id}")
	public String hello(@PathVariable(name="id")  String id) {
		System.out.println("hello world:"+id);
		return "success";
	}

HiddenHttpMethodFilter

  1. 作用:将post请求转成delete请求 或者put请求
  2. REST:即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构;
  3. 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符;
  4. 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式
  5. 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源

示例

web.xml中过滤器配置
/*跟/的区别
https://www.cnblogs.com/xiehang/p/9472620.html
/*
这种形式将会覆盖所有其它的servlet。不管你发出了什么样的请求,最终都会在这个servlet中结束。因此,对于servlet来说,这是一个很糟糕的URL模式。通常来讲,你只会想要在一个Filter中使用这种模式。它可以通过调用doFilter()方法来使请求继续。
/
这种形式不会覆盖任何其它的servlet。它仅仅替换了servlet容器中内建的默认servlet。这种形式通常只用来请求静态资源(CSS/JS/image等)和展示目录的列表。servlet容器内建的默认servlet同样可以处理HTTP cache请求、媒体(声音/视频)流以及文件的下载。通常来说,你不会想要覆盖这个默认的servlet,否则,你将不得不自己处理一些琐碎的任务。因此,对于sevlet来说,这同样是一个糟糕的URL模式。说到为什么JSP页面的请求并不会命中这个servlet,那是因为servlet容器内建的JSP servlet将会被调用,而这个容器内建的JSP servlet已经默认地映射在了*.jsp上。

这种空串的形式。当上下文的根被请求的时候,它将被调用。这与的方式是不同的,因为这种形式在当任何子目录被请求的时候不会被调用。当你期望一个“首页servlet”的时候,这种URL模式就是适合你的。

    
   	
   		HiddenHttpMethodFilter
   		org.springframework.web.filter.HiddenHttpMethodFilter
   	
   	
   		HiddenHttpMethodFilter
   		/*
   	

controller代码

@Controller
public class HelloWorld {

	@RequestMapping(value = "/helloWorld",method=RequestMethod.POST)
	public String testPost() {
		System.out.println("test post");
		return "success";
	}
	
	@RequestMapping(value = "/helloWorld/{id}",method=RequestMethod.GET)
	public String testGet(@PathVariable(name="id")  String s) {
		System.out.println("test get:"+s);
		return "success";
	}
	
	@RequestMapping(value = "/helloWorld/{id}",method=RequestMethod.PUT)
	public String testPut(@PathVariable(name="id")  String s) {
		System.out.println("test put:"+s);
		return "success";
	}
	
	@RequestMapping(value = "/helloWorld/{id}",method=RequestMethod.DELETE)
	public String testDelete(@PathVariable(name="id")  String s) {
		System.out.println("test delete:"+s);
		return "success";
	}
	
}

请求jsp中form表单

总结步骤

  1. 配置HidderHttpMethodFilter
  2. 发送post请求
  3. 发送post请求携带一个name="_method"的隐藏域,值为DELETE或者PUT

@RequestParam

  1. 直接在方法的参数前面使用可以将表单上送的属性值注入进来;
  2. 其中属性:
    1. name跟value都是跟前台上送的属性名绑定
    2. required:参数是否必输
    3. defaultValue:默认值
@Controller
public class TestParam {

	private static final String SUCCESS = "success";
	
	@RequestMapping(value="/testParam")
	public String testParam(@RequestParam(value = "uname") String uname,
			@RequestParam(value = "uage") String uage) {
		System.out.println("uname:"+uname);
		System.out.println("uage:"+uage);
		return SUCCESS;
	}
}

RequestHeader

  1. 跟RequestParam使用方法一样

@CookieValue

  1. 跟requestParam一样

POJO自动匹配赋值

  1. springmvc会自动根据参数跟POJO的属性名进行自动匹配,自动为该属性填充值,支持级联属性

示例

控制器代码,页面表单传入uname跟uage会自动注入到user参数中;

	@RequestMapping(value="/testParam")
	public String testParam(User u) {
		System.out.println("uname:"+u);
		return SUCCESS;
	}

表单属性

用户名:
年龄

用户实体类

public class User {

	private String uname;
	
	private String uage;

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public String getUage() {
		return uage;
	}

	public void setUage(String uage) {
		this.uage = uage;
	}

	@Override
	public String toString() {
		return "User [uname=" + uname + ", uage=" + uage + "]";
	}
}

将servlet API作为方法入参传入

  1. servlet API有如下等等:
    1. HttpServletRequest
    2. HttpServletResponse
    3. HttpSession
    4. java.security.Principal
    5. Locale
    6. InputStream
    7. OutputStream
    8. Reader
    9. Writer

处理模型数据输出

使用ModelAndView对象

设置view为页面,model是数据
设置model

MoelAndView addObject(String attributeName, Object attributeValue)
ModelAndView addAllObject(Map modelMap)

设置视图

void setView(View view)
void setViewName(String viewName)j

控制器

	@RequestMapping(value="/testModelAndView")
	public ModelAndView testModelAndView(User u) {
		System.out.println("uname:"+u);
		ModelAndView modelAndView = new ModelAndView(SUCCESS);
		modelAndView.addObject("user", u);
		
		
		return modelAndView;
	}

请求表单

用户名:
年龄

应答页面

跳转成功

uname: ${requestScope.user.uname} uage: ${requestScope.user.uage}

map

  1. 在方法的参数中增加map,那么往map中放的值会存到request的属性中;
    这样页面即可以从请求域中拿到值users值
	@RequestMapping(value="/testModelAndView")
	public String testModelAndView(Map map) {
		map.put("users", Arrays.asList("1","2","3"));
		return SUCCESS;
	}

@sessionAttributes

  1. 在控制器上增加该注解可以将请求中的参数绑定到session中
  2. name跟value属性都是指定属性名,type属性是用来指定类型,例如如果是types = {String.class},那么只要是String类型的属性都会放到session中;
    这里就是讲map中增加的users对象增加到了session中,页面可以使用${sessionScope.users}获取
@SessionAttributes("users")
@Controller
public class TestParam {

	private static final String SUCCESS = "success";
	
	@RequestMapping(value="/testModelAndView")
	public String testModelAndView(Map map) {
		map.put("users", Arrays.asList("1","2","3"));
		return SUCCESS;
	}
}

@ModelAttribute

  1. 在每个目标方法执行之前都会调用被ModelAttrbute注解标记的方法;
  2. 执行步骤
    1. 首先在执行testModelAttribute方法前获取User(模拟从数据库中获取User信息)并放到map中;
    2. 然后再从map中取出User信息,然后赋值表单的值
    3. 然后再将user传入testModelAttribute方法参数中
    4. 注意:在ModelAttribute修饰的方法中,放到map中的键需要跟目标方法入参类型第一个字母小写的名称一致
    5. 或者是在目标方法参数前使用@modelAttribute跟参数绑定新名称
    6. 如果找不到则会通过反射新建对象传入
@Controller
public class TestParam {

	private static final String SUCCESS = "success";
	
	@ModelAttribute
	public void getUser(@RequestParam(value = "id",required = false) Integer id,Map map) {
		if(id != null) {
			User user = new User();
			
			user.setUage("15");
			user.setUname("z3");
			
			System.out.println("获取一个user:"+user);
			map.put("user", user);
		}
	}
	
	@RequestMapping(value="/testModelAttribute")
	public String testModelAttribute(User user) {
		System.out.println(user);
		return SUCCESS;
	}
}

直接转发页面

  1. 在配置文件中直接配置mvc:view-controller可以让请求直接根据配置的路径转发到响应的view中而不经过控制器,但是同时也必须配置mvc:annotation-driven标签
	
	
	

配置自定义解析视图

  1. 自定义视图实现view接口,并声明为component
@Component
public class HelloView implements View {

	@Override
	public void render(Map model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		response.getWriter().print("hello view  time:"+new Date());
		
	}
	
	@Override
	public String getContentType() {
		// TODO Auto-generated method stub
		return "text/html";
	}

}
  1. 配置文件配置BeanNameViewResolver,表示根据bean的名称解析,使用order表示与之前的InternalResourceViewResolver先执行,InternalResourceViewResolver的order为int的最大值,值越大优先级越低;
	
		
	
  1. 控制器:当请求testHelloView时会打印view并返回helloView字符串,BeanNameViewResolver会根据该字符串去找响应的视图,由于HelloView被component注解修饰,因此可以通过类名第一个字母小写找到;
	@RequestMapping("/testHelloView")
	public String testHelloView() {
		
		System.out.println("test view");
		
		return "helloView";
	}

重定向与转发

  1. 在目标方法返回值得字符串前加上redirect:或者forward:即可从定向或者转发到某个页面;

中间跳过一些格式化内容

springmvc的流程

springMVC入门_第1张图片

  1. 页面发起请求
  2. 请求被DispatcherServlet匹配,如果找不到相应的匹配,则判断是否配置,配置了则寻找目标资源,没配置则控制台输出找不到映射,页面返回404
  3. 如果匹配到了具体的映射,则获取HandlerAdapter对象调用preHandler然后值目标方法,然后postHandler方法,然后如果存在异常则使用handlerExceptionResolver处理,否则直接有viewResolver处理,然后渲染视图调用拦截器的afterCompetion方法;

你可能感兴趣的:(springmvc,java,springmvc)