虽然在Spring MVC后,Servlet中的request、response、session对象使用频率大大降低,但有时还是会用到,例如设置session属性、response设置Cookie、返回二进制数据等。
当需要这些对象时,一般的做法有2种。
1、参数中注入
@RequestMapping
public void login(HttpSession session) {
session.setAttribute("code", 123);
// ...
}
2、对象属性中注入
@Autowired
private HttpSession session; // 也可声明为final,通过构造器注入
@RequestMapping
public void login() {
session.setAttribute("code", 123);
// ...
}
但是如果使用的场景很多,这些注入的代码将分布到许多方法或类中。而在整个应用中,这些注入的相同类型的对象实际上指向同一对象,所以可以把这些对象统一放到一个类的静态常量中。考虑到接口中的变量都是公开的静态常量,所以用接口去包装这些对象是很合适的。
好了,一个工具类就此诞生:
import java.lang.reflect.Field;
import javax.servlet.http.*;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.stereotype.Component;
public interface HttpContext {
HttpServletRequest request = null;
HttpServletResponse response = null;
HttpSession session = null;
}
@Component
class HttpContextInjector {
private HttpContextInjector(HttpServletRequest request, HttpServletResponse response, HttpSession session)
throws Exception {
setValue("request", request);
setValue("response", response);
setValue("session", session);
}
private void setValue(String name, Object value) throws Exception {
Field field = HttpContext.class.getField(name);
FieldUtils.removeFinalModifier(field);
FieldUtils.writeStaticField(field, value);
}
}
注:HttpContext是工具类,HttpContextInjector是HttpContext的注入器,相当于配置文件,在项目启动时注入。项目需要引入commos-lang3依赖,这里它的作用是通过反射修改接口中常量。
用法:
1、控制器实现这个接口,类中的方法可直接使用这些对象。相比上面的通过属性注入,用法更加简单、安全。
@Controller
public class DemoController implements HttpContext {
@RequestMapping
private void zeros() throws Exception {
response.getOutputStream().write(new byte[8]);
}
}
2、直接当作工具类使用
@RequestMapping
private void zeros() throws Exception {
HttpContext.response.getOutputStream().write(new byte[8]);
}
希望对大家有所启发。