SpringMVC_3.x_入门指南_2

SpringMVC 3.x

该篇博文接着上一篇博文的架构继续从零基础实战springmvc

上一篇我们提到了在springmvc中如何请求user文件夹中的user.jsp,那种做法可以通过请求/user访问到user.jsp。

现在我们的新问题是这样的:
我有一个新的UserController,我想让这个Controller中的所有方法都以/user/**来请求

 

@Controller
public class UserController {

	@RequestMapping("/user/list")
	public String userList(){
		return "user/list";
	}

	@RequestMapping(value="/user/add",method=RequestMethod.GET)
	public String addForm(){
		return "user/add";
	}
}

这样可以实现,但是不是很方便,我们通过在类上加注解实现namespace

 

 

@Controller
@RequestMapping("/user")
public class UserController {

	@RequestMapping("/list")
	public String userList(){
		return "user/list";
	}
	
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public String addForm(){
		return "user/add";
	}
	
	@RequestMapping(value="/add",method=RequestMethod.POST)
	public String addUser(){
		return "user/list";
	}
	
}

如果把@RequestMapping后的括号去掉,直接访问/user即可访问仅带有@RequestMapping的方法

 

注意:一个类中只能存在一个没有配置的方法

 

@Controller
@RequestMapping("/user")
public class UserController {

	@RequestMapping
	public String userList(){
		return "user/list";
	}
	
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public String addForm(){
		return "user/add";
	}
	
	@RequestMapping(value="/add",method=RequestMethod.POST)
	public String addUser(){
		return "user/list";
	}
	
}

下面说一下URL传参的问题,也就是上一篇中提到的:

 

/user/1  获取ID=1的用户
这种方法的实现;

 

@RequestMapping(value="/{id}",method=RequestMethod.GET)
public String getUser(@PathVariable int id){
	System.out.println(id);
	return "user/list";
}

通过url传参,{id}表示传入的参数:/user/1,则id=1

 

在方法的参数列表中需要接收url传来的参数,如果{id}与定义的int id相同,则直接@PathVariable int id即可,如果不同的话,使用下面的方式:

 

@RequestMapping(value="/{abc}",method=RequestMethod.GET)
public String getUser(@PathVariable("abc") int id){
	System.out.println(id);
	return "user/list";
}

这是何必呢,所以我们大多数情况这个变量名是相同的!!!

 


启动服务器,输入:localhost/user/1
控制台会显示:1
如果要是输入:localhost/user/hh 呢?
肯定是错的呀!!

写道
HTTP ERROR 400

Problem accessing /user/hh. Reason:

Bad Request

不会在控制台报异常,只是页面请求出现400,我们不想这样!错误了也要给合适的提示,比如没找到就404错误呗!

我们使用正则来约束传入的参数:

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET)
public String getUser(@PathVariable int id){
	System.out.println(id);
	return "user/list";
}

再次输入:localhost/user/hh

 

写道
HTTP ERROR 404

Problem accessing /user/hh. Reason:

Not Found

 

现在又有一个问题:

我的用户有两类,一类是学生,一类是老师,学生的ID可能会和老师的ID相同,我如何通过上述一个方法实现对两类用户的访问呢?
我们可以在url添加一个参数type来实现对不同用户的访问!
重载getUser方法如下:

 

@RequestMapping(value="/{type}/{id:\\d+}",method=RequestMethod.GET)
public String getUser(@PathVariable int id,@PathVariable String type){
	System.out.println(type+"----"+id);
	return "user/list";
}

输入:localhost/user/student/11

 

显示:student---11

 

使用URL给服务器传值,我们先说这么多,下面我们说一下服务器怎么给页面传值

我们目前不连接数据库,只是熟悉SpringMVC的使用过程,我们创建一个User类

 

package com.cn.pojo;

public class User {

	private Integer id;
	private String name;
	private String password;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}

我们怎样把一个user对象传给页面呢?

 

第一种方式
使用SpringMVC的依赖注入Model接口(Springframework UI 提供的)

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET)
public String getUser(@PathVariable int id,Model model){
	System.out.println(id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	model.addAttribute("user", user);//将user装到user中
	
	return "user/list";
}

JSP中使用EL表达式接收:

 

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
 <html> 
   <head> 
     <title>list.jsp</title> 
   </head> 
   <body> 
      This is list page. <br> 
      <h1>${user.name }----${user.password }</h1> 
   </body> 
 </html>

第二种方式:

 

在方法上设置返回值类型为:ModelAndView,使用方法如下:

 

@RequestMapping(value="/{type}/{id:\\d+}",method=RequestMethod.GET)
public ModelAndView getUser(@PathVariable int id,@PathVariable String type){
	System.out.println(type+"----"+id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	ModelAndView mav=new ModelAndView("user/list");
	mav.addObject("user", user);
	return mav;
}

第三种方式:

 

让方法的返回类型直接是User,如下:

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET)
public User getUser(@PathVariable int id){
	System.out.println(id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	return user;
}

启动服务器请求:localhost/user/111  是什么效果呢?

 

写道
HTTP ERROR 404

Problem accessing /WEB-INF/views/user/111.jsp. Reason:

Not Found

服务器去找:111.jsp了,这明显是错误的嘛!


我们需要再添加注解,在User的前面添加@ResponseBody,或者在方法上面添加@ResponseBody注解,如下:

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET)
public @ResponseBody User getUser(@PathVariable int id){
	System.out.println(id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	return user;
}

 或者

 

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET)
@ResponseBody
public User getUser(@PathVariable int id){
	System.out.println(id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	return user;
}

  再次启动服务器访问,结果:

 

写道
HTTP ERROR 406

Problem accessing /user/111. Reason:

Not Acceptable

不是404了,而是406了!!!

不要灰心,我们马上就要胜利了,就差一步了!!!!
我们还需要在我们的pom.xml中添加一个依赖:jackson-mapper-asl(之前用来返回JSON使用过)

 

<!-- 用于对@ResponseBody注解的支持 -->
<dependency>
	<groupId>org.codehaus.jackson</groupId>
	<artifactId>jackson-mapper-asl</artifactId>
	<version>1.9.10</version>
</dependency>

 

 

再次重启,请求,你会看到很友好的JSON返回!!!你还可以在方法的注解中添加类似之前写的response.setContentType("application/json;charset=UTF-8")

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET,produces="application/json;charset=UTF-8")
@ResponseBody
public User getUser(@PathVariable int id){
	System.out.println(id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	return user;
}

注意:返回的是JSON,而不是跳转到某一个view。

 


有些公司的做法是不直接返回获得的对象,而是把返回的对象进行封装进一个叫Result的类中:

 

package com.cn.dto;

public class Result {

	private String error;
	private Object obj;
	
	public Result(){}
	public Result(String error, Object obj) {
		super();
		this.error = error;
		this.obj = obj;
	}
	public String getError() {
		return error;
	}
	public void setError(String error) {
		this.error = error;
	}
	public Object getObj() {
		return obj;
	}
	public void setObj(Object obj) {
		this.obj = obj;
	}
	
}

 

 

dto:Data Translation Object(数据传输对象)
怎么使用呢?把刚才的返回User的方法改造如下:

 

@RequestMapping(value="/{id:\\d+}",method=RequestMethod.GET,produces="application/json;charset=UTF-8")
@ResponseBody
public Result getUser(@PathVariable int id){
	System.out.println(id);
	
	User user=new User();
	user.setId(123);
	user.setName("tom");
	user.setPassword("000000");
	
	return new Result("0", user);
	
}

返回的JSON数据如下所示:

 

{"error":"0","obj":{"id":123,"name":"tom","password":"000000"}}

如果成功了,error=0,如果失败了,error=1呗,接收数据的时候,先判断error再决定后续该干啥!

我们上面详细学习了URL给服务器传值的RESTFUL方式(关于restful请查阅这篇博文http://www.ruanyifeng.com/blog/2011/09/restful.html),服务器给页面传值的三种方式,及跳转到VIEWS并显示值,但是如果我们仍然想使用之前用的很熟练的?传值怎么做呢?

我们举一个小小的例子你就明白了。仍然是注解。

 

@RequestMapping("/show")
@ResponseBody
public String showName(@RequestParam String name){
	return name;
}

请求:localhost/user/show?name=tom

 

返回的是字符串,@RequestParam表示参数来源与url中?后的name=***。
如果想改变名称:@RequestParam("xingming") String name;你喜欢哪一种方式,自己决定吧!
这样仍然存在一个问题,当你在方法中设置了参数的时候,而你在请求的时候不给它传name,这时是会报错的:

写道
HTTP ERROR 400

Problem accessing /user/show. Reason:

Required String parameter 'name' is not present

意思是:需要一个为name的参数,而你没有给俺传,给你来个400

怎么解决这个问题呢?
第一种解决方案:设置@RequestParam(required=false)

 

@RequestMapping("/show")
@ResponseBody
public String showName(@RequestParam(required=false) String name){
	return name;
}

第二中解决方案:设置@RequestParam(defaultValue="rose")默认值,如果没传,就给你显示rose

 

@RequestMapping("/show")
@ResponseBody
public String showName(@RequestParam(defaultValue="rose") String name){
	return name;
}

还有一个问题:

我们往往需要执行完一个方法后,跳转到另一个方法,例如:
我执行完添加用户后,我需要跳转到list中去获取最新的用户信息,该怎么办?
操作很简单,执行一下重定向即可!

@Controller
@RequestMapping("/user")
public class UserController {

	@RequestMapping
	public String userList(){
		System.out.println("user list...");
		return "user/list";
	}
	
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public String addForm(){
		return "user/add";
	}
	//为了请求的方便,我将请求的method改为GET了!
	@RequestMapping(value="/save",method=RequestMethod.GET)
	public String addUser(){
		return "redirect:/user";
	}
}

请求/user/save,则跳转到/user,即userList方法,下跳到user/list.jsp


最后一个问题:
如果我想使用原来的Request,Response,Application空间,该怎么办呢?
关于这些空间,你需要用的时候,直接拿来用就行了,就跟Model是一样样的!!!

@RequestMapping("/show")
@ResponseBody
public String showName(@RequestParam(defaultValue="rose") String name,HttpSession session,HttpServletRequest request,HttpServletResponse response,ServletContext application){
	return name;
}

这些Servlet的API,对象都是依赖注入的,你需要就拿出来用,不需要就算了,太方便了!!!!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值