实现基本的Controller并处理输入输出html
添加了Controller Annotation声明该类是Controller
也添加RequestMapping,经过value制定的/hello
的路径
咱们在函数处理以前也加了RequestMapping,经过value指定/spring
这样的结果是当碰到/hello/spring
就会把请求转接到Spring这个函数的处理
这个函数就输出信息。web
@Controller @RequestMapping(value = "/hello") public class HelloController { @RequestMapping(value = "/spring") public void spring(HttpSerlvetResponse response) throw IOException{ response.getWriter().write("Hello, Spring Web!!"); } }
在Spring配置文件中,经过context:component-scan来自动扫描,这样咱们在所扫描包下的经过Controller Annotation定义Controller都会被加载WebApplicationContext做为实例正则表达式
<!-- 自动扫描Controller,自动扫描目录下的子包,不可以直接填写对应controller,会自动扫描@componetns 等注释,并注册Bean--> <context:component-scan base-package="com.hava"/>
{userId}
表明是变量,当访问URL在users以后跟的参数,咱们都认为是userId的值。而后在函数的参数部分添加@PathVariable
,把userId的值做为这个函数的参数添加到这里。经过这种方式,只须要在这个方法上添加@RequestMapping
就能够很好的处理路径参数匹配问题。@RequestMapping(path = "/users/{userId}") public String webMethod(@PathVariable String userId){ // do work }
咱们能够在RequestMapping中使用正则表达式,不过对格式有限制。以下示例表示,只有字母的userId。spring
@RequestMapping(path = "/users/{userId:[a-z]+}") public String webMethod(@PathVariable String userId){ }
首先咱们经过RequestMapping经过匹配达到某些条件的请求进入函数,对于以下示例的函数,参数有HttpServletResponse
,自动的注入到response对象中。在实现里面,咱们经过response获取客户端的writer,把咱们想输出的信息输出到客户端。
须要注意的是,以下示例的函数返回值为void,为何咱们在这个函数内写response,response就能够拿到上下文信息,把咱们想要的信息输出到客户端当中。主要是由于Spring会对请求处理函数,作一些限制:能够注入哪些参数、有哪些种类的返回值。若是在请求参数里面设定参数,例如response参数,会在进入到这个函数的时候运行时会把相关的信息注入到函数当中。apache
@RequestMapping(value = "/spring") public void spring(HttpServletResponse response) throw Exception{ response.getWriter().write("Hello, Spring Web!!"); }
函数返回值是返回给用户的View的名称。json
下面的示例和咱们以前的示例相似,首先返回值是void。以后是函数参数:api
@RequestMapping(value = "/spring/{user}") public void spring( @PathVariable("user") String user, @RequestParam("msg") String msg, @RequestHeader("host") String host, HttpServletRequest request, Writer writer) throw IOException{ writer.write("URI: " + request.getRequestURI()); writer.write("Hello " + user + " : " + msg + " host=" + host); }
@RequestMapping(value = "/spring/login") public void login( @RequestParam("username") String username, @RequestParam("password") String password, Writer writer) throw IOException{ // do something with name and password }
@ModelAttribute
,经过@ModelAttribute
的Annotation来匹配称做Model的Java对象,直接从参数里面匹配Model,上面的示例,简化匹配一个参数就能够了。以下示例咱们定义了User的Model类。包含两个字段,name&password。而后就能够像以下示例,经过@ModelAttribute
注入user对象。会自动把user的name和password,经过表单注入到对象内。而后就能够经过对象,获取属性。@RequestMapping(value = "/spring/login") public void login( @ModelAttribute User user, Writer writer) throw IOException{ // do something with name and password }
CommonsMultipartResolver
,咱们通常把文件上传称做Multipart,当在Spring定义完CommonsMultipartResolver
就能够简单使用了。Spring的Multipart是经过Apache commons的第三方库实现的。因此,若是要添加CommonsMultipartResolver
,则须要在Maven中添加Apache Commons的依赖。<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="100000" /> </bean>
@RequestMapping(path="/form",method=RequestMethod.POST) public String handleFormUpload(@RequestParam("file") MultipartFile file){ //save file }
@RequestMapping("/someting") public ResponseEntity <String> handle(HttpEntity <byte[]> requestEntity){ String requestHeader = requstEntity.getHeaders().getFirst("MyRequestHeader"); byte [] requestBody = requestEntity.getBody(); // do something with request header and body HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set("MyResponseHeader","MyValue"); return new ResponseEntity<String>("Hello",responseHeaders,HttpStatus.CREATED); }
@RequestMapping(value = "/spring") @RequestBody public String spring(@RequestBody String body) throws IOException{ return "Hello " + body; }
@RequestMapping(value = "/spring/login") @RequestBody public User login(){ User user = new User(); return user; }
**注意:**Tomcat会报错误。描述的是所返回的内容,不符合指定的媒体类型。例如,咱们经过浏览器进行返回,或者经过http的测试工具,来执行accept header,若是经过浏览器访问接口的话,accept通常会指定成textHtml页面。返回的是纯文本的内容。若是是经过特定指定的话,能够指定返回JSON,或者是XML。若是没有通过设置,则默认的是textHtml。本示例的意思为,浏览器所请求的是textHtml,可是返回的是数据对象。 服务器
<mvc:annotation-driven />
该配置就会自动添加一些Converter,好比说JSON相关的Converter还有XML相关的Converter,返回的User对象,因为打开了Converter会根据默认的Converter进行转换。因为默认的JSON、XML处理须要引用外部包,则须要在Maven中添加mvc
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.6.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.6.4</version> </dependency>
@Controller public class HavaHelloController { @RequestMapping(value = "/response") public void response(HttpServletResponse response) throws IOException { System.out.println(response); response.getWriter().write("Hello,Spring Web!!"); } }
因为web.xml配置以下,访问的路径为/api/*
<servlet> <servlet-name>example</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping>
访问的URL:http://localhost:8080/api/response
后台输出
org.apache.catalina.connector.ResponseFacade@725005c5
@RequestMapping(value = "/write") public void write(Writer writer) throws IOException { System.out.println(writer); writer.write("Hello,Spring Web!!"); }
访问的URL:http://localhost:8080/api/write
后台输出
org.apache.catalina.connector.CoyoteWriter@2e6c953a
@RequestMapping(value = "/user/{userId}") public void user(@PathVariable("userId") String userId,Writer writer) throws IOException { writer.write("userId= " + userId); }
访问的URL路径:http://localhost:8080/api/user/123
前台结果
userId= 123
@RequestMapping(value = "/user-host/{userId}") public void user_host(@PathVariable("userId") String userId, @RequestParam("msg") String msg, @RequestHeader("host") String host, Writer writer) throws IOException { writer.write("userId= " + userId + ", msg=" + msg + ", hostHeader=" + host); }
访问的URL路径:http://localhost:8080/api/user-host/123?msg=test_message 前台结果
userId= 123, msg=test_message, hostHeader=localhost:8080
若是没有添加msg,则Spring会给前段报异常
URL:http://localhost:8080/api/user-host/123
HTTP Status 400 - Required String parameter 'msg' is not present type Status report message Required String parameter 'msg' is not present description The request sent by the client was syntactically incorrect.
@RequestMapping(value = "/user/login") @ResponseBody public String login(@RequestParam("username") String username, @RequestParam("password") String password, @RequestHeader("host") String host) throws IOException{ System.out.println("username:" + username); System.out.println("password:" + password); return "Username: " + username + "\n " + "Password: " + password + "\n Host:" + host; }
Html表单
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/api/user/login" method="post"> <p>Name: <input type="text" name="username" /></p> <p>Password: <input type="text" name="password" /></p> <input type="submit" value="Submit" /> </form> </body> </html>
注意:本例子中,html是没有web应用名称路径的,这个是因为编者使用的idea,直接运行的。而没有经过Maven进行运行。正常运行状态,还有Maven运行是带有web应用名称的,而idea须要单独设置Edit Configurations里面添加路径。
页面以及填入的信息
后台输出
username:123 password:456
Chrome查看的跳转结果,注意URL发生了变化跳转到了http://localhost:8080/api/user/login
而且显示以下结果
Username: 123 Password: 456 Host:localhost:8080
须要注意的是,咱们在输出的String添加\n
字符做为回车,可是在输出的页面当中,并无进行换行。这时咱们监控Chrome的Response能够看到以下内容
Username: test123 Password: test123 Host:localhost:8080
Html须要添加html的换行,才可以显示换行。若是添加<p></p>则发生了换行。
**注意:**若是函数返回类型为String,而且使用@ResponseBody做为函数的返回值,若是函数参数当中注入Writer writer,则会发生异常显现。在表单提交时,可以正确发送post请求,服务器也可以正确接收到参数内容。可是在输出时,会发生异常获取空白页面,经过Chrome的请求来看,仅仅可以看到response输出不完整错误信息。错误代号500
错误代码以下:
@RequestMapping(value = "/user/login") @ResponseBody public String login(@RequestParam("username") String username, @RequestParam("password") String password, @RequestHeader("host") String host, Writer writer) throws IOException{ System.out.println("username:" + username); System.out.println("password:" + password); return "Username: " + username + " " + "Password: " + password + " Host:" + host; }
Chrome的显示
不完整的显示输出