@Controller 和 @RestController的區別
@Controller: 處理http請求
@RestController: Spring4之後新加的註解,原來返回json需要@ResponseBody
和@Controller的配合
- 如果只是使用@RestController註解Controller,則Controller中的方法無法返回jsp頁面,或者html,配置的視圖解析器 InternalResourceViewResolver不起作用,返回的內容就是Return 裏的內容。
- 如果需要返回到指定頁面,則需要用 @Controller配合視圖解析器InternalResourceViewResolver才行。
如果需要返回JSON,XML或自定義mediaType內容到頁面,則需要在對應的方法上加上@ResponseBody註解。
@PathVariable,@RequestParam,@GetMapping,@RequestBody
@PathVariable: 獲取url中的參數
@GetMapping: 組合註解
@RequestParam:
用來處理Content-Type: 爲 application/x-www-form-urlencoded編碼的內容。(Http協議中,如果不指定Content-Type,則默認傳遞的參數就是application/x-www-form-urlencoded類型)
RequestParam可以接受簡單類型的屬性,也可以接受對象類型。
實質是將Request.getParameter() 中的Key-Value參數Map利用Spring的轉化機制ConversionService配置,轉化成參數接收對象或字段。
在Content-Type: application/x-www-form-urlencoded的請求中,
get 方式中queryString的值,和post方式中 body data的值都會被Servlet接受到並轉化到Request.getParameter()參數集中,所以@RequestParam可以獲取的到。
@RequestBody
處理HttpEntity傳遞過來的數據,一般用來處理非Content-Type: application/x-www-form-urlencoded編碼格式的數據。
GET請求中,因爲沒有HttpEntity,所以@RequestBody並不適用。
POST請求中,通過HttpEntity傳遞的參數,必須要在請求頭中聲明數據的類型Content-Type,SpringMVC通過使用HandlerAdapter 配置的HttpMessageConverters來解析HttpEntity中的數據,然後綁定到相應的bean上。
@RequestMapping(value="/get/id/{id}", method = RequestMethod.GET)
public String getId(@PathVariable("id")Integer id){
System.out.println("test");
return "id:" + id ;
}
maven更改資源目錄
不同工具對資源目錄的識別位置不同,可以利用maven來指定資源目錄
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--配置spring的資源目錄,否則maven不識別-->
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
@Value 和 靜態變量
spring不支持通過@Value的方式注入靜態變量中,但是可以通過set方法來注入到靜態變量中
private static String xx;
@Value("${test}")
public void setXx(String test){
xx = test;
}
set方法也必須爲非靜態方法,且賦值過程在靜態塊初始化過程之後.
InitializingBean,DisposableBean
Spirng的InitializingBean爲bean提供了定義初始化方法的方式
InitializingBean是一個接口,它僅僅包含一個方法:afterPropertiesSet()
實現org.springframework.beans.factory.InitializingBean接口允許一個bean在它的所有必須屬性被BeanFactory設置後,來執行初始化的工作,InitialzingBean僅僅指定了一個方法。
實現org.springframework.beans.factory.DisposableBean接口的bean允許在容器銷燬該bean的時候獲得一次回調。DisposableBean接口也只規定了一個方法:
void destroy() throws Exception;
Component
@ComponentScan
public class MqConsumer implements InitializingBean, DisposableBean {
private static final Logger logger = LogManager.getLogger(MQController.class.getName());
@Autowired
private AliMQConfig aliMQConfig;
private Consumer busConsumer;
@Autowired
private MqMessageMapper mqMessageMapper;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("消費者初始化");
busConsumer = ONSFactory.createConsumer(aliMQConfig.getConsumer());
System.out.println("消費者初始化完成");
}
public void start(){
busConsumer.start();
}
public void onMessage(){
busConsumer.subscribe(aliMQConfig.getTopic(), "*", new MessageListener() {
@Override
public Action consume(Message message, ConsumeContext context) {
String msg = "";
try {
//do something..
msg = new String(message.getBody(), "UTF-8");
MqMessage mqMessage = new MqMessage();
mqMessage.setMessage(msg);
mqMessageMapper.insert(mqMessage);
WebSocketServer.sendInfo(msg, "20");
logger.info("訂閱消息:" + msg);
return Action.CommitMessage;
} catch (Exception e) {
//消費失敗
e.printStackTrace();
logger.info("消費失敗:" + msg);
return Action.ReconsumeLater;
}
}
});
}
@Override
public void destroy() throws Exception {
busConsumer.shutdown();
System.out.println("停止");
}
}