Cannot call sendError() after the response

来源:网页教学基地 时间:2017-09-20 11:36:03  浏览次数:0

Jersey2+Spring4+Hibernate4测试添加字段,代码如下:

package resource;

import java.util.List;

import javax.annotation.Resource;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import entity.User;
import service.UserService;;

@Singleton
@Path("user")
@Component // @Repository/@Service/@Controller
public class UserResource {

	@Context
	UriInfo uri;

	@Context
	HttpHeaders header;

	private UserService userService; // Service which will do all data
										// retrieval/manipulation work

	public UserService getUserService() {
		return userService;
	}

	@Resource
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	
	
	
	// -------------------Create a
	// User--------------------------------------------------------

	@POST
	@Path("/create")
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@Produces({ MediaType.TEXT_HTML })
	public Response createUser(User user) {
		System.out.println("Creating User " + user.getName());

		if (userService.exists(user)) {
			System.out.println("A User with name " + user.getName() + " already exist");

			user = userService.getUserByName(user.getName());
			return Response.status(Response.Status.CONFLICT)
			.entity("A User with name " + user.getName() + " already exist")
		        .header("Location", "http://localhost:8080/rest.jerseySpring/user " 
		        + user.getId()).build();

			
		} else {

			userService.add(user);

			return Response.status(Response.Status.CREATED)
			.entity("A new user has been created at /rest.jerseySpring/user/"+ 
			user.getId()).
			header("Location","http://localhost:8080/rest.jerseySpring/user" 
			+ user.getId()).build();
			
		}
	}

	
}

结果当插入有相同名字的user时报错如下:

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
	at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:450)
	at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:484)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Unknown Source)

根据错误信息

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)

        在ServletContainer.calss的223行打个断点,debug进去-->WebComponent.class-->ApplicationHandler.class

    -->ServerRuntime.class-->ContainerResponse.class-->OutboundMessageContext.class.class-->URI,发现问题最终出在

这里的str是这里的Location的value,即http://localhost:8080/rest.jerseySpring/user 

header("Location", "http://localhost:8080/rest.jerseySpring/user "

也就是说在解析该字符串时出了问题。那么就是字条串有问题了。我仔细看了半天,发现最后面多了个空格……

当Location的value与@Path("user")所对应的绝对路径有差异时就报错:

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

所以路径一定要写对了,多一个空格都不行。