日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring MVC 实践 - Component

發(fā)布時(shí)間:2025/3/17 javascript 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC 实践 - Component 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Spring MVC 實(shí)踐

標(biāo)簽 : Java與Web


Converter

Spring MVC的數(shù)據(jù)綁定并非沒(méi)有任何限制, 有案例表明: Spring在如何正確綁定數(shù)據(jù)方面是雜亂無(wú)章的. 比如: Spring總是試圖用默認(rèn)的語(yǔ)言區(qū)域?qū)⑷掌谳斎虢壎ǖ絡(luò)ava.util.Data, 如果想要使用不同的日期格式(format),就需要Converter的協(xié)助.

Spring提供了Converter接口來(lái)供開(kāi)發(fā)者自定義Converter類:

/*** @since 3.0* @param <S> the source type* @param <T> the target type*/ public interface Converter<S, T> {T convert(S source); }
  • 自定義Converter:
/*** @author jifang.* @since 2016/6/19 7:23.*/ public class StringDateConverter implements Converter<String, Date> {private String pattern;public StringDateConverter(String pattern) {this.pattern = pattern;}@Overridepublic Date convert(String source) {try {return new SimpleDateFormat(pattern).parse(source);} catch (ParseException e) {throw new RuntimeException(e);}} }
  • 配置
    為了能夠讓Spring MVC使用我們自定義的Converter, 需要在配置文件中配置一個(gè)ConversionServiceFactoryBean:
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><set><bean class="com.fq.mvc.converter.StringDateConverter"><constructor-arg type="java.lang.String" value="yyyy-MM-dd hh:mm:ss"/></bean></set></property> </bean>

然后為<annotation-driven/>配置conversion-service屬性:

<mvc:annotation-driven conversion-service="conversionService"/>

注: 還可以使用FormattingConversionServiceFactoryBean來(lái)加載Converter, 由于其配置方法與ConversionServiceFactoryBean, 故在此就不再贅述.

  • Controller
@RequestMapping("/add_user.do") public String addUser(User user, BindingResult binding) {if (binding.hasErrors()) {FieldError error = binding.getFieldError();// log ...}service.addUser(user);return "redirect: users.do"; }

BindingResult參數(shù)中放置了Spring的所有綁定錯(cuò)誤.


Interceptor

Spring MVC的攔截器類似于Servlet中的Filter(關(guān)于Filter,詳細(xì)可參考Servlet - Listener、Filter、Decorator),用于Controller進(jìn)行預(yù)處理和后處理.

Spring提供了Interceptor接口來(lái)供開(kāi)發(fā)者自定義Interceptor類:

public interface HandlerInterceptor {/*** 進(jìn)入Controller方法前執(zhí)行* 應(yīng)用場(chǎng)景: 身份認(rèn)證、身份授權(quán)等*/boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception;/*** 進(jìn)入Controller方法后, 返回ModelAndView前執(zhí)行* 應(yīng)用場(chǎng)景: 將公共模型數(shù)據(jù)填充到ModelAndView、統(tǒng)一指定視圖等*/void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;/*** 執(zhí)行完Controller方法后執(zhí)行* 應(yīng)用場(chǎng)景: 統(tǒng)一日志處理、統(tǒng)一異常處理等*/void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;}
示例: 統(tǒng)計(jì)Controller執(zhí)行耗時(shí).
  • 自定義Interceptor
/*** @author jifang* @since 16/7/4 上午10:35.*/ public class HandleTimeInterceptor implements HandlerInterceptor {private static final String START_TIME = "start_time";private static final String HANDLE_TIME = "handle_time";private static final Logger LOGGER = LoggerFactory.getLogger(HandleTimeInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {request.setAttribute(START_TIME, System.currentTimeMillis());return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {long start = (long) request.getAttribute(START_TIME);request.setAttribute(HANDLE_TIME, System.currentTimeMillis() - start);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {String uri = request.getRequestURI();long consume = (long) request.getAttribute(HANDLE_TIME);LOGGER.info("uri: {} consume {}s", uri, consume / 1000);} }
  • 配置
<mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.fq.mvc.interceptor.HandleTimeInterceptor"/></mvc:interceptor> </mvc:interceptors>

Upload

Spring MVC提供了對(duì)Servlet 3.0文件上傳的支持(關(guān)于Servlet 3.0文件上傳可參考博客Servlet - Upload、Download、Async、動(dòng)態(tài)注冊(cè)).

Spring MVC提供了MultipartFile接口,上傳到應(yīng)用中的文件都被包裝在一個(gè)MultipartFile對(duì)象中:

MultipartFile描述
String getName()Return the name of the parameter in the multipart form.
String getOriginalFilename()Return the original filename in the client’s filesystem.
long getSize()Return the size of the file in bytes.
boolean isEmpty()Return whether the uploaded file is empty, that is, either no file has been chosen in the multipart form or the chosen file has no content.
String getContentType()Return the content type of the file.
byte[] getBytes()Return the contents of the file as an array of bytes.
InputStream getInputStream()Return an InputStream to read the contents of the file from.
void transferTo(File dest)Transfer the received file to the given destination file.

在Servlet 3.0及更高版本的容器中進(jìn)行文件上傳編程,總是圍繞著@MultipartConfig注解和Part接口,處理上傳文件的Servlet必須以@MultipartConfig注解標(biāo)注, 但DispatcherServlet是Spring jar包已經(jīng)編譯好的類, 無(wú)法進(jìn)行修改,值得慶幸的是Servlet 3.0還可以使用部署描述符web.xml將一個(gè)Servlet變?yōu)?strong>MultipartConfig Servlet:

<servlet><servlet-name>mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/mvc-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup><multipart-config><max-file-size>20848820</max-file-size><file-size-threshold>1048576</file-size-threshold></multipart-config> </servlet> <servlet-mapping><servlet-name>mvc</servlet-name><url-pattern>*.do</url-pattern> </servlet-mapping>

此外, 在mvc-servlet.xml文件中配置一個(gè)MultipartResolver:

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>

此時(shí)就可以進(jìn)行文件上傳編程了:

@RequestMapping("/upload.do") public String upload(MultipartFile file) throws IOException {String name = file.getOriginalFilename();String fileName = String.format("/data/file/%s", name);file.transferTo(new File(fileName));return "file_upload"; }

Exception

系統(tǒng)異常包含兩類: 預(yù)期異常、運(yùn)行時(shí)異常RuntimeException.前者通過(guò)捕獲異常從而獲取異常信息,后者主要通過(guò)規(guī)范代碼開(kāi)發(fā)、測(cè)試等手段減少運(yùn)行時(shí)異常的發(fā)生.

基于Spring MVC的DAO、Service、Controller的異常都可以通過(guò)throw向上層拋出,最后統(tǒng)一由DispatcherServlet的異常處理器進(jìn)行處理.

  • 自定義異常
    如果Controller/Service/DAO拋出此類異常說(shuō)明是預(yù)期異常:
/*** @author jifang.* @since 2016/6/21 16:28.*/ public class MVCException extends Exception {private String message;public MVCException(String message) {super(message);this.message = message;}@Overridepublic String getMessage() {return this.message;}public void setMessage(String message) {this.message = message;} }
  • 異常處理器
/*** @author jifang.* @since 2016/6/21 16:33.*/ public class MVCExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {String message;if (ex instanceof MVCException) {message = ex.getMessage();} else {message = "未知異常";}return new ModelAndView("error", "message", message);} }
  • error.vm
<html> <head><title>錯(cuò)誤信息</title><meta http-equiv="content-type" content="text/html; charset=UTF-8"/> </head> <body> ${message} </body> </html>
  • 注冊(cè)異常處理器
<bean class="com.fq.mvc.exception.MVCExceptionResolver"/>

JSON

JSON數(shù)據(jù)格式形式簡(jiǎn)單, 解析方便, 因此常用在接口調(diào)用、HTML頁(yè)面中.

Spring MVC對(duì)其提供了如下支持:在Controller方法上添加@ResponseBody注解, Spring MVC會(huì)自動(dòng)將Java對(duì)象轉(zhuǎn)換成JSON字符串輸出; 在方法形參上添加@RequestBody注解, Spring MVC會(huì)自動(dòng)將JSON串轉(zhuǎn)換成Java對(duì)象:

@ResponseBody @RequestMapping("/user_json.do") public User userJSON(@RequestBody User user) {return user; }
  • fastjson
    Spring MVC默認(rèn)使用jackson對(duì)request/response進(jìn)行JSON轉(zhuǎn)換,而在此我們選用性能更高的fastjson, 因此需要在<annotation-driven/>中另做配置.

首先, 使用fastjson需要在pom.xml中添加如下依賴:

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.7</version> </dependency>

然后在mvc-servlet.xml中做如下配置:

<mvc:annotation-driven><mvc:message-converters register-defaults="false"><bean id="fastJsonHttpMessageConverter"class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json;charset=UTF-8</value></list></property><property name="features"><array value-type="com.alibaba.fastjson.serializer.SerializerFeature"><value>DisableCircularReferenceDetect</value></array></property></bean></mvc:message-converters> </mvc:annotation-driven>

Other

1. POST Encoder

在web.xml配置一個(gè)編碼Filter可以解決POST亂碼問(wèn)題:

<filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param> </filter> <filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>

2. GET Encoder

對(duì)于GET亂碼, 由于Tomcat 8.0之前版本默認(rèn)使用ISO-8859-1編碼, 因此有兩種解決方案:

  • 修改tomcat配置文件
    修改tomcat配置文件server.xml設(shè)置編碼與工程編碼一致:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
  • 重新編碼
    將經(jīng)Tomcat編碼的內(nèi)容解碼后再重新編碼為UTF-8:
String name = new String(request.getParamter("name").getBytes("ISO8859-1"),"utf-8");

注: Tomcat 8.0及更高版本的容器不用此配置.


3. Static Resources Mapping

如果將DispatherServlet配置成攔截所有請(qǐng)求<url-pattern>/</url-pattern>, 則必須額外配置靜態(tài)資源的映射規(guī)則, 否則Spring MVC會(huì)對(duì)像js/css之類的文件也做轉(zhuǎn)發(fā).
Spring MVC使用<mvc:resources/>元素配置對(duì)靜態(tài)資源的映射:

<mvc:resources location="/js/" mapping="/js/**"/>

總結(jié)

以上是生活随笔為你收集整理的Spring MVC 实践 - Component的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。