實現基本的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的顯示
不完整的顯示輸出