URL
springMVC
<servlet>
<servlet-name>DispatcherServlet</servlet-name> <!-- 3 <== servlet 名称 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 4 <== servlet 名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value> <!-- 5 <== servlet 名称 -->
classpath:xml/websocket-config.xml
classpath:xml/springMVC.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name> <!-- 2 <== servlet 名称 -->
<url-pattern>/</url-pattern> <!-- 1 <== url 地址 -->
</servlet-mapping>
加载
Central dispatcher for HTTP request handlers/controllers, e.g. for web UI controllers
* or HTTP-based remote service exporters. Dispatches to registered handlers for processing
* a web request, providing convenient mapping and exception handling facilities.
相当于把一个http请求分配给handlers/controllers
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
try {
doDispatch(request, response); // 这个是重点
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
// 这个是重点
doDispatch(HttpServletRequest request, HttpServletResponse response) {
...
}
我晕了,并没看懂,上面:
大概是会将 所有请求拦截,然后分配给对应的 控制器 controller
DispatcherServlet
: 会初始化两个参数
init-param 'contextConfigLocation'
WebApplicationContext webApplicationContext
《 == 注意这个 设为 A
DispatcherServlet 继承了 servlet. httpservlet 类(熟悉了吧)
init()
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}
// Set bean properties from init parameters. 初始化一些参数
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
}
// Let subclasses do whatever initialization they like. 注意这个!!!!
initServletBean();
if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}
@Override
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
if (this.logger.isInfoEnabled()) {
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
}
long startTime = System.currentTimeMillis();
try {
// 这里: A Initialize and publish the WebApplicationContext for this servlet.
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
catch (ServletException ex) {
this.logger.error("Context initialization failed", ex);
throw ex;
}
catch (RuntimeException ex) {
this.logger.error("Context initialization failed", ex);
throw ex;
}
if (this.logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +
elapsedTime + " ms");
}
}
妹子四连:
先说简单的
- 为啥要跳转到post jsp?
因为这是展示页面,这是与用户交互的地方;
它是如何跳过去的, 这个要看源码
Every view name returned from a handler will be translated to a JSP
* resource (for example: "myView" -> "/WEB-INF/jsp/myView.jsp"), using
* this view class by default.
大致是会对路径进行拼接
/**
* A convenience constructor that allows for specifying {@link #setPrefix prefix}
* and {@link #setSuffix suffix} as constructor arguments.
* @param prefix the prefix that gets prepended to view names when building a URL
* @param suffix the suffix that gets appended to view names when building a URL
* @since 4.3
*/
public InternalResourceViewResolver(String prefix, String suffix) {
this();
setPrefix(prefix);
setSuffix(suffix);
}
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(getViewClass());
view.setUrl(getPrefix() + viewName + getSuffix()); 《=== here
- 为啥要在jsp里foreachpost?
这里用的是 jsp 的标签库,如果是原生的话大概是:很不方便,所以引入了 jsp 标签库
<%@ page import="com.hsjfans.scholar.entity.Post" %>
<%@ page import="java.util.List" %>
<%@ page import="javafx.geometry.Pos" %>
<% List<Post> posts= (List<Post>) request.getAttribute("posts");
if(posts!=null){
for(Post post:posts) {
%>
<time datetime="<%=post.getCreateTime()%>"><%=post.getCreateTime()%>
</time>
<%}}%>
- 为啥会return json?
@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用;
在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。例如,异步获取 json 数据,加上 @Responsebody 注解后,就会直接返回 json 数据。
@RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象
这个问题就很有内涵了?
下面这个方法有没有印象: 其实 @Responsebody 注解就类似这个方法,它一般用于与 ajax交互使用
@RequestMapping(value = "/sd")
private void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
PrintWriter writer=response.getWriter();
JsonObject jsonObject=new JsonObject();
jsonObject.addProperty("laaal","meizihao");
writer.print(jsonObject.toString());
}
/**
* 上传图片 界面
* /jsp/addsubscribe.jsp 中的内容
* 以下字段未被参数化,请严格使用
* ImgPr 展示图片的 id
* <img id="ImgPr" width="120" height="120" />
* avatar 表单中的 logo或头像信息输入框 id
* <input type="text" class="form-control" id="avatar" name="avatar" readonly >
* @param url get 或 post 的 url
* @param domId 代表form 表单的 id
*
*/
//选择图片后无需点击上传,直接上传图片
function updataFile(url,domId,uploadId){
// 提交表单
$('#'+domId).ajaxSubmit({
url : url, // 请求的url
type : "post", // 请求方式
dataType : "json", // 响应的数据类型
async :true, // 异步
success: function (data) {
if(data.url!=null){
$("#ImgPr").attr('src',data.url)
$('#'+uploadId).css('display','none')
$("#avatar").attr('value',data.url)
}else {
alert(data.error)
}
},
error : function(status){
alert("服务器连接出错,请稍后重试...")
}
});
}
4 .嗯嗯我就是流程没搞明白?
最好的办法是debug 启动一下,加断点 然后看参数传递;
-
关于jsp像 servlet内传参:
- 类似于以前的servlet方法可以获取:
取参数
@RequestMapping(value = WebInfo.EDIT,method = RequestMethod.GET) private String editPost(@RequestParam(value = "id") Long id, Model model)... 可以改写成: @RequestMapping(value = WebInfo.EDIT,method = RequestMethod.GET) private String editPost( Model model){... Long id=Long.valueOf(request.getParameter("id")); @RequestParam 类似于 定义参数,还可以定义类型 Model 类似于 request.setAttribute(); 然后 还有一个 ModelAndView(),类似 不过 它要配置一个 view 相当与 页面地址(也可以跳转)
- @PathVariable: url参数注解, 一般用于从url中获取参数:、
@RequestMapping(value = "/{domain}",method = RequestMethod.POST) @ResponseBody private String replyMessage(HttpServletRequest request,@PathVariable(value = "domain") String domain){ log.info(" 被动回复消息..."); Map<String,Object> params=new HashMap<>(); params.put("domain",domain);
- 类似于以前的servlet方法可以获取:
以前没有jsp
的时候,我们写页面都是在servlet
中拼的字符串;
其实jsp就是servlet